Skip to content

Conversation

@weneghawi
Copy link
Contributor

Summary

Adds AAA + TACACS+ support with SecretRef for secure key storage, server groups (VRF/source-interface), and full authentication/authorization/accounting configuration.

Manual Testing with gnmic

# Port-forward to switch gNMI
kubectl port-forward -n <namespace> pod/<switch-pod> 9339:60009 &

# Create TACACS server
gnmic -a 127.0.0.1:9339 -u admin -p admin --skip-verify set \
  --update-path "System/userext-items/tacacsext-items/tacacsplusprovider-items/TacacsPlusProvider-list[name=10.16.8.142]" \
  --update-value '{"name":"10.16.8.142","port":49,"key":"testkey","keyEnc":"7","timeout":5}'

# Create provider group and add server
gnmic -a 127.0.0.1:9339 -u admin -p admin --skip-verify set \
  --update-path "System/userext-items/tacacsext-items/tacacsplusprovidergroup-items/TacacsPlusProviderGroup-list[name=GR_TACACS]" \
  --update-value '{"name":"GR_TACACS","vrf":"management","srcIf":"mgmt0"}'

# Verify on switch CLI: show running-config | section tacacs

@weneghawi weneghawi requested a review from a team as a code owner February 4, 2026 16:43
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Merging this branch will decrease overall coverage

Impacted Packages Coverage Δ 🤖
github.com/ironcore-dev/network-operator/api/cisco/nx/v1alpha1 0.00% (ø)
github.com/ironcore-dev/network-operator/api/core/v1alpha1 0.00% (ø)
github.com/ironcore-dev/network-operator/cmd 0.00% (ø)
github.com/ironcore-dev/network-operator/internal/controller/core 63.92% (-2.72%) 👎
github.com/ironcore-dev/network-operator/internal/provider 48.00% (ø)
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos 10.42% (-0.51%) 👎

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/ironcore-dev/network-operator/api/cisco/nx/v1alpha1/zz_generated.deepcopy.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/api/core/v1alpha1/aaa_types.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/api/core/v1alpha1/zz_generated.deepcopy.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/cmd/main.go 0.00% (ø) 0 0 0
github.com/ironcore-dev/network-operator/internal/controller/core/aaa_controller.go 0.00% (ø) 124 (+124) 0 124 (+124)
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos/aaa.go 0.00% (ø) 25 (+25) 0 25 (+25)
github.com/ironcore-dev/network-operator/internal/provider/cisco/nxos/provider.go 0.06% (-0.00%) 1556 (+80) 1 1555 (+80) 👎
github.com/ironcore-dev/network-operator/internal/provider/provider.go 48.00% (ø) 25 12 13

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.

@hardikdr hardikdr added the area/metal-automation Automation processes within the Metal project. label Feb 5, 2026
@hardikdr hardikdr added this to Roadmap Feb 5, 2026
Copy link
Contributor

@felix-kaestner felix-kaestner left a comment

Choose a reason for hiding this comment

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

@weneghawi Please have a look at the openconfig-system:system/aaa yang model. Only configurations that are part of this or are otherwise commonly found on all vendors (Nokia, Juniper, Arista & Co.) should be part of the core api. All Cisco NX-OS specific configuration should be refactored into a vendor specific provider config, see e.g. the ManagementAccess resource on how this is done. There is a separate api package for cisco specific CRDs.

//
// It models the Authentication, Authorization, and Accounting (AAA) configuration on a network device,
// including TACACS+ server configuration and AAA group/method settings.
type AAASpec struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add some XValidation rules to verify that at least one of the fields in this spec is set? Otherwise, I'd be able to create a resource without any configuration.

Comment on lines +74 to +80
// KeyEncryption specifies the encryption type for the key.
// Type7 is the Cisco Type 7 encryption (reversible).
// Type6 is the AES encryption (more secure).
// Clear means the key is sent in cleartext (not recommended).
// +optional
// +kubebuilder:validation:Enum=Type6;Type7;Clear
// +kubebuilder:default=Type7
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't want to include cisco specific stuff in the core api (we want this to be vendor agnostic). So at a minimum, we have to remove "Type7". Is Type6/AES universally supported across vendors (Nokia, Juniper, Arista etc.)?

// VRF is the VRF to use for communication with the TACACS+ servers.
// +optional
// +kubebuilder:validation:MaxLength=63
VRF string `json:"vrf,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
VRF string `json:"vrf,omitempty"`
VrfName string `json:"vrfName,omitempty"`

Let's use a string name here, to make clear that we are talking about the name of the VRF directly. This would leave us the possibility have "VRF" field in the future, which could then be a resource reference to a "VRF" resource.

// SourceInterface is the source interface to use for communication with the TACACS+ servers.
// +optional
// +kubebuilder:validation:MaxLength=63
SourceInterface string `json:"sourceInterface,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
SourceInterface string `json:"sourceInterface,omitempty"`
SourceInterfaceName string `json:"sourceInterfaceName,omitempty"`

Same reasoning as with the VRF, lets append the "Name" suffix to have the possibility for an "SourceInterface" object reference to a "Interface" resource.

Comment on lines +136 to +138
// LoginErrorEnable enables login error messages.
// +optional
LoginErrorEnable bool `json:"loginErrorEnable,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

This configuration seems cisco nx-os specific and should go into a provider config crd.

)

// TacacsPlusProvider represents a TACACS+ server host configuration.
// Path: System/userext-items/tacacsext-items/tacacsplusprovider-items/TacacsPlusProvider-list[name=<address>]
Copy link
Contributor

Choose a reason for hiding this comment

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

I would leave out these comments as those are already clear from the XPath() functions.

}

// Configure TACACS+ server hosts
for _, server := range req.AAA.Spec.TACACSServers {
Copy link
Contributor

Choose a reason for hiding this comment

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

With this logic, we are leaving over tacacs servers that were once part of the resource, but got removed in a later reconcile, as we only make sure to have those that are in the spec but never clean up any previous ones. We should do this.

}

// MapRealmFromMethodType maps the API method type to NX-OS realm.
func MapRealmFromMethodType(method v1alpha1.AAAMethodType, groupName string) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

The groupName parameter is never used.

return p.Patch(ctx, conf...)
}

func (p *Provider) DeleteAAA(ctx context.Context, req *provider.DeleteAAARequest) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please batch all the updates into a single call, similar to the EnsureAAA.

conf = append(conf, acct)
}

return p.Patch(ctx, conf...)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is a Patch (netconf merge) really the operation we'd like to perform here? Or could this lead to leftover configurations that the operator didn't intent to and is unaware of? In general we prefer to do a Update (netconf replace) to make sure that the operator is in charge of all the configuration.

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

Labels

area/metal-automation Automation processes within the Metal project.

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants