Skip to content

Add kubectl-net plugin for managing network-operator resources - #411

Open
felix-kaestner wants to merge 8 commits into
mainfrom
cli
Open

Add kubectl-net plugin for managing network-operator resources#411
felix-kaestner wants to merge 8 commits into
mainfrom
cli

Conversation

@felix-kaestner

Copy link
Copy Markdown
Contributor

Implements a kubectl plugin with get, pause, unpause, and shell
completion subcommands. The get command supports server-side table
printing and all standard kubectl output formats. Label shorthand
flags (--device/-d, --aggregate, --vrf, --routed-vlan, --evi)
provide convenient filtering. Resource definitions are code-generated
from the API types via kubebuilder markers.

@felix-kaestner
felix-kaestner force-pushed the cli branch 3 times, most recently from a1f82a8 to 06ea0ef Compare June 18, 2026 09:45
@felix-kaestner
felix-kaestner marked this pull request as ready for review June 18, 2026 09:49
@felix-kaestner
felix-kaestner requested a review from a team June 18, 2026 09:49
@felix-kaestner
felix-kaestner force-pushed the cli branch 4 times, most recently from 7805fa5 to 573acd5 Compare June 23, 2026 14:34
@felix-kaestner
felix-kaestner force-pushed the cli branch 2 times, most recently from 3082510 to 9d3047f Compare July 22, 2026 13:52
@felix-kaestner
felix-kaestner force-pushed the cli branch 2 times, most recently from bab5c83 to 69fe2ff Compare August 20, 2026 07:42
@felix-kaestner

Copy link
Copy Markdown
Contributor Author
$ kind get clusters
network-operator
network-operator-target

$ kubectl --context kind-network-operator get deploy -n network-operator-system
NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
network-operator-controller-manager   1/1     1            1           112m

$ kubectl --context kind-network-operator-target get deploy -n network-operator-system
NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
network-operator-controller-manager   1/1     1            1           23m

$ kubectl net move --context kind-network-operator --to-context kind-network-operator-target --to-kubeconfig ~/.kube/config --dry-run
Checking target cluster CRDs...
Discovering resources in namespace "default"...
  Device/leaf1
  Interface/lo0

Total: 2 resources would be moved.

$ kubectl net move --context kind-network-operator --to-context kind-network-operator-target --to-kubeconfig ~/.kube/config
Checking target cluster CRDs...
Discovering resources in namespace "default"...
Pausing Devices on source...
Creating resources on target...
Deleting resources from source...
Unpausing Devices on target...
Move complete.

@felix-kaestner
felix-kaestner force-pushed the cli branch 2 times, most recently from 8459451 to f9697d3 Compare August 20, 2026 11:50
@hardikdr hardikdr added the area/switch-automation Automation processes for network switch management and operations. label Aug 21, 2026
@hardikdr hardikdr added this to Roadmap Aug 21, 2026

@SchwarzM SchwarzM left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice ! I have some minor points.

Also we might want to consider adding a test or 2 for the non-trivial logic which is now very flat but might get more complicated over time. Thinking of patch generation and flags.

Comment thread Makefile

root := cmd.NewCmdNet(genericiooptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr})
if err := root.Execute(); err != nil {
os.Exit(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems we just exit without bubbling the error to the user ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cobra prints errors by default unless SilenceErrors is set. ref/ https://github.com/spf13/cobra/blob/v1.10.2/command.go#L1157-L1161

So based on this the error is already shown to the user.

Comment thread kubectl-net/pkg/cmd/get.go Outdated
list.SetResourceVersion("")
for _, info := range infos {
if info.Object != nil {
list.Items = append(list.Items, *info.Object.(*unstructured.Unstructured))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you've made sure the conversion to unstructured is safe above why not here ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to not safely check in both places. It can't ever not be unstructured, as this is explicitly requested in the buildResourceResult.

crd := schema.GroupVersionResource{Group: "apiextensions.k8s.io", Version: "v1", Resource: "customresourcedefinitions"}
for _, def := range resourceDefs {
name := def.Name + "." + def.Group
_, err := tgtDyn.Resource(crd).Get(ctx, name, metav1.GetOptions{})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should check the version ? It might not be in use now but could be in the future ...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resourceDefs we are looping over here are generated from code and therefore already contain the api version which we check on the target cluster. So this is already implicitly the case.


infos, err := result.Infos()
if err != nil {
return err

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should at least print the error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error will automatically be printed, as mentioned in #411 (comment)

Comment thread kubectl-net/pkg/cmd/pause.go Outdated
Comment thread kubectl-net/pkg/cmd/resources.go Outdated
Comment thread kubectl-net/pkg/cmd/resources.go Outdated
Comment thread kubectl-net/pkg/cmd/move.go Outdated
Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
Implements a kubectl plugin with get, pause, unpause, and shell
completion subcommands. The get command supports server-side table
printing and all standard kubectl output formats. Label shorthand
flags (--device/-d, --aggregate, --vrf, --routed-vlan, --evi)
provide convenient filtering. Resource definitions are code-generated
from the API types via kubebuilder markers.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
Add --serial flag for Device resources to filter by DeviceSerialLabel,
and --neighbor flag for Interface resources to filter by
PhysicalInterfaceNeighborLabel. Both flags are available on get and
pause/unpause commands.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
The generator was capturing kubebuilder marker suffixes
(singular=, shortName=) as part of the resource name when all
attributes appeared on one line (e.g. path=indices,singular=index).

Parse inline attributes from the same line as path= so the Name
field contains only the plural resource name.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
Implements a 'kubectl net move' subcommand that migrates all
network-operator resources from a source cluster namespace to a
target cluster. Inspired by clusterctl move from cluster-api.

The move algorithm:
- Verify CRDs exist on the target cluster
- Ensure the target namespace exists
- Discover all network-operator resources in the source namespace
- Pause all Devices on the source (spec.paused)
- Create resources on the target (stripped of cluster-specific
  metadata and owner references)
- Delete resources from the source (stripping finalizers)
- Unpause Devices on the target

Owner references are not rewritten; controllers re-establish them
on first reconcile after unpause. The operation is idempotent and
can be re-run on partial failure.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
controller-gen with paths="./..." recurses into the kubectl-net
sub-module, fails to resolve its dependencies in CI, and aborts.
Narrow the paths to ./api/ and ./internal/ where the actual types
and controllers live.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
Add a 'kubectl net version' subcommand that prints the version
injected at build time via ldflags.

Add a 'make kubectl-net' target that builds the plugin binary into
bin/ with stripped symbols and version info from git describe.

Signed-off-by: Felix Kästner <felix.kaestner@sap.com>
@github-actions

Copy link
Copy Markdown

Merging this branch will not change overall coverage

Impacted Packages Coverage Δ 🤖
github.com/ironcore-dev/network-operator/api/pool/v1alpha1 18.20% (ø)
github.com/ironcore-dev/network-operator/kubectl-net/cmd 0.00% (ø)
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd 0.00% (ø)
github.com/ironcore-dev/network-operator/kubectl-net/tools/generate-resources 0.00% (ø)

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/ironcore-dev/network-operator/api/pool/v1alpha1/claim_types.go 20.00% (ø) 5 1 4
github.com/ironcore-dev/network-operator/kubectl-net/cmd/kubectl-net.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/completion.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/doc.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/gen.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/get.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/labels.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/move.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/must.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/pause.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/resources.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/root.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/pkg/cmd/version.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/kubectl-net/tools/generate-resources/main.go 0.00% (ø) 0 0 0

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/switch-automation Automation processes for network switch management and operations. size/XXL

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants