feat(network): add interface and route management via Netplan#349
Merged
feat(network): add interface and route management via Netplan#349
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## main #349 +/- ##
=========================================
Coverage 99.91% 99.92%
=========================================
Files 443 469 +26
Lines 21606 23814 +2208
=========================================
+ Hits 21587 23795 +2208
Misses 11 11
Partials 8 8
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
11 tasks: provider types, interface CRUD, route CRUD, agent processors, wiring, OpenAPI spec, handlers, SDK, CLI, docs, verification. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Define InterfaceProvider and RouteProvider interfaces with associated entry, result, and route types. Generate gomock mocks for testing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add Debian provider with List, Get, Create, Update, Delete for network interface configuration via Netplan YAML files. Includes YAML generation, name validation, platform stubs (Darwin/Linux), and comprehensive tests with 100% coverage on all new files. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add job operation constants for network interface and route CRUD operations. Create processor_interface.go and processor_route.go with dispatch functions following the existing sysctl/service pattern. Wire both into NewNetworkProcessor with new case branches for "interface" and "route" base operations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add createNetplanProviders() to agent_setup.go that creates platform-specific Netplan interface and route providers (Debian with file-state KV, stubs on Darwin/Linux). Pass both providers to NewNetworkProcessor and include them in the FactsAware wiring list for the network registry entry. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add network interface CRUD endpoints (list, get, create, update, delete), route CRUD endpoints (list, get by interface, create, update, delete), and DNS delete endpoint to the network OpenAPI spec. Fix ping handler enum constants that changed due to new status types. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Implement all StrictServerInterface methods for the new network endpoints: interface list/get/create/update/delete, route list/get/create/update/delete, and DNS delete. Each handler validates hostname and body, supports broadcast targets, and follows the existing DNS get/put patterns. Adds OpNetworkDNSDelete operation constant. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add CLI commands for network interface management (list, get, create, update, delete), network route management (list, get, create, update, delete), and DNS delete. All commands support --json output and broadcast targeting. Co-Authored-By: Claude <noreply@anthropic.com>
Add feature page, CLI docs, SDK docs, and SDK examples for network interface and route management. Update cross-reference files including features landing page, network management feature page, architecture overview, API guidelines path table, SDK client overview, and Docusaurus navbar config. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Split flat netplan package into netplan/ (shared helpers), netif/ (interface provider), and route/ (route provider). Each sub-package has its own marshalJSON var and test suite, eliminating data races under -parallel -race. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Rename netif → netplan/iface, move route → netplan/route. Each sub-package has its own marshalJSON var eliminating test races under -parallel -race. Update all imports and regenerate mocks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add back the marshalJSON package var and marshal error test to the netplan package. Now safe because iface and route are in separate sub-packages with their own marshalJSON vars — no shared state. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add test cases for broadcast paths, optional field builders, conversion edge cases, and validation error branches across all 11 network handler files. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add marshalJSON error tests for route Create/Update, and all-fields test for SDK interfaceConfigRequestFromOpts. All new network code now at 100% coverage. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
DNS writes Netplan config via ApplyConfig, so it logically belongs under netplan/ alongside iface/ and route/. Update all imports. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Match the sysctl/service pattern — one Println before Job ID, none after. Also fix operation constants to use network. prefix. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Interface list and get now return system info from netinfo provider and a primary flag from agent facts. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add read-only system fields to InterfaceInfo schema, handler conversion, SDK types, and CLI display. Primary interface marked with * in CLI list output. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Drop IPv6 column, add dedicated PRIMARY column, use cleaner layout. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Scan /etc/netplan/*.yaml files to detect if an interface uses DHCP. Add DHCP column to CLI interface list output. Use Glob instead of ReadDir+filter for cleaner file discovery. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Delete now returns an error with "not managed" instead of silently returning Changed: false when the target interface or route set has no OSAPI-managed Netplan config file. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace netinfo provider calls with netplan status --format json parsing. Single command provides interfaces, addresses with DHCP flags, routes with protocol, MAC, type, and state. Remove netinfo dependency from iface and route providers. Add shared GetStatus helper and InterfaceStatus methods. 100% coverage across all netplan packages. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove domain-specific prefixes from ErrUnsupported returns across all providers. The error message is now consistently just "operation not supported on this OS family". Also drop MAC column from interface list CLI for cleaner output. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Use netplan status to determine if interface is wifi, bridge, etc. and generate the correct YAML section (wifis vs ethernets). Fix file permissions to 0600 for netplan configs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add dhcp4-overrides and dhcp6-overrides with use-dns: false to the generated DNS Netplan YAML. When explicitly setting DNS servers, DHCP-provided servers should not be merged in. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add capabilities needed for netplan file ownership (CAP_CHOWN) and network configuration (CAP_NET_ADMIN). Update docs, preflight checks, and test fixtures. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add overrideDHCP bool parameter to DNSService.Update() SDK method, --override-dhcp flag to the CLI update command, and test coverage for both. Update CLI docs, feature docs, and SDK docs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
When override_dhcp is true, the generated Netplan YAML includes dhcp4-overrides and dhcp6-overrides with use-dns: false, ensuring only explicitly configured DNS servers are used. Default false preserves DHCP DNS merge behavior. Updated across all layers: OpenAPI spec, handler, agent processor, provider, SDK, CLI (--override-dhcp flag), tests, and docs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add DeleteNetplanConfig method to DNS provider that removes the osapi-dns.yaml file and applies netplan. Wire delete operation in the agent processor to distinguish from update. Add platform stubs. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…lete) The operation string is "dns.delete" not "network.dns.delete" — the category prefix is already stripped. Fix parts index from [2] to [1]. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Document in the provider that accept-ra: false would break IPv6 connectivity (default route, global addresses, prefix info) so RA-provided DNS servers may still appear alongside configured ones. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Fix three gaps found in audit: DNS Delete method missing from SDK doc page, SDK example, and network management permissions table. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Move interface type detection to shared netplan.SectionForInterface and netplan.SectionForType. Remove duplicated logic from DNS and route providers. All YAML generators now accept ifaceSection param. WIP: tests need updating for new netplan status mock expectation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Create and Update now call SectionForInterface which queries netplan status. Add RunCmd mock expectations to all affected test cases. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Route list now cross-references state KV to mark managed routes. MANAGED column added to CLI output. Strip "netplan" prefix from all provider error messages — users don't need implementation details. Update OpenAPI spec and SDK types. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Replace "already exists"/"does not exist" with "already managed"/ "not managed" across certificate, service, and cron providers. Strip "netplan" prefix from interface errors. Consistent wording across all CRUD providers. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…viders Create now returns Changed: false when the resource already exists instead of erroring. Delete returns Changed: false when the resource doesn't exist. This matches Ansible's desired-state semantics where state: present/absent are always idempotent. Also fixes interface List to scan /etc/netplan/ for osapi-*.yaml files, including managed interfaces that are down/unlinked and not visible in netplan status output. Providers updated: cron, certificate, service, NTP, sysctl, interface, and route. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add Idempotency (MANDATORY) section to CLAUDE.md documenting the Create/Update/Delete contract. Update OpenAPI specs, feature docs, CLI docs, type comments, and agent processor tests to reflect that Create returns Changed: false (not an error) when already managed. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Add test cases for managed route matching in List via loadManagedRoutes (KV happy path, undeployed entries, Keys/Get errors, invalid JSON, missing metadata keys). Add test cases for scanManagedInterfaces (multiple managed-only interfaces sorting, directory/non-yaml skips, ReadDir failure). 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
24c5cb1 to
2676219
Compare
…t processor Add tests for DNS DeleteNetplanConfig on all platforms (Debian, Darwin, DebianDocker, Linux), overrideDHCP branch in YAML generation, SectionForInterface/SectionForType in netplan status, and DNS delete operation in the agent network processor. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove mixed wantErr/wantErrMsg + validateFunc pattern. All test cases now use a single validateFunc(result, error) callback, matching the convention used across all other provider tests. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
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.
Summary
Full CRUD for network interface configuration and route management via Netplan drop-in files, following the direct-write provider pattern.
/etc/netplan/osapi-{name}.yaml/etc/netplan/osapi-{name}-routes.yaml0.0.0.0/0,::/0) protection blocks accidental deletionnetplan generatevalidates merged config beforenetplan apply; rollback on failuremanaged: true/false; interface list includes down/unlinked interfaces with osapi config fileschanged: falseinstead of erroring when creating an already-managed resource or deleting an absent oneLayers implemented
internal/provider/network/netplan/(interface + route CRUD, Debian impl, platform stubs)interface.*androute.*operations/node/{hostname}/network/InterfaceServiceandRouteServicewith typed methodsosapi client node network interfaceandroutecommand treesTest plan
🤖 Generated with Claude Code