From 68297f5f4a14c448feb1f1cdbc0a5499304572e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20K=C3=A4stner?= Date: Wed, 17 Dec 2025 15:59:11 +0100 Subject: [PATCH] Standardize administrative state using AdminState enum across resources This patch harmonizes the API for setting a administrative state on resources using the AdminState enumeration and introduces this field for protocols (BGP, OSPF, ISIS, PIM) and system level services (NTP, DNS). --- api/cisco/nx/v1alpha1/bordergateway_types.go | 5 ++ api/cisco/nx/v1alpha1/vpcdomain_types.go | 29 ++++------ api/core/v1alpha1/bgp_peer_types.go | 6 +++ api/core/v1alpha1/bgp_types.go | 5 ++ api/core/v1alpha1/dns_types.go | 5 ++ api/core/v1alpha1/interface_types.go | 11 ++-- api/core/v1alpha1/isis_types.go | 5 ++ api/core/v1alpha1/ntp_types.go | 5 ++ api/core/v1alpha1/ospf_types.go | 5 ++ api/core/v1alpha1/pim_types.go | 5 ++ api/core/v1alpha1/ref_types.go | 1 + api/core/v1alpha1/vlan_types.go | 15 +----- .../networking.metal.ironcore.dev_bgp.yaml | 8 +++ ...etworking.metal.ironcore.dev_bgppeers.yaml | 9 ++++ ...networking.metal.ironcore.dev_devices.yaml | 12 ++++- .../networking.metal.ironcore.dev_dns.yaml | 8 +++ ...working.metal.ironcore.dev_interfaces.yaml | 2 +- .../networking.metal.ironcore.dev_isis.yaml | 8 +++ .../networking.metal.ironcore.dev_ntp.yaml | 8 +++ .../networking.metal.ironcore.dev_ospf.yaml | 8 +++ .../networking.metal.ironcore.dev_pim.yaml | 8 +++ .../networking.metal.ironcore.dev_vlans.yaml | 6 +-- ...ing.metal.ironcore.dev_bordergateways.yaml | 8 +++ ...working.metal.ironcore.dev_vpcdomains.yaml | 4 +- .../networking.metal.ironcore.dev_bgp.yaml | 8 +++ ...etworking.metal.ironcore.dev_bgppeers.yaml | 9 ++++ .../networking.metal.ironcore.dev_dns.yaml | 8 +++ ...working.metal.ironcore.dev_interfaces.yaml | 2 +- .../networking.metal.ironcore.dev_isis.yaml | 8 +++ .../networking.metal.ironcore.dev_ntp.yaml | 8 +++ .../networking.metal.ironcore.dev_ospf.yaml | 8 +++ .../networking.metal.ironcore.dev_pim.yaml | 8 +++ .../networking.metal.ironcore.dev_vlans.yaml | 6 +-- ...ing.metal.ironcore.dev_bordergateways.yaml | 8 +++ ...working.metal.ironcore.dev_vpcdomains.yaml | 4 +- config/samples/v1alpha1_vlan.yaml | 1 - .../core/evpninstance_controller_test.go | 4 +- .../core/interface_controller_test.go | 4 +- .../controller/core/vlan_controller_test.go | 2 +- internal/provider/cisco/nxos/bgp.go | 1 + internal/provider/cisco/nxos/bgp_test.go | 1 + internal/provider/cisco/nxos/ntp.go | 1 + internal/provider/cisco/nxos/pim.go | 24 +++++++++ internal/provider/cisco/nxos/provider.go | 54 ++++++++++++++++--- .../cisco/nxos/testdata/bgp_peer.json | 1 + 45 files changed, 294 insertions(+), 62 deletions(-) diff --git a/api/cisco/nx/v1alpha1/bordergateway_types.go b/api/cisco/nx/v1alpha1/bordergateway_types.go index cc8d3402..fa723a3f 100644 --- a/api/cisco/nx/v1alpha1/bordergateway_types.go +++ b/api/cisco/nx/v1alpha1/bordergateway_types.go @@ -17,6 +17,11 @@ type BorderGatewaySpec struct { // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="DeviceRef is immutable" DeviceRef v1alpha1.LocalObjectReference `json:"deviceRef"` + // AdminState indicates whether the BorderGateway instance is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState v1alpha1.AdminState `json:"adminState,omitempty"` + // MultisiteID is the identifier for the multisite border gateway. // +required // +kubebuilder:validation:Minimum=1 diff --git a/api/cisco/nx/v1alpha1/vpcdomain_types.go b/api/cisco/nx/v1alpha1/vpcdomain_types.go index 01735884..15f5ded8 100644 --- a/api/cisco/nx/v1alpha1/vpcdomain_types.go +++ b/api/cisco/nx/v1alpha1/vpcdomain_types.go @@ -6,7 +6,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - corev1 "github.com/ironcore-dev/network-operator/api/core/v1alpha1" + "github.com/ironcore-dev/network-operator/api/core/v1alpha1" ) // VPCDomainSpec defines the desired state of a vPC domain (Virtual Port Channel Domain) @@ -15,7 +15,7 @@ type VPCDomainSpec struct { // Immutable. // +required // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="DeviceRef is immutable" - DeviceRef corev1.LocalObjectReference `json:"deviceRef"` + DeviceRef v1alpha1.LocalObjectReference `json:"deviceRef"` // DomainID is the vPC domain ID (1-1000). // This uniquely identifies the vPC domain and must match on both peer switches. @@ -27,8 +27,9 @@ type VPCDomainSpec struct { // AdminState is the administrative state of the vPC domain (enabled/disabled). // When disabled, the vPC domain is administratively shut down. - // +required - AdminState AdminState `json:"adminState"` + // +optional + // +kubebuilder:default=Up + AdminState v1alpha1.AdminState `json:"adminState"` // RolePriority is the role priority for this vPC domain (1-65535). // The switch with the lower role priority becomes the operational primary. @@ -67,17 +68,6 @@ type VPCDomainSpec struct { Peer Peer `json:"peer"` } -// AdminState represents the administrative state of the peer-link connection (Up/Down). -// +kubebuilder:validation:Enum=Up;Down -type AdminState string - -const ( - // AdminStateUp indicates the connection to the peer is administratively enabled. - AdminStateUp AdminState = "Up" - // AdminStateDown indicates the connection to the peer is administratively disabled. - AdminStateDown AdminState = "Down" -) - // Enabled represents a simple enabled/disabled configuration. type Enabled struct { // Enabled indicates whether a configuration property is administratively enabled (true) or disabled (false). @@ -88,14 +78,15 @@ type Enabled struct { // Peer defines settings to configure peer settings type Peer struct { // AdminState defines the administrative state of the peer-link. - // +required - AdminState AdminState `json:"adminState"` + // +optional + // +kubebuilder:default=Up + AdminState v1alpha1.AdminState `json:"adminState"` // InterfaceRef is a reference to an Interface resource and identifies the interface to be used as the vPC domain's peer-link. // This interface carries control and data traffic between the two vPC domain peers. // It is usually dedicated port-channel, but it can also be a single physical interface. // +required - InterfaceRef corev1.LocalObjectReference `json:"interfaceRef,omitempty"` + InterfaceRef v1alpha1.LocalObjectReference `json:"interfaceRef,omitempty"` // KeepAlive defines the out-of-band keepalive configuration. // +required @@ -145,7 +136,7 @@ type KeepAlive struct { // If specified, the switch sends keepalive packets throughout this VRF. // If omitted, the management VRF is used. // +optional - VRFRef *corev1.LocalObjectReference `json:"vrfRef,omitempty"` + VRFRef *v1alpha1.LocalObjectReference `json:"vrfRef,omitempty"` } // AutoRecovery holds settings to automatically restore vPC domain's operation after detecting diff --git a/api/core/v1alpha1/bgp_peer_types.go b/api/core/v1alpha1/bgp_peer_types.go index bfd07ff9..32215087 100644 --- a/api/core/v1alpha1/bgp_peer_types.go +++ b/api/core/v1alpha1/bgp_peer_types.go @@ -21,6 +21,12 @@ type BGPPeerSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether this BGP peer is administratively up or down. + // When Down, the BGP session with this peer is administratively shut down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // Address is the IPv4 address of the BGP peer. // +required // +kubebuilder:validation:Format=ipv4 diff --git a/api/core/v1alpha1/bgp_types.go b/api/core/v1alpha1/bgp_types.go index d6de64ef..6efcad62 100644 --- a/api/core/v1alpha1/bgp_types.go +++ b/api/core/v1alpha1/bgp_types.go @@ -21,6 +21,11 @@ type BGPSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether this BGP router is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // ASNumber is the autonomous system number (ASN) for the BGP router. // Supports both plain format (1-4294967295) and dotted notation (1-65535.0-65535) as per RFC 5396. // +required diff --git a/api/core/v1alpha1/dns_types.go b/api/core/v1alpha1/dns_types.go index 8747d734..1b093928 100644 --- a/api/core/v1alpha1/dns_types.go +++ b/api/core/v1alpha1/dns_types.go @@ -20,6 +20,11 @@ type DNSSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether DNS is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // Default domain name that the device uses to complete unqualified hostnames. // +required // +kubebuilder:validation:MinLength=1 diff --git a/api/core/v1alpha1/interface_types.go b/api/core/v1alpha1/interface_types.go index 336240fb..5e75eb1b 100644 --- a/api/core/v1alpha1/interface_types.go +++ b/api/core/v1alpha1/interface_types.go @@ -43,7 +43,8 @@ type InterfaceSpec struct { Name string `json:"name"` // AdminState indicates whether the interface is administratively up or down. - // +required + // +optional + // +kubebuilder:default=Up AdminState AdminState `json:"adminState"` // Description provides a human-readable description of the interface. @@ -95,14 +96,16 @@ type InterfaceSpec struct { BFD *BFD `json:"bfd,omitempty"` } -// AdminState represents the administrative state of the interface. +// AdminState represents the administrative state of a resource. +// This type is used across multiple resources including interfaces, protocols (BGP, OSPF, ISIS, PIM), +// and system services (NTP, DNS) to indicate whether these are administratively enabled or disabled. // +kubebuilder:validation:Enum=Up;Down type AdminState string const ( - // AdminStateUp indicates that the interface is administratively set up. + // AdminStateUp indicates that the resource is administratively enabled. AdminStateUp AdminState = "Up" - // AdminStateDown indicates that the interface is administratively set down. + // AdminStateDown indicates that the resource is administratively disabled. AdminStateDown AdminState = "Down" ) diff --git a/api/core/v1alpha1/isis_types.go b/api/core/v1alpha1/isis_types.go index 0399f0ec..9bcc7fab 100644 --- a/api/core/v1alpha1/isis_types.go +++ b/api/core/v1alpha1/isis_types.go @@ -20,6 +20,11 @@ type ISISSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether the ISIS instance is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // Instance is the name of the ISIS instance. // +required // +kubebuilder:validation:MinLength=1 diff --git a/api/core/v1alpha1/ntp_types.go b/api/core/v1alpha1/ntp_types.go index 3263f445..7b950801 100644 --- a/api/core/v1alpha1/ntp_types.go +++ b/api/core/v1alpha1/ntp_types.go @@ -20,6 +20,11 @@ type NTPSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether NTP is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // Source interface for all NTP traffic. // +required // +kubebuilder:validation:MinLength=1 diff --git a/api/core/v1alpha1/ospf_types.go b/api/core/v1alpha1/ospf_types.go index 0de718a0..b72b4a53 100644 --- a/api/core/v1alpha1/ospf_types.go +++ b/api/core/v1alpha1/ospf_types.go @@ -20,6 +20,11 @@ type OSPFSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether the OSPF instance is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // Instance is the process tag of the OSPF instance. // +required // +kubebuilder:validation:MinLength=1 diff --git a/api/core/v1alpha1/pim_types.go b/api/core/v1alpha1/pim_types.go index 59038343..87753dc3 100644 --- a/api/core/v1alpha1/pim_types.go +++ b/api/core/v1alpha1/pim_types.go @@ -20,6 +20,11 @@ type PIMSpec struct { // +optional ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"` + // AdminState indicates whether the PIM instance is administratively up or down. + // +optional + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` + // RendezvousPoints defines the list of rendezvous points for sparse mode multicast. // +optional // +listType=map diff --git a/api/core/v1alpha1/ref_types.go b/api/core/v1alpha1/ref_types.go index ff7c576a..9a1aefdc 100644 --- a/api/core/v1alpha1/ref_types.go +++ b/api/core/v1alpha1/ref_types.go @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2025 SAP SE or an SAP affiliate company and IronCore contributors // SPDX-License-Identifier: Apache-2.0 + package v1alpha1 // LocalObjectReference contains enough information to locate a diff --git a/api/core/v1alpha1/vlan_types.go b/api/core/v1alpha1/vlan_types.go index 4db8b267..e06355ab 100644 --- a/api/core/v1alpha1/vlan_types.go +++ b/api/core/v1alpha1/vlan_types.go @@ -37,21 +37,10 @@ type VLANSpec struct { // AdminState indicates whether the VLAN is administratively active or inactive/suspended. // +optional - // +kubebuilder:default=Active - AdminState VLANState `json:"adminState"` + // +kubebuilder:default=Up + AdminState AdminState `json:"adminState,omitempty"` } -// VLANState represents the administrative state of the VLAN. -// +kubebuilder:validation:Enum=Active;Suspended -type VLANState string - -const ( - // VLANStateActive indicates that the VLAN is administratively active. - VLANStateActive VLANState = "Active" - // VLANStateSuspended indicates that the VLAN is administratively inactive/suspended. - VLANStateSuspended VLANState = "Suspended" -) - // VLANStatus defines the observed state of VLAN. type VLANStatus struct { // The conditions are a list of status objects that describe the state of the VLAN. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgp.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgp.yaml index 22630388..71e878c7 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgp.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgp.yaml @@ -228,6 +228,14 @@ spec: type: object type: object type: object + adminState: + default: Up + description: AdminState indicates whether this BGP router is administratively + up or down. + enum: + - Up + - Down + type: string asNumber: anyOf: - type: integer diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgppeers.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgppeers.yaml index 3abbc534..c3a9c9a0 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgppeers.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_bgppeers.yaml @@ -165,6 +165,15 @@ spec: type: string type: object type: object + adminState: + default: Up + description: |- + AdminState indicates whether this BGP peer is administratively up or down. + When Down, the BGP session with this peer is administratively shut down. + enum: + - Up + - Down + type: string asNumber: anyOf: - type: integer diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_devices.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_devices.yaml index ff6b374b..c333486e 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_devices.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_devices.yaml @@ -184,7 +184,7 @@ spec: rule: '!has(oldSelf.secretRef) || has(self.secretRef)' provisioning: description: |- - Bootstrap is an optional configuration for the device bootstrap process. + Provisioning is an optional configuration for the device provisioning process. It can be used to provide initial configuration templates or scripts that are applied during the device provisioning. properties: bootScript: @@ -372,7 +372,7 @@ spec: enum: - Pending - Provisioning - - Active + - Running - Failed - Provisioned type: string @@ -431,12 +431,20 @@ spec: type: string error: type: string + phase: + description: ProvisioningPhase represents the reason for the + current provisioning status. + type: string + reboot: + format: date-time + type: string startTime: format: date-time type: string token: type: string required: + - phase - startTime - token type: object diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_dns.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_dns.yaml index 04ac01ba..8fc01137 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_dns.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_dns.yaml @@ -57,6 +57,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether DNS is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_interfaces.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_interfaces.yaml index 77274cf4..7245049b 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_interfaces.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_interfaces.yaml @@ -83,6 +83,7 @@ spec: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: adminState: + default: Up description: AdminState indicates whether the interface is administratively up or down. enum: @@ -407,7 +408,6 @@ spec: type: object x-kubernetes-map-type: atomic required: - - adminState - deviceRef - name - type diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_isis.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_isis.yaml index 984282fd..42fff7cb 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_isis.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_isis.yaml @@ -71,6 +71,14 @@ spec: minItems: 1 type: array x-kubernetes-list-type: set + adminState: + default: Up + description: AdminState indicates whether the ISIS instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ntp.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ntp.yaml index e8b38823..abe88726 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ntp.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ntp.yaml @@ -57,6 +57,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether NTP is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ospf.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ospf.yaml index e6e33653..955e2e6e 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ospf.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_ospf.yaml @@ -75,6 +75,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the OSPF instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_pim.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_pim.yaml index 3f97bfec..bfe185fc 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_pim.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_pim.yaml @@ -57,6 +57,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the PIM instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_vlans.yaml b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_vlans.yaml index 11bfd826..b154e016 100644 --- a/charts/network-operator/templates/crd/networking.metal.ironcore.dev_vlans.yaml +++ b/charts/network-operator/templates/crd/networking.metal.ironcore.dev_vlans.yaml @@ -72,12 +72,12 @@ spec: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: adminState: - default: Active + default: Up description: AdminState indicates whether the VLAN is administratively active or inactive/suspended. enum: - - Active - - Suspended + - Up + - Down type: string deviceRef: description: |- diff --git a/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml b/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml index a7c7953d..9a512c19 100644 --- a/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml +++ b/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml @@ -59,6 +59,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the BorderGateway instance + is administratively up or down. + enum: + - Up + - Down + type: string bgpPeerRefs: description: |- BGPPeerRefs is a list of BGP peers that are part of the border gateway configuration. diff --git a/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml b/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml index afb1f0ea..18bef2c1 100644 --- a/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml +++ b/charts/network-operator/templates/crd/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml @@ -96,6 +96,7 @@ spec: description: spec defines the desired state of VPCDomain resource properties: adminState: + default: Up description: |- AdminState is the administrative state of the vPC domain (enabled/disabled). When disabled, the vPC domain is administratively shut down. @@ -160,6 +161,7 @@ spec: peer-link, keepalive. properties: adminState: + default: Up description: AdminState defines the administrative state of the peer-link. enum: @@ -287,7 +289,6 @@ spec: - enabled type: object required: - - adminState - interfaceRef - keepalive type: object @@ -308,7 +309,6 @@ spec: minimum: 1 type: integer required: - - adminState - deviceRef - domainId - peer diff --git a/config/crd/bases/networking.metal.ironcore.dev_bgp.yaml b/config/crd/bases/networking.metal.ironcore.dev_bgp.yaml index 23392f15..8a826d4b 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_bgp.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_bgp.yaml @@ -222,6 +222,14 @@ spec: type: object type: object type: object + adminState: + default: Up + description: AdminState indicates whether this BGP router is administratively + up or down. + enum: + - Up + - Down + type: string asNumber: anyOf: - type: integer diff --git a/config/crd/bases/networking.metal.ironcore.dev_bgppeers.yaml b/config/crd/bases/networking.metal.ironcore.dev_bgppeers.yaml index e3ffca1d..cbd6ed6e 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_bgppeers.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_bgppeers.yaml @@ -159,6 +159,15 @@ spec: type: string type: object type: object + adminState: + default: Up + description: |- + AdminState indicates whether this BGP peer is administratively up or down. + When Down, the BGP session with this peer is administratively shut down. + enum: + - Up + - Down + type: string asNumber: anyOf: - type: integer diff --git a/config/crd/bases/networking.metal.ironcore.dev_dns.yaml b/config/crd/bases/networking.metal.ironcore.dev_dns.yaml index 84a72045..ca176ed7 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_dns.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_dns.yaml @@ -51,6 +51,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether DNS is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/config/crd/bases/networking.metal.ironcore.dev_interfaces.yaml b/config/crd/bases/networking.metal.ironcore.dev_interfaces.yaml index 4292b3e2..9284fee0 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_interfaces.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_interfaces.yaml @@ -77,6 +77,7 @@ spec: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: adminState: + default: Up description: AdminState indicates whether the interface is administratively up or down. enum: @@ -401,7 +402,6 @@ spec: type: object x-kubernetes-map-type: atomic required: - - adminState - deviceRef - name - type diff --git a/config/crd/bases/networking.metal.ironcore.dev_isis.yaml b/config/crd/bases/networking.metal.ironcore.dev_isis.yaml index cc7b42f3..543295b9 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_isis.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_isis.yaml @@ -65,6 +65,14 @@ spec: minItems: 1 type: array x-kubernetes-list-type: set + adminState: + default: Up + description: AdminState indicates whether the ISIS instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml index 8846f8c2..0e83abf5 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml @@ -51,6 +51,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether NTP is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/config/crd/bases/networking.metal.ironcore.dev_ospf.yaml b/config/crd/bases/networking.metal.ironcore.dev_ospf.yaml index 24ca6fee..6c4958d8 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_ospf.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_ospf.yaml @@ -69,6 +69,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the OSPF instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/config/crd/bases/networking.metal.ironcore.dev_pim.yaml b/config/crd/bases/networking.metal.ironcore.dev_pim.yaml index d3645376..b71f6e2c 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_pim.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_pim.yaml @@ -51,6 +51,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the PIM instance is administratively + up or down. + enum: + - Up + - Down + type: string deviceRef: description: |- DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace. diff --git a/config/crd/bases/networking.metal.ironcore.dev_vlans.yaml b/config/crd/bases/networking.metal.ironcore.dev_vlans.yaml index 5e88acef..04178f8a 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_vlans.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_vlans.yaml @@ -66,12 +66,12 @@ spec: More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: adminState: - default: Active + default: Up description: AdminState indicates whether the VLAN is administratively active or inactive/suspended. enum: - - Active - - Suspended + - Up + - Down type: string deviceRef: description: |- diff --git a/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml b/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml index c0911965..5a68eb76 100644 --- a/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml +++ b/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_bordergateways.yaml @@ -53,6 +53,14 @@ spec: Specification of the desired state of the resource. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status properties: + adminState: + default: Up + description: AdminState indicates whether the BorderGateway instance + is administratively up or down. + enum: + - Up + - Down + type: string bgpPeerRefs: description: |- BGPPeerRefs is a list of BGP peers that are part of the border gateway configuration. diff --git a/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml b/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml index ae30e8a5..5f5319b1 100644 --- a/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml +++ b/config/crd/bases/nx.cisco.networking.metal.ironcore.dev_vpcdomains.yaml @@ -90,6 +90,7 @@ spec: description: spec defines the desired state of VPCDomain resource properties: adminState: + default: Up description: |- AdminState is the administrative state of the vPC domain (enabled/disabled). When disabled, the vPC domain is administratively shut down. @@ -154,6 +155,7 @@ spec: peer-link, keepalive. properties: adminState: + default: Up description: AdminState defines the administrative state of the peer-link. enum: @@ -281,7 +283,6 @@ spec: - enabled type: object required: - - adminState - interfaceRef - keepalive type: object @@ -302,7 +303,6 @@ spec: minimum: 1 type: integer required: - - adminState - deviceRef - domainId - peer diff --git a/config/samples/v1alpha1_vlan.yaml b/config/samples/v1alpha1_vlan.yaml index 0dd271ba..a253a0d4 100644 --- a/config/samples/v1alpha1_vlan.yaml +++ b/config/samples/v1alpha1_vlan.yaml @@ -11,4 +11,3 @@ spec: name: leaf1 id: 10 name: MonteCarlo - adminState: Active diff --git a/internal/controller/core/evpninstance_controller_test.go b/internal/controller/core/evpninstance_controller_test.go index 92628f36..78626108 100644 --- a/internal/controller/core/evpninstance_controller_test.go +++ b/internal/controller/core/evpninstance_controller_test.go @@ -73,7 +73,7 @@ var _ = Describe("EVPNInstance Controller", func() { DeviceRef: v1alpha1.LocalObjectReference{Name: name}, ID: 10, Name: "vlan-10", - AdminState: v1alpha1.VLANStateActive, + AdminState: v1alpha1.AdminStateUp, }, } Expect(k8sClient.Create(ctx, vlan)).To(Succeed()) @@ -200,7 +200,7 @@ var _ = Describe("EVPNInstance Controller", func() { DeviceRef: v1alpha1.LocalObjectReference{Name: "different-device"}, ID: 10, Name: "vlan-10", - AdminState: v1alpha1.VLANStateActive, + AdminState: v1alpha1.AdminStateUp, }, } Expect(k8sClient.Create(ctx, vlan)).To(Succeed()) diff --git a/internal/controller/core/interface_controller_test.go b/internal/controller/core/interface_controller_test.go index 6a64d06d..915b852c 100644 --- a/internal/controller/core/interface_controller_test.go +++ b/internal/controller/core/interface_controller_test.go @@ -642,7 +642,7 @@ var _ = Describe("Interface Controller", func() { DeviceRef: v1alpha1.LocalObjectReference{Name: name}, ID: 100, Name: "test-vlan", - AdminState: v1alpha1.VLANStateActive, + AdminState: v1alpha1.AdminStateUp, }, } Expect(k8sClient.Create(ctx, vlan)).To(Succeed()) @@ -741,7 +741,7 @@ var _ = Describe("Interface Controller", func() { DeviceRef: v1alpha1.LocalObjectReference{Name: "different-device"}, ID: 100, Name: "test-vlan", - AdminState: v1alpha1.VLANStateActive, + AdminState: v1alpha1.AdminStateUp, }, } Expect(k8sClient.Create(ctx, vlan)).To(Succeed()) diff --git a/internal/controller/core/vlan_controller_test.go b/internal/controller/core/vlan_controller_test.go index bdafac8d..9c4c3ef1 100644 --- a/internal/controller/core/vlan_controller_test.go +++ b/internal/controller/core/vlan_controller_test.go @@ -50,7 +50,7 @@ var _ = Describe("VLAN Controller", func() { DeviceRef: v1alpha1.LocalObjectReference{Name: name}, ID: id, Name: "Scrum", - AdminState: v1alpha1.VLANStateActive, + AdminState: v1alpha1.AdminStateUp, }, } Expect(k8sClient.Create(ctx, resource)).To(Succeed()) diff --git a/internal/provider/cisco/nxos/bgp.go b/internal/provider/cisco/nxos/bgp.go index 1c5b27a0..00226d88 100644 --- a/internal/provider/cisco/nxos/bgp.go +++ b/internal/provider/cisco/nxos/bgp.go @@ -115,6 +115,7 @@ func (af *BGPDomAfItem) SetMultipath(m *v1alpha1.BGPMultipath) error { type BGPPeer struct { Addr string `json:"addr"` + AdminSt AdminSt `json:"adminSt"` Asn string `json:"asn"` AsnType PeerAsnType `json:"asnType"` Name string `json:"name,omitempty"` diff --git a/internal/provider/cisco/nxos/bgp_test.go b/internal/provider/cisco/nxos/bgp_test.go index 50c156e1..7f2fb008 100644 --- a/internal/provider/cisco/nxos/bgp_test.go +++ b/internal/provider/cisco/nxos/bgp_test.go @@ -20,6 +20,7 @@ func init() { bgpPeer := &BGPPeer{ Addr: "1.1.1.1", + AdminSt: AdminStEnabled, Asn: "65000", AsnType: PeerAsnTypeNone, Name: "EVPN peering with spine", diff --git a/internal/provider/cisco/nxos/ntp.go b/internal/provider/cisco/nxos/ntp.go index 438ee927..a4b297bf 100644 --- a/internal/provider/cisco/nxos/ntp.go +++ b/internal/provider/cisco/nxos/ntp.go @@ -28,6 +28,7 @@ func (*NTP) XPath() string { func (n *NTP) Default() { n.AdminSt = AdminStDisabled + n.Logging = AdminStDisabled } type NTPProvider struct { diff --git a/internal/provider/cisco/nxos/pim.go b/internal/provider/cisco/nxos/pim.go index 046608d1..49c3191f 100644 --- a/internal/provider/cisco/nxos/pim.go +++ b/internal/provider/cisco/nxos/pim.go @@ -6,11 +6,35 @@ package nxos import "github.com/ironcore-dev/network-operator/internal/provider/cisco/gnmiext/v2" var ( + _ gnmiext.Configurable = (*PIM)(nil) + _ gnmiext.Configurable = (*PIMDom)(nil) _ gnmiext.Configurable = (*StaticRPItems)(nil) _ gnmiext.Configurable = (*AnycastPeerItems)(nil) _ gnmiext.Configurable = (*PIMIfItems)(nil) ) +type PIM struct { + AdminSt AdminSt `json:"adminSt"` + InstItems struct { + AdminSt AdminSt `json:"adminSt"` + } `json:"inst-items"` +} + +func (*PIM) XPath() string { + return "System/pim-items" +} + +type PIMDom struct { + Name string `json:"name"` + AdminSt AdminSt `json:"adminSt"` +} + +func (*PIMDom) IsListItem() {} + +func (p *PIMDom) XPath() string { + return "System/pim-items/inst-items/dom-items/Dom-list[name=" + p.Name + "]" +} + type StaticRPItems struct { StaticRPList gnmiext.List[string, *StaticRP] `json:"StaticRP-list,omitzero"` } diff --git a/internal/provider/cisco/nxos/provider.go b/internal/provider/cisco/nxos/provider.go index f44c942f..4010c530 100644 --- a/internal/provider/cisco/nxos/provider.go +++ b/internal/provider/cisco/nxos/provider.go @@ -246,6 +246,9 @@ func (p *Provider) EnsureBGP(ctx context.Context, req *provider.EnsureBGPRequest b := new(BGP) b.AdminSt = AdminStEnabled + if req.BGP.Spec.AdminState == v1alpha1.AdminStateDown { + b.AdminSt = AdminStDisabled + } b.Asn = req.BGP.Spec.ASNumber.String() var asf AsFormat @@ -321,6 +324,10 @@ func (p *Provider) EnsureBGPPeer(ctx context.Context, req *provider.EnsureBGPPee pe := new(BGPPeer) pe.Addr = req.BGPPeer.Spec.Address + pe.AdminSt = AdminStEnabled + if req.BGPPeer.Spec.AdminState == v1alpha1.AdminStateDown { + pe.AdminSt = AdminStDisabled + } pe.Asn = req.BGPPeer.Spec.ASNumber.String() pe.AsnType = PeerAsnTypeNone pe.Name = req.BGPPeer.Spec.Description @@ -432,6 +439,9 @@ func (p *Provider) DeleteCertificate(ctx context.Context, req *provider.DeleteCe func (p *Provider) EnsureDNS(ctx context.Context, req *provider.EnsureDNSRequest) error { d := new(DNS) d.AdminSt = AdminStEnabled + if req.DNS.Spec.AdminState == v1alpha1.AdminStateDown { + d.AdminSt = AdminStDisabled + } pf := new(DNSProf) pf.Name = DefaultVRFName @@ -1115,6 +1125,9 @@ func (p *Provider) EnsureISIS(ctx context.Context, req *provider.EnsureISISReque i := new(ISIS) i.AdminSt = AdminStEnabled + if req.ISIS.Spec.AdminState == v1alpha1.AdminStateDown { + i.AdminSt = AdminStDisabled + } i.Name = req.ISIS.Spec.Instance dom := new(ISISDom) @@ -1294,6 +1307,9 @@ func (p *Provider) EnsureNTP(ctx context.Context, req *provider.EnsureNTPRequest n := new(NTP) n.AdminSt = AdminStEnabled + if req.NTP.Spec.AdminState == v1alpha1.AdminStateDown { + n.AdminSt = AdminStDisabled + } n.Logging = AdminStDisabled if cfg.Log.Enable { n.Logging = AdminStEnabled @@ -1448,6 +1464,9 @@ func (p *Provider) EnsureOSPF(ctx context.Context, req *provider.EnsureOSPFReque o := new(OSPF) o.AdminSt = AdminStEnabled + if req.OSPF.Spec.AdminState == v1alpha1.AdminStateDown { + o.AdminSt = AdminStDisabled + } o.Name = req.OSPF.Spec.Instance conf = append(conf, o) @@ -1458,6 +1477,9 @@ func (p *Provider) EnsureOSPF(ctx context.Context, req *provider.EnsureOSPFReque dom.AdjChangeLogLevel = AdjChangeLogLevelBrief } dom.AdminSt = AdminStEnabled + if req.OSPF.Spec.AdminState == v1alpha1.AdminStateDown { + dom.AdminSt = AdminStDisabled + } dom.BwRef = DefaultBwRef // default 40 Gbps dom.BwRefUnit = BwRefUnitMbps if cfg.ReferenceBandwidthMbps != 0 { @@ -1599,6 +1621,25 @@ func (p *Provider) EnsurePIM(ctx context.Context, req *provider.EnsurePIMRequest f.Name = "pim" f.AdminSt = AdminStEnabled + pim := new(PIM) + pim.AdminSt = AdminStEnabled + pim.InstItems.AdminSt = AdminStEnabled + if req.PIM.Spec.AdminState == v1alpha1.AdminStateDown { + pim.AdminSt = AdminStDisabled + pim.InstItems.AdminSt = AdminStDisabled + } + + dom := new(PIMDom) + dom.Name = DefaultVRFName + dom.AdminSt = AdminStEnabled + if req.PIM.Spec.AdminState == v1alpha1.AdminStateDown { + dom.AdminSt = AdminStDisabled + } + + if err := p.client.Patch(ctx, pim, dom); err != nil { + return err + } + rpItems := new(StaticRPItems) apItems := new(AnycastPeerItems) @@ -2023,10 +2064,8 @@ func (p *Provider) EnsureVLAN(ctx context.Context, req *provider.VLANRequest) er v := new(VLAN) v.FabEncap = fmt.Sprintf("vlan-%d", req.VLAN.Spec.ID) v.AdminSt = BdStateActive - switch req.VLAN.Spec.AdminState { - case v1alpha1.VLANStateActive: - v.BdState = BdStateActive - case v1alpha1.VLANStateSuspended: + v.BdState = BdStateActive + if req.VLAN.Spec.AdminState == v1alpha1.AdminStateDown { v.BdState = BdStateInactive } if req.VLAN.Spec.Name != "" { @@ -2250,7 +2289,7 @@ func (p *Provider) EnsureVPCDomain(ctx context.Context, vpcdomain *nxv1alpha1.VP v.Id = uint16(vpcdomain.Spec.DomainID) // #nosec G115 -- kubebuilder v.AdminSt = AdminStEnabled - if vpcdomain.Spec.AdminState == nxv1alpha1.AdminStateDown { + if vpcdomain.Spec.AdminState == v1alpha1.AdminStateDown { v.AdminSt = AdminStDisabled } @@ -2315,7 +2354,7 @@ func (p *Provider) EnsureVPCDomain(ctx context.Context, vpcdomain *nxv1alpha1.VP v.KeepAliveItems.PeerLinkItems.Id = pcName v.KeepAliveItems.PeerLinkItems.AdminSt = AdminStEnabled - if vpcdomain.Spec.Peer.AdminState == nxv1alpha1.AdminStateDown { + if vpcdomain.Spec.Peer.AdminState == v1alpha1.AdminStateDown { v.KeepAliveItems.PeerLinkItems.AdminSt = AdminStDisabled } @@ -2417,6 +2456,9 @@ func (p *Provider) EnsureBorderGatewaySettings(ctx context.Context, req *BorderG conf := make([]gnmiext.Configurable, 0, 3) bg := new(MultisiteItems) bg.AdminSt = AdminStEnabled + if req.BorderGateway.Spec.AdminState == v1alpha1.AdminStateDown { + bg.AdminSt = AdminStDisabled + } bg.SiteID = strconv.FormatInt(req.BorderGateway.Spec.MultisiteID, 10) bg.DelayRestoreSeconds = int64(math.Round(req.BorderGateway.Spec.DelayRestoreTime.Seconds())) if bg.DelayRestoreSeconds < 30 || bg.DelayRestoreSeconds > 1000 { diff --git a/internal/provider/cisco/nxos/testdata/bgp_peer.json b/internal/provider/cisco/nxos/testdata/bgp_peer.json index edd22c75..71439f08 100644 --- a/internal/provider/cisco/nxos/testdata/bgp_peer.json +++ b/internal/provider/cisco/nxos/testdata/bgp_peer.json @@ -9,6 +9,7 @@ "Peer-list": [ { "addr": "1.1.1.1", + "adminSt": "enabled", "asn": "65000", "asnType": "none", "name": "EVPN peering with spine",