Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ linters:
- linters:
- tagliatelle
text: CA
- linters:
- tagliatelle
text: VLAN
paths:
- zz_generated.*\.go$
- .*conversion.*\.go$
Expand Down
109 changes: 109 additions & 0 deletions api/v1alpha1/ironic_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,100 @@ type TLS struct {
InsecureRPC *bool `json:"insecureRPC,omitempty"`
}

// SwitchportMode defines the switchport mode for network interfaces.
type SwitchportMode string

const (
// SwitchportModeAccess sets the interface to access mode (single VLAN).
SwitchportModeAccess SwitchportMode = "access"
// SwitchportModeTrunk sets the interface to trunk mode (multiple VLANs).
SwitchportModeTrunk SwitchportMode = "trunk"
// SwitchportModeHybrid sets the interface to hybrid mode (access + trunk).
SwitchportModeHybrid SwitchportMode = "hybrid"
)

// ProviderNetworkType defines the type of provider network.
type ProviderNetworkType string

const (
ProviderNetworkIdle ProviderNetworkType = "idle"
ProviderNetworkInspection ProviderNetworkType = "inspection"
ProviderNetworkCleaning ProviderNetworkType = "cleaning"
ProviderNetworkRescuing ProviderNetworkType = "rescuing"
ProviderNetworkServicing ProviderNetworkType = "servicing"
ProviderNetworkProvisioning ProviderNetworkType = "provisioning"
)

// ProviderNetworkConfig defines the network configuration for Ironic service operations.
type ProviderNetworkConfig struct {
// Type specifies which provider network this configuration applies to.
// +kubebuilder:validation:Enum=idle;inspection;cleaning;rescuing;servicing;provisioning
Type ProviderNetworkType `json:"type"`

// Mode specifies the switch port mode for service operations
// +kubebuilder:validation:Enum=access;trunk;hybrid
// +kubebuilder:default=access
Mode SwitchportMode `json:"mode"`

// NativeVLAN specifies the native VLAN ID for service operations
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=4094
NativeVLAN int32 `json:"nativeVLAN"`

// AllowedVLANs specifies the list of allowed VLANs for trunk/hybrid modes.
// Each entry can be a single VLAN ID (e.g., "100") or a range (e.g., "100-200").
// +optional
AllowedVLANs []string `json:"allowedVLANs,omitempty"`
}

// NetworkingService defines configuration for the Ironic Networking Service.
type NetworkingService struct {
// Enabled enables the Ironic Networking Service integration
// +kubebuilder:default=false
// +optional
Enabled bool `json:"enabled"`

// RPCPort is the internal RPC port used for Ironic Networking
// Only change this if the default value causes a conflict on your deployment.
// +kubebuilder:default=6190
// +kubebuilder:validation:Minimum=1
// +optional
RPCPort int32 `json:"rpcPort,omitempty"`

// NetworkDriver sets the default network interface driver for nodes.
// Defaults to "ironic-networking" when networking service is enabled.
// +kubebuilder:default=ironic-networking
// +optional
NetworkDriver string `json:"networkDriver,omitempty"`

// SwitchDrivers sets the supported switch drivers for the service.
// +kubebuilder:default={generic-switch}
// +optional
SwitchDrivers []string `json:"switchDrivers,omitempty"`

// ProviderNetworks defines the provider network configurations for Ironic
ProviderNetworks []ProviderNetworkConfig `json:"providerNetworks,omitempty"`

// Endpoint optionally specifies an external networking service hostname or IP address.
// The port is determined by the RPCPort field. If not specified and Enabled is true,
// the operator creates a separate Deployment for the networking service.
// Format: "hostname" or "ip-address"
// +optional
Endpoint string `json:"endpoint,omitempty"`

// SwitchConfigSecretName optionally specifies the name of the secret containing
// switch configuration. If not specified, defaults to "<ironic-name>-switch-config".
// This secret is automatically generated from IronicSwitch CRDs in the namespace.
// +optional
SwitchConfigSecretName string `json:"switchConfigSecretName,omitempty"`

// SwitchCredentialsSecretName optionally specifies the name of the secret containing
// additional switch credentials. If specified, the secret will be mounted to the
// networking service pod. If not specified, no credentials secret is mounted.
// +optional
SwitchCredentialsSecretName string `json:"switchCredentialsSecretName,omitempty"`
}

type Images struct {
// DeployRamdiskBranch is the branch of IPA to download. The main branch is used by default.
// Not used if deployRamdisk.disableDownloader is true.
Expand Down Expand Up @@ -366,6 +460,10 @@ type IronicSpec struct {
// +optional
Networking Networking `json:"networking,omitempty"`

// NetworkingService provides configuration for the Ironic Networking Service
// +optional
NetworkingService *NetworkingService `json:"networkingService,omitempty"`

// NodeSelector is a selector which must be true for the Ironic pod to fit on a node.
// Selector which must match a node's labels for the vmi to be scheduled on that node.
// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
Expand Down Expand Up @@ -427,6 +525,17 @@ type Ironic struct {
Status IronicStatus `json:"status,omitempty"`
}

// IsNetworkingServiceEnabled returns true if the networking service is configured and enabled.
func (i *Ironic) IsNetworkingServiceEnabled() bool {
return i.Spec.NetworkingService != nil && i.Spec.NetworkingService.Enabled
}

// IsNetworkingServiceExternal returns true if the networking service is enabled and provided
// by a separate service externally managed by the user.
func (i *Ironic) IsNetworkingServiceExternal() bool {
return i.IsNetworkingServiceEnabled() && i.Spec.NetworkingService.Endpoint != ""
}

//+kubebuilder:object:root=true

// IronicList contains a list of Ironic.
Expand Down
52 changes: 52 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions config/crd/bases/ironic.metal3.io_ironics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,103 @@ spec:
minimum: 1
type: integer
type: object
networkingService:
description: NetworkingService provides configuration for the Ironic
Networking Service
properties:
enabled:
default: false
description: Enabled enables the Ironic Networking Service integration
type: boolean
endpoint:
description: |-
Endpoint optionally specifies an external networking service hostname or IP address.
The port is determined by the RPCPort field. If not specified and Enabled is true,
the operator creates a separate Deployment for the networking service.
Format: "hostname" or "ip-address"
type: string
networkDriver:
default: ironic-networking
description: |-
NetworkDriver sets the default network interface driver for nodes.
Defaults to "ironic-networking" when networking service is enabled.
type: string
providerNetworks:
description: ProviderNetworks defines the provider network configurations
for Ironic
items:
description: ProviderNetworkConfig defines the network configuration
for Ironic service operations.
properties:
allowedVLANs:
description: |-
AllowedVLANs specifies the list of allowed VLANs for trunk/hybrid modes.
Each entry can be a single VLAN ID (e.g., "100") or a range (e.g., "100-200").
items:
type: string
type: array
mode:
default: access
description: Mode specifies the switch port mode for service
operations
enum:
- access
- trunk
- hybrid
type: string
nativeVLAN:
description: NativeVLAN specifies the native VLAN ID for
service operations
format: int32
maximum: 4094
minimum: 1
type: integer
type:
description: Type specifies which provider network this
configuration applies to.
enum:
- idle
- inspection
- cleaning
- rescuing
- servicing
- provisioning
type: string
required:
- mode
- nativeVLAN
- type
type: object
type: array
rpcPort:
default: 6190
description: |-
RPCPort is the internal RPC port used for Ironic Networking
Only change this if the default value causes a conflict on your deployment.
format: int32
minimum: 1
type: integer
switchConfigSecretName:
description: |-
SwitchConfigSecretName optionally specifies the name of the secret containing
switch configuration. If not specified, defaults to "<ironic-name>-switch-config".
This secret is automatically generated from IronicSwitch CRDs in the namespace.
type: string
switchCredentialsSecretName:
description: |-
SwitchCredentialsSecretName optionally specifies the name of the secret containing
additional switch credentials. If specified, the secret will be mounted to the
networking service pod. If not specified, no credentials secret is mounted.
type: string
switchDrivers:
default:
- generic-switch
description: SwitchDrivers sets the supported switch drivers for
the service.
items:
type: string
type: array
type: object
nodeSelector:
additionalProperties:
type: string
Expand Down
39 changes: 39 additions & 0 deletions config/samples/ironic_with_networking_sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: ironic.metal3.io/v1alpha1
kind: Ironic
metadata:
name: ironic-with-networking
spec:
# Enable networking service for ToR switch integration
# The operator deploys the networking service in a separate Deployment/Service
# for better isolation and independent restart behavior
networkingService:
enabled: true

# Optional: External networking service endpoint (hostname or IP)
# If not specified, the operator creates and manages a networking service deployment
# Format: "hostname" or "ip-address" (port is determined by rpcPort)
# endpoint: "external-networking.example.com"

# Optional: RPC port (defaults to 6190)
# rpcPort: 6190

# Optional: Network driver (defaults to "ironic-networking")
networkDriver: "ironic-networking"

# Optional: Provider network configurations
# Each entry maps to IRONIC_NETWORKING_<TYPE>_NETWORK env var
# Supported types: idle, inspection, cleaning, rescuing, servicing, provisioning
providerNetworks:
- type: "idle"
mode: "access"
nativeVLAN: 313

- type: "inspection"
mode: "access"
nativeVLAN: 313

# Example: trunk mode with allowed VLANs (supports individual IDs and ranges)
# - type: "cleaning"
# mode: "trunk"
# nativeVLAN: 313
# allowedVLANs: ["313", "400-500"]
Loading
Loading