Add netplan provider for network.managed (fixes #62219)#69615
Open
ggiesen wants to merge 14 commits into
Open
Conversation
Baseline regression tests before adding netplan-aware provider selection. debian_ip.__virtual__ had zero test coverage; these pin that it claims the 'ip' provider on the Debian os_family and declines elsewhere, so the upcoming change (deferring to a netplan provider when netplan is active) can't silently alter which systems debian_ip manages.
On netplan systems (Ubuntu 18.04+ and Debian where netplan is the active renderer), network.managed wrote /etc/network/interfaces via debian_ip, which netplan ignores -- so interface config never took effect. Add salt/modules/netplan_ip.py: a new 'ip' provider that generates per-interface netplan v2 YAML under /etc/netplan/90-salt-<iface>.yaml and applies it via 'netplan generate'/'netplan apply'. It claims the 'ip' virtual when the netplan command and /etc/netplan are present; debian_ip now defers in that case so exactly one provider owns 'ip'. This first increment covers ethernet interfaces (static/dhcp4/dhcp6, addresses, gateway as a default route, nameservers, mtu), routes, and apply/up/down. ifupdown-only options (ethtool, up/down hooks) raise an informative error rather than being silently dropped. bonds/vlans/bridges are not yet implemented (the state's bond path is gated on ip.get_bond, which this provider does not yet define, so it is safely skipped). Targets 3006.x; can be rebased forward if maintainers prefer a later line. Refs saltstack#62219
Extend build_interface beyond ethernet: - bond: slaves -> interfaces, bond options (mode, miimon, lacp_rate, xmit_hash_policy, up/down delay, arp_interval, primary) -> parameters. Handled inline in the interface YAML (netplan has no separate modprobe file), so get_bond is intentionally not defined and the state's bond path is skipped. - vlan: id + link from vlan_id/parent settings, or parsed from a dotted iface name (eth0.100 -> id 100, link eth0). - bridge: ports -> interfaces, bridge options (stp, forward-delay, ageing-time, max-age, hello-time, priority) -> parameters. Adds unit tests for each type. Refs saltstack#62219
netplan rejects a config that references an interface it can't resolve
("Error in network definition: bond0: interface 'eth3' is not defined"),
so a bond/bridge/vlan file that named its slaves/ports/parent but never
declared them failed 'netplan generate' and the interface never came up.
Emit each member (bond slaves, bridge ports, vlan parent) as a bare
ethernets entry in the same document; setdefault leaves any
separately-managed definition of the same NIC intact on merge.
Caught by behavioral testing on a real Ubuntu VM (unit tests checked the
dict shape but not netplan's acceptance); re-validated end-to-end --
vlan/bond/bridge now generate, apply, come up, and survive reboot.
Refs saltstack#62219
The placeholder '3006.x' failed the salt-rewrite (fix_docstrings) pre-commit hook, which rewrites it to a concrete version. Set it to 3006.27 (the next 3006 release, which also ships Python 3.11 per saltstack#69526) rather than salt-rewrite's default '3006.0', which would wrongly imply the provider has existed since the first 3006 release.
3006.27 was released 2026-07-01 without this provider, so the next available 3006.x release is 3006.28.
…tion The direct test calls netplan_ip.build_interface at the exact call shape network.managed uses (name, iface_type, enabled, **kwargs) with the test flag the state always injects from __opts__, asserting a test=True dry run returns the rendered lines without writing under /etc/netplan while test=False writes the file. The inverse test guards against overcorrecting the debian_ip gate: a netplan binary alone (netplan.io installed as a dependency, no /etc/netplan) must not stop debian_ip from claiming the ip provider on ifupdown systems.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a netplan provider for
network.managedso it manages netplan YAML on netplan-based systems instead of writing/etc/network/interfaces, which netplan ignores.On Ubuntu 18.04+ (and Debian where netplan is the active renderer), the legacy
debian_ipprovider writes/etc/network/interfaces(ifupdown). netplan does not read that file, sonetwork.managedsilently has no effect -- issue #62219.New module
salt/modules/netplan_ip.py:ipvirtual only when netplan is active (thenetplancommand +/etc/netplanpresent);debian_ipnow defers in that case, so exactly one provider ownsipon any box./etc/netplan/90-salt-<iface>.yaml(prefix90so salt-managed config wins over cloud-init's50-cloud-init.yaml) and applies withnetplan generate+netplan apply.eth,bond,vlan, andbridge(addresses, dhcp4/dhcp6, gateway as a default route, nameservers, mtu; bond slaves/params, vlan id/link, bridge ports/params), plus routes and up/down. Referenced member NICs (bond slaves, bridge ports, vlan parent) are declared sonetplan generateresolves them.What issues does this PR fix or reference?
Fixes #62219.
Previous Behavior
network.managedon Ubuntu 18.04+ wrote/etc/network/interfaces; netplan ignored it, so interfaces were never configured as declared.New Behavior
network.managedwrites and applies/etc/netplan/90-salt-<iface>.yaml; the interface comes up via the active renderer (networkd/NetworkManager) and persists across reboot.debian_ipcontinues to handle non-netplan Debian unchanged.Testing
Unit tests for
netplan_ip(all interface types, provider selection, apply, routes) and new baseline tests pinningdebian_ip.__virtual__selection. All green; black/isort/pylint clean.Beyond unit tests, validated behaviorally on real VMs (VMware Workstation via Vagrant), since config application and reboot-persistence can't be exercised in a container:
The interface types create a real 802.1Q vlan, an active-backup bond over two slaves, and a bridge with a port -- each up with its address and persistent across reboot. Provider selection verified in all three modes (netplan Ubuntu, non-netplan Debian, Debian with netplan installed).
Branch
Targeted at
3006.xsince #62219 affects the LTS line. Happy to rebase ontomaster(or another branch) if the team considers a new provider a feature that doesn't belong in 3006.x -- just say which branch you'd prefer.Merge requirements satisfied?
[NOTICE] Bug fixes or features added to Salt require tests.
Commits signed with GPG?
No