Kubermatic Virtualization CRDs Reference

v1alpha1

KubeVRole

KubeVRole defines what operations a subject may perform.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specKubeVRoleSpectrue

Back to Group

KubeVRoleBinding

KubeVRoleBinding grants a KubeVRole to a user.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specKubeVRoleBindingSpectrue

Back to Group

KubeVRoleBindingList

KubeVRoleBindingList is the list type for KubeVRoleBinding.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]KubeVRoleBindingtrue

Back to Group

KubeVRoleBindingSpec

KubeVRoleBindingSpec defines who gets what role.

FieldDescriptionSchemeRequired
subjectSubject is the name of the User being bound.stringtrue
roleRefRoleRef is the name of the KubeVRole to grant.stringtrue

Back to Group

KubeVRoleList

KubeVRoleList is the list type for KubeVRole.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]KubeVRoletrue

Back to Group

KubeVRoleSpec

KubeVRoleSpec defines the rules of a KubeVRole.

FieldDescriptionSchemeRequired
displayNameDisplayName is a human-readable label shown in the UI.stringfalse
descriptionDescription explains what this role is intended for.stringfalse
systemSystem marks the role as built-in. System roles cannot be deleted via the API.boolfalse
rulesRules is the list of policy rules that define the permissions of this role.[]PolicyRuletrue

Back to Group

PolicyRule

PolicyRule grants a set of verbs on a set of resources, optionally scoped to one or more resource groups. Any field left empty (or set to ["*"]) is a wildcard that matches everything.

Example — full compute access:

{ resourceGroups: [\"compute\"], verbs: [\"*\"] }

Example — read-only access to a single resource type:

{ resourceGroups: [\"networking\"], resources: [\"subnets\"], verbs: [\"view\"] }
FieldDescriptionSchemeRequired
resourceGroupsResourceGroups scopes the rule to one or more IAM resource categories (e.g. "compute", "networking", "storage", "iam"). An empty list or ["*"] matches all groups.[]stringfalse
resourcesResources further narrows the rule to specific resource types within the group (e.g. "virtualmachines", "subnets"). An empty list or ["*"] matches all resources in the matched groups.[]stringfalse
verbsVerbs is the list of operations this rule permits. Standard verbs are: create, delete, update, view, manage, start, stop, restart, console. The wildcard "*" permits all verbs.[]stringtrue

Back to Group

User

User represents a synced OIDC identity. The controller creates and updates these from OIDC subject claims so that bindings can reference stable K8s resource names instead of raw OIDC subjects.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specUserSpecfalse
statusUserStatusfalse

Back to Group

UserList

UserList is the list type for User.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]Usertrue

Back to Group

UserSpec

UserSpec is the desired state of a User.

FieldDescriptionSchemeRequired
subSub is the stable OIDC subject identifier (never changes for a given user).stringtrue
emailEmail is the user’s email address from the OIDC claims.stringfalse
nameName is the user’s display name from the OIDC claims.stringfalse
disabledDisabled prevents the user from authenticating when true.boolfalse

Back to Group

UserStatus

UserStatus is the observed state of a User.

FieldDescriptionSchemeRequired
lastSeenLastSeen is the timestamp of the user’s most recent authentication.*metav1.Timefalse

Back to Group

Image

Image is a catalog entry describing an OS image available for use as a DataVolume source when creating VirtualMachines or VMPools.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specImageSpecfalse

Back to Group

ImageList

ImageList is the list type for Image.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]Imagetrue

Back to Group

ImageSourceGCS

ImageSourceGCS references an image stored in Google Cloud Storage.

FieldDescriptionSchemeRequired
urlURL is the GCS URL of the image.stringtrue

Back to Group

ImageSourceHTTP

ImageSourceHTTP references an image hosted at an HTTP/HTTPS URL.

FieldDescriptionSchemeRequired
urlURL is the full HTTP/HTTPS URL of the image.stringtrue

Back to Group

ImageSourcePVC

ImageSourcePVC references an image backed by an existing PersistentVolumeClaim.

FieldDescriptionSchemeRequired
nameName is the PVC name.stringtrue
namespaceNamespace is the PVC namespace. Defaults to the Image’s namespace when omitted.stringfalse

Back to Group

ImageSourceRegistry

ImageSourceRegistry references an image stored in a container registry.

FieldDescriptionSchemeRequired
urlURL is the full registry URL including tag or digest (e.g. docker.io/library/ubuntu:22.04).stringtrue

Back to Group

ImageSourceS3

ImageSourceS3 references an image stored in an S3-compatible bucket.

FieldDescriptionSchemeRequired
urlURL is the S3 URL of the image.stringtrue

Back to Group

ImageSpec

ImageSpec defines the desired state of an Image.

FieldDescriptionSchemeRequired
typeType identifies the kind of source backing this image.ImageSourceTypetrue
readableNameReadableName is a human-friendly display name shown in the UI.stringtrue
readableDescriptionReadableDescription is an optional human-friendly description.stringfalse
credentialsCredentials is an optional reference to a Secret holding credentials required to access the image source.stringfalse
httpHTTP describes an image hosted at an HTTP/HTTPS URL.*ImageSourceHTTPfalse
registryRegistry describes an image stored in a container registry.*ImageSourceRegistryfalse
s3S3 describes an image stored in an S3-compatible object store.*ImageSourceS3false
gcsGCS describes an image stored in Google Cloud Storage.*ImageSourceGCSfalse
pvcPVC describes an image backed by an existing PersistentVolumeClaim.*ImageSourcePVCfalse

Back to Group

SSHKey

SSHKey stores an SSH public key in the workspace namespace. The controller reconciles each SSHKey into an owned K8s Secret so that cloud-init can inject the key into virtual machines at creation time.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specSSHKeySpecfalse
statusSSHKeyStatusfalse

Back to Group

SSHKeyList

SSHKeyList is the list type for SSHKey.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]SSHKeytrue

Back to Group

SSHKeySpec

SSHKeySpec defines the desired state of an SSHKey.

FieldDescriptionSchemeRequired
publicKeyPublicKey is the SSH public key content (e.g. "ssh-rsa AAAA… user@host").stringtrue

Back to Group

SSHKeyStatus

SSHKeyStatus is the observed state of an SSHKey.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase.SSHKeyPhasefalse
secretRefSecretRef is the name of the managed Secret in the same namespace.stringfalse
messageMessage contains a human-readable description of the current phase.stringfalse

Back to Group

BackupObject

BackupObject records a single disk image uploaded to the storage location.

FieldDescriptionSchemeRequired
volumeNameVolumeName is the VirtualMachine volume this object was captured from.stringtrue
dataVolumeNameDataVolumeName is the original CDI DataVolume name backing the volume.stringfalse
objectKeyObjectKey is the key of the uploaded image within the bucket.stringtrue
sizeBytesSizeBytes is the size of the uploaded image in bytes.integerfalse
formatFormat is the image format that was uploaded, e.g. “gzip”.stringfalse

Back to Group

BackupStorageLocation

BackupStorageLocation is the namespace-scoped configuration for an S3-compatible object storage target that VM backups are written to. An administrator creates one or more locations per namespace; the dashboard lists them so a user can pick a destination when creating a backup.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specBackupStorageLocationSpecfalse
statusBackupStorageLocationStatusfalse

Back to Group

BackupStorageLocationList

BackupStorageLocationList is the list type for BackupStorageLocation.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
itemsBackupStorageLocation arraytrue

Back to Group

BackupStorageLocationSpec

BackupStorageLocationSpec defines an object storage destination for backups.

FieldDescriptionSchemeRequired
providerProvider is the object storage backend. Only “s3” (S3-compatible) is supported.stringtrue
bucketBucket is the name of the bucket that backup objects are written to.stringtrue
endpointEndpoint is the S3 endpoint URL for non-AWS backends (e.g. MinIO or Ceph RGW), such as “https://minio.example.com:9000”. Leave empty for AWS S3.stringfalse
regionRegion is the S3 region. Optional for endpoints that do not require it.stringfalse
prefixPrefix is an optional object key prefix applied to every backup written to this location, allowing several locations to share one bucket.stringfalse
credentialsSecretRefCredentialsSecretRef is the name of a Secret in the same namespace holding the S3 credentials. The Secret must use the keys “accessKeyId” and “secretKey” so it can be consumed directly by CDI on restore.stringtrue
caBundleConfigMapRefCABundleConfigMapRef is the name of a ConfigMap in the same namespace whose data provides a custom CA bundle for verifying the endpoint’s TLS certificate.stringfalse
insecureSkipTLSVerifyInsecureSkipTLSVerify disables TLS certificate verification for the endpoint. Intended for development backends with self-signed certificates. It applies only to the backup upload path; CDI cannot skip verification on restore, so a TLS endpoint that relies on this flag must also set CABundleConfigMapRef to be restorable.booleanfalse

Back to Group

BackupStorageLocationStatus

BackupStorageLocationStatus is the observed state of a BackupStorageLocation.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase of this location. It reaches Ready once the referenced credentials Secret exists with the required keys. This does not probe the endpoint; actual bucket reachability surfaces when a backup’s upload Job runs.Phasefalse
messageMessage is a human-readable explanation of the current phase, typically the reason a validation check failed.stringfalse
lastValidatedLastValidated is the time the location was last successfully validated.metav1.Timefalse

Back to Group

DNATRule

DNATRule maps an external port on an EIP to an internal address and port.

FieldDescriptionSchemeRequired
externalPortExternalPort is the port on the EIP to forward.stringtrue
internalIPInternalIP is the internal VM IP to forward traffic to.stringtrue
internalPortInternalPort is the destination port on the internal VM.stringtrue
protocolProtocol is the transport protocol: tcp or udp.stringfalse
eipRefEIPRef is the name of the ElasticIP wrapper in the same namespace.stringtrue

Back to Group

ElasticIP

ElasticIP is the namespace-scoped wrapper for a Kube-OVN IptablesEIP resource. It represents a public IP address that can be associated with a NAT gateway.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specElasticIPSpecfalse
statusElasticIPStatusfalse

Back to Group

ElasticIPList

ElasticIPList is the list type for ElasticIP.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]ElasticIPtrue

Back to Group

ElasticIPSpec

ElasticIPSpec defines the desired state of an ElasticIP.

FieldDescriptionSchemeRequired
natGatewayRefNATGatewayRef is the name of the NATGateway wrapper this EIP belongs to.stringfalse

Back to Group

ElasticIPStatus

ElasticIPStatus is the observed state of the ElasticIP wrapper.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase.Phasefalse
realNameRealName is the actual Kube-OVN IptablesEIP object name.stringfalse
ipAddressIPAddress is the public IP address allocated to this EIP.stringfalse
isUsedIsUsed indicates whether this EIP is currently in use by a NAT rule.booltrue
associatedNatAssociatedNAT is the real Kube-OVN NAT gateway name this EIP is bound to.stringfalse

Back to Group

NATGateway

NATGateway is the namespace-scoped wrapper for a Kube-OVN VpcNatGateway resource. It bundles SNAT and DNAT rules that are individually provisioned as separate Kube-OVN objects (IptablesSnatRule / IptablesDnatRule).

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specNATGatewaySpecfalse
statusNATGatewayStatusfalse

Back to Group

NATGatewayList

NATGatewayList is the list type for NATGateway.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]NATGatewaytrue

Back to Group

NATGatewaySpec

NATGatewaySpec defines the desired state of a NAT gateway.

FieldDescriptionSchemeRequired
vpcRefVPCRef is the name of the VPC wrapper in the same namespace.stringtrue
subnetRefSubnetRef is the name of the Subnet wrapper in the same namespace.stringtrue
lanIPLanIP is the LAN-side IP address of the NAT gateway.stringfalse
snatRulesSNATRules define source NAT rules for outbound connectivity.[]SNATRulefalse
dnatRulesDNATRules define destination NAT rules for inbound port-forwarding.[]DNATRulefalse

Back to Group

NATGatewayStatus

NATGatewayStatus is the observed state of the NATGateway wrapper.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase.Phasefalse
realNameRealName is the actual Kube-OVN VpcNatGateway object name.stringfalse

Back to Group

SNATRule

SNATRule maps an internal CIDR to an EIP for outbound NAT.

FieldDescriptionSchemeRequired
cidrCIDR is the internal IP range to SNAT.stringtrue
eipRefEIPRef is the name of the ElasticIP wrapper in the same namespace.stringtrue

Back to Group

SecurityGroup

SecurityGroup is the namespace-scoped wrapper for a Kube-OVN SecurityGroup resource. It defines ACL-based firewall rules that can be applied to VMs.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specSecurityGroupSpecfalse
statusSecurityGroupStatusfalse

Back to Group

SecurityGroupList

SecurityGroupList is the list type for SecurityGroup.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]SecurityGrouptrue

Back to Group

SecurityGroupRule

SecurityGroupRule is a single ACL rule within a SecurityGroup.

FieldDescriptionSchemeRequired
ipVersionIPVersion specifies whether the rule applies to IPv4 or IPv6 traffic.stringfalse
protocolProtocol is the network protocol: tcp, udp, icmp, or all.stringfalse
priorityPriority determines the rule evaluation order (lower values = higher priority).intfalse
remoteTypeRemoteType is the type of the remote endpoint: address or securityGroup.stringtrue
remoteAddressRemoteAddress is the IP address or CIDR of the remote endpoint when RemoteType is address.stringfalse
remoteSecurityGroupRemoteSecurityGroup is the name of the remote security group when RemoteType is securityGroup.stringfalse
portRangeMinPortRangeMin is the inclusive minimum port number for this rule.intfalse
portRangeMaxPortRangeMax is the inclusive maximum port number for this rule.intfalse
policyPolicy is the rule action: allow or drop.stringtrue

Back to Group

SecurityGroupSpec

SecurityGroupSpec defines the desired firewall rules.

FieldDescriptionSchemeRequired
allowSameGroupTrafficAllowSameGroupTraffic permits traffic between members of the same security group.boolfalse
ingressRulesIngressRules defines the inbound firewall rules.[]SecurityGroupRulefalse
egressRulesEgressRules defines the outbound firewall rules.[]SecurityGroupRulefalse

Back to Group

SecurityGroupStatus

SecurityGroupStatus is the observed state of the SecurityGroup wrapper.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase.Phasefalse
realNameRealName is the actual Kube-OVN SecurityGroup object name.stringfalse

Back to Group

Subnet

Subnet is the namespace-scoped wrapper for a Kube-OVN Subnet resource. It is always associated with a VPC wrapper in the same namespace.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specSubnetSpecfalse
statusSubnetStatusfalse

Back to Group

SubnetList

SubnetList is the list type for Subnet.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]Subnettrue

Back to Group

SubnetSpec

SubnetSpec defines the desired state of a Subnet wrapper.

FieldDescriptionSchemeRequired
vpcRefVPCRef is the name of the VPC wrapper in the same namespace.stringtrue
cidrBlockCIDRBlock is the IP address range for this subnet.stringtrue
gatewayGateway is the gateway IP address for this subnet.stringfalse
protocolProtocol is the IP protocol family: IPv4, IPv6, or Dual.stringfalse
excludeIPsExcludeIPs is a list of IP ranges to exclude from allocation.[]stringfalse
enableDHCPEnableDHCP enables DHCP on this subnet.boolfalse
gatewayTypeGatewayType controls the gateway mode: distributed or centralized.stringfalse
natOutgoingNatOutgoing enables NAT for traffic leaving this subnet.boolfalse
privatePrivate denies traffic from outside this subnet when true.boolfalse
providerProvider is the kube-ovn provider name for this subnet, used to associate it with a NetworkAttachmentDefinition (NAD) via kube-ovn’s provider matching. Required for multi-homed pods (e.g. AZ transit NICs).stringfalse

Back to Group

SubnetStatus

SubnetStatus is the observed state of the Subnet wrapper.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase of this Subnet.Phasefalse
realNameRealName is the actual Kube-OVN Subnet object name.stringfalse
vpcRealNameVPCRealName is the real Kube-OVN Vpc name this subnet belongs to.stringfalse
availableIPsAvailableIPs is the number of IP addresses currently available in this subnet.int64true
usedIPsUsedIPs is the number of IP addresses currently in use.int64true

Back to Group

UnderlayCustomInterface

UnderlayCustomInterface overrides DefaultInterface on a specific set of nodes.

FieldDescriptionSchemeRequired
interfaceInterface is the physical NIC name to use on the listed nodes. It must be a valid Linux network interface name, which the kernel caps at 15 bytes.stringtrue
nodesNodes is the list of node names that use Interface instead of the spec-level DefaultInterface.[]stringtrue

Back to Group

UnderlaySubnet

UnderlaySubnet is the namespace-scoped wrapper that bundles the three Kube-OVN objects required to expose an underlay (L2) network: a cluster- scoped ProviderNetwork (which physical NIC per node), a Vlan (the 802.1Q tag), and a Subnet bound to that Vlan. The reconciler ensures the children are created and torn down in dependency order.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specUnderlaySubnetSpecfalse
statusUnderlaySubnetStatusfalse

Back to Group

UnderlaySubnetList

UnderlaySubnetList is the list type for UnderlaySubnet.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]UnderlaySubnettrue

Back to Group

UnderlaySubnetSpec

UnderlaySubnetSpec defines the desired state of an UnderlaySubnet wrapper.

FieldDescriptionSchemeRequired
defaultInterfaceDefaultInterface is the physical NIC name (e.g. "eth1") that the ProviderNetwork attaches to on every selected node. It must be a valid Linux network interface name, which the kernel caps at 15 bytes.stringtrue
nodeSelectorNodeSelector restricts the ProviderNetwork to a subset of nodes via label selection. When empty, the ProviderNetwork applies to all nodes.*metav1.LabelSelectorfalse
customInterfacesCustomInterfaces overrides DefaultInterface on specific nodes.[]UnderlayCustomInterfacefalse
vlanIDVlanID is the 802.1Q tag applied to traffic on this underlay.inttrue
cidrBlockCIDRBlock is the IP address range allocated from this underlay subnet.stringtrue
gatewayGateway is the gateway IP address for this subnet.stringfalse
gatewayNodeGatewayNode is the comma-separated list of node names that host the centralized gateway for this subnet.stringfalse
protocolProtocol is the IP protocol family: IPv4, IPv6, or Dual.stringfalse
excludeIPsExcludeIPs is a list of IP addresses or ranges to exclude from allocation.[]stringfalse
namespacesNamespaces binds this subnet as the DEFAULT (primary) subnet for the listed namespaces — pods there with no explicit network selection get their primary IP from it. Leave empty for a secondary/underlay network attached only via its NAD + ip_pool annotation: binding a namespace already owned by another VPC’s subnet makes kube-ovn reject the subnet (“namespaces … overlap with vpc …”) and never create its logical switch.string arrayfalse

Back to Group

UnderlaySubnetStatus

UnderlaySubnetStatus is the observed state of the UnderlaySubnet wrapper.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase of this UnderlaySubnet.Phasefalse
providerNetworkNameProviderNetworkName is the name of the cluster-scoped Kube-OVN ProviderNetwork backing this underlay.stringfalse
vlanNameVlanName is the name of the cluster-scoped Kube-OVN Vlan backing this underlay.stringfalse
subnetNameSubnetName is the name of the cluster-scoped Kube-OVN Subnet backing this underlay.stringfalse
availableIPsAvailableIPs is the number of IP addresses currently available in this subnet.int64true
usedIPsUsedIPs is the number of IP addresses currently in use.int64true

Back to Group

VMBackup

VMBackup is the namespace-scoped wrapper that captures a point-in-time backup of a VirtualMachine and uploads its disk images to a BackupStorageLocation. The reconciler drives a VirtualMachineSnapshot, a VirtualMachineExport, and an upload Job, then records where each disk landed in the bucket.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specVMBackupSpecfalse
statusVMBackupStatusfalse

Back to Group

VMBackupList

VMBackupList is the list type for VMBackup.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
itemsVMBackup arraytrue

Back to Group

VMBackupSpec

VMBackupSpec defines the desired backup of a VirtualMachine.

FieldDescriptionSchemeRequired
vmNameVMName is the name of the VirtualMachine to back up, in the same namespace.stringtrue
storageLocationStorageLocation is the name of the BackupStorageLocation in the same namespace that this backup is written to.stringtrue

Back to Group

VMBackupStatus

VMBackupStatus is the observed state of a VMBackup.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase of this backup.Phasefalse
startTimeStartTime is when the backup began.metav1.Timefalse
completionTimeCompletionTime is when the backup finished successfully.metav1.Timefalse
snapshotNameSnapshotName is the name of the VirtualMachineSnapshot created for this backup.stringfalse
exportNameExportName is the name of the VirtualMachineExport created for this backup.stringfalse
objectsObjects lists the disk images that were uploaded to the storage location.BackupObject arrayfalse
vmManifestKeyVMManifestKey is the object key of the VM manifest snapshot retained in object storage as an out-of-band disaster-recovery artifact. Restore rebuilds the VM from the in-cluster manifest ConfigMap, not from this object.stringfalse
messageMessage is a human-readable explanation of the current phase, typically the reason the backup failed.stringfalse

Back to Group

VMRestore

VMRestore is the namespace-scoped wrapper that restores a VMBackup into a new VirtualMachine. The reconciler imports each backed-up disk image from the storage location into a CDI DataVolume (via source.s3) and recreates the VirtualMachine from the stored manifest under a new name. The original VM is never modified.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specVMRestoreSpecfalse
statusVMRestoreStatusfalse

Back to Group

VMRestoreList

VMRestoreList is the list type for VMRestore.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
itemsVMRestore arraytrue

Back to Group

VMRestoreSpec

VMRestoreSpec defines the desired restore of a VMBackup.

FieldDescriptionSchemeRequired
backupNameBackupName is the name of the VMBackup in the same namespace to restore from.stringtrue
targetVMNameTargetVMName is the name of the new VirtualMachine to create. It must differ from any existing VirtualMachine in the namespace.stringtrue
storageClassNameStorageClassName is the storage class for the restored DataVolumes. When empty, the cluster default storage class is used.stringfalse

Back to Group

VMRestoreStatus

VMRestoreStatus is the observed state of a VMRestore.

FieldDescriptionSchemeRequired
phasePhase is the current lifecycle phase of this restore.Phasefalse
startTimeStartTime is when the restore began.metav1.Timefalse
completionTimeCompletionTime is when the restore finished successfully.metav1.Timefalse
dataVolumesDataVolumes lists the names of the CDI DataVolumes created for this restore.string arrayfalse
restoredVMNameRestoredVMName is the name of the VirtualMachine that was created.stringfalse
vmManifestVMManifest is set for a restore synced from a KDP workspace only: the restored VirtualMachine as JSON, to be created in that workspace. A VM created on the host would never reach the workspace, so the restore waits for this one to be synced down instead. It is cleared once the VM exists.stringfalse
vmManifestPublishedTimeVMManifestPublishedTime is when VMManifest was published. The restore fails if its VirtualMachine is not created within a day of it.metav1.Timefalse
messageMessage is a human-readable explanation of the current phase, typically the reason the restore failed.stringfalse

Back to Group

VPC

VPC is the namespace-scoped wrapper for a Kube-OVN Vpc resource. Users create VPCs inside workspace namespaces; the operator reconciles them into cluster-scoped Kube-OVN Vpc objects, prefixing their names with the workspace namespace to prevent cross-tenant collisions.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMetafalse
specVPCSpecfalse
statusVPCStatusfalse

Back to Group

VPCBFDPort

VPCBFDPort holds optional BFD logical router port configuration.

FieldDescriptionSchemeRequired
enabledEnabled activates the BFD port.booltrue
ipIP is the IP address assigned to the BFD port.stringfalse
nodeSelectorNodeSelector restricts which nodes the BFD LRP is hosted on. If not set, Kube-OVN selects up to 3 nodes automatically.*metav1.LabelSelectorfalse

Back to Group

VPCBFDPortStatus

VPCBFDPortStatus is the observed state of the BFD logical router port.

FieldDescriptionSchemeRequired
namestringfalse
ipstringfalse
nodes[]stringfalse

Back to Group

VPCList

VPCList is the list type for VPC.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]VPCtrue

Back to Group

VPCPeering

VPCPeering configures a peering connection between two VPCs. The RemoteVPCRef references the name of another VPC wrapper in the same namespace.

FieldDescriptionSchemeRequired
remoteVpcRefRemoteVPCRef is the name of the remote VPC wrapper in the same namespace.stringtrue
localConnectIPLocalConnectIP is the local IP used to establish the peering connection.stringfalse

Back to Group

VPCPolicyRoute

VPCPolicyRoute is a policy-based routing rule for the VPC router.

FieldDescriptionSchemeRequired
priorityPriority determines evaluation order; lower numbers are evaluated first.intfalse
matchMatch is the OVN match expression that selects traffic for this rule.stringtrue
actionAction is the rule action: allow, drop, or reroute.stringtrue
nextHopIPNextHopIP is required when Action is reroute.stringfalse

Back to Group

VPCSpec

VPCSpec defines the desired state of a VPC wrapper.

FieldDescriptionSchemeRequired
defaultSubnetDefaultSubnet is the name of the default subnet wrapper in this namespace.stringfalse
staticRoutesStaticRoutes configures static routes for the VPC router.[]VPCStaticRoutefalse
policyRoutesPolicyRoutes configures policy-based routing rules for the VPC router.[]VPCPolicyRoutefalse
vpcPeeringsVPCPeerings configures peering connections to other VPCs in the same namespace.[]VPCPeeringfalse
enableExternalEnableExternal controls whether the VPC has access to the external network.boolfalse
enableBfdEnableBfd enables Bidirectional Forwarding Detection on the VPC router.boolfalse
bfdPortBFDPort holds configuration for the BFD logical router port. Only effective when EnableBfd is true.*VPCBFDPortfalse

Back to Group

VPCStaticRoute

VPCStaticRoute is a single static route entry for the VPC router.

FieldDescriptionSchemeRequired
cidrCIDR is the destination IP prefix for this route.stringtrue
nextHopIPNextHopIP is the IP address of the next-hop router.stringtrue
policyPolicy is the routing policy direction: dst or src.stringfalse
bfdIDBFDID is the UUID of the BFD session to associate with this route. When set, the underlying KubeOVN VPC will use BFD-monitored ECMP for this route.stringfalse
ecmpModeECMPMode sets the ECMP mode for this route (e.g. "ecmp" or "ecmp-symmetric").stringfalse

Back to Group

VPCStatus

VPCStatus mirrors the Kube-OVN VpcStatus, surfacing the full operational state of the underlying cluster-scoped Vpc object.

FieldDescriptionSchemeRequired
phasePhase is the lifecycle phase of this VPC wrapper.Phasefalse
realNameRealName is the cluster-scoped Kube-OVN Vpc object name (namespace-prefixed). Used internally by dependent controllers.stringfalse
standbybooltrue
defaultbooltrue
defaultLogicalSwitchstringtrue
routerstringtrue
tcpLoadBalancerstringtrue
udpLoadBalancerstringtrue
sctpLoadBalancerstringtrue
tcpSessionLoadBalancerstringtrue
udpSessionLoadBalancerstringtrue
sctpSessionLoadBalancerstringtrue
subnetsSubnets lists the user-facing names of subnets belonging to this VPC (namespace prefix stripped).[]stringtrue
vpcPeeringsVPCPeerings lists the real names of peered Kube-OVN Vpcs.[]stringtrue
enableExternalbooltrue
extraExternalSubnetsExtraExternalSubnets lists additional external subnets attached to this VPC.[]stringtrue
enableBfdbooltrue
bfdPortVPCBFDPortStatustrue

Back to Group

AZEdgeRouter

AZEdgeRouter is the Schema for regional/AZ-mode edge routers that serve multiple VPCs via per-VPC transit subnets and VRF-based routing.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMeta
specAZEdgeRouterSpec
statusAZEdgeRouterStatus

Back to Group

AZEdgeRouterSpec

AZEdgeRouterSpec defines the desired state of an AZ-mode EdgeRouter.

FieldDescriptionSchemeRequired
replicaCountReplicaCount is the number of FRR pod replicas.integer
imageImage specifies the container images used by the EdgeRouter.EdgeRouterImage
managementSubnetManagementSubnet is the name of the OVN Subnet in the management VPC that the FRR pods are attached to. The operator uses this to derive the management VPC name and gateway.string
vlanVLAN is a reference to the pre-existing NetworkAttachmentDefinition for the router’s inbound VLAN interface (net1). The router pods attach to it as a Multus secondary interface, giving them L2 reachability to the physical network. It carries EVPN peering and the plain BGP sessions in bgpPeers. In bgp-per-vrf mode, tenant traffic uses the per-VPC VLANs in perVRFTransit instead, and this field is only needed for a router-wide service VLAN.NADRef
vlanGatewayVLANGateway is the default gateway IP on the VLAN NAD subnet. The operator sets the Multus routes annotation to route 0.0.0.0/0 via this address, making the VLAN interface the pod’s default route (same mechanism as the per-VPC EdgeRouter’s external NAD). Only meaningful when VLAN is set.string
serviceVlanServiceVLAN is a reference to a separate pre-existing NetworkAttachmentDefinition for the service-advertisement (anycast) VLAN, distinct from vlan. When it differs from vlan, the router attaches it as a second inbound VLAN interface (net2) and pins the bgpPeers session to it, so region transit and service advertisement use different VLANs. When empty or equal to vlan, both share net1. Requires vlan and bgpPeers.NADRef
serviceVlanGatewayServiceVLANGateway is the gateway IP on the ServiceVLAN subnet used to reach off-subnet anycast BGP peers (BGPPeers). When set, the operator installs a /32 static route to each anycast peer via this gateway over the service VLAN NIC. Leave empty when the anycast peers are directly connected on the ServiceVLAN subnet (the common case), in which case the connected route suffices. This is NOT a default route — the pod default route stays on the region-transit VLAN. Only meaningful when ServiceVLAN differs from VLAN.string
apiServerViaInternalProxyAPIServerViaInternalProxy makes the router pods reach the Kubernetes API server through an in-VPC API server proxy instead of a node IP. Set it when the router pods live in a management VPC that has no L2 path to the node or API server address, which is the usual case for AZ routers. The proxy must be deployed separately.boolean
dynamicTransitNICsDynamicTransitNICs attaches the per-VPC transit NICs to the running router pods by Multus hot-plug instead of adding them to the StatefulSet pod template. Adding or removing a VPC then does not restart the router pods, so BGP and BFD sessions of VPCs that are already attached stay up. Requires thick-mode Multus with the multus-dynamic-networks-controller. Defaults to false, which attaches the NICs through the pod template.boolean
configWatcherConfigWatcher configures the configuration watcher sidecar. It is enabled by default. Do not disable it: without it the router never re-renders its FRR configuration as VPCs resolve and never applies its nftables rules, and sessions stay stuck in Connect.ConfigWatcherSpec
bfdBFD configures Bidirectional Forwarding Detection. When BFD.Internal.Enabled is set, the operator enables a BFD logical-router port on each tenant VPC and creates BFD sessions to every replica’s transit IP, so OVN-monitored ECMP reroute policies automatically prune a dead replica’s transit IP. The FRR pods run bfdd and answer the OVN gateway’s BFD probes per VPC VRF.BFDSpec
netshootNetshoot configures the netshoot debug sidecar.NetshootSpec
resourcesResources defines the resource requirements for each container.EdgeRouterResources
nodeSelectorNodeSelector constrains the FRR pods to nodes matching these labels.object (keys:string, values:string)
allowColocatedReplicasAllowColocatedReplicas lets more than one replica run on the same node. By default the router pods require anti-affinity on kubernetes.io/hostname, so the replica count cannot exceed the number of nodes matching nodeSelector. Setting this relaxes the rule to a preference, which is only useful for test setups with few nodes, because replicas on one node fail together. When replicas share a node, the ReplicaRedundancy condition turns False and draining that node is blocked by the PodDisruptionBudget.boolean
zoneZone names the availability zone this router serves, for example region-a. Set it when several AZEdgeRouters share the same tenant VPCs, one per zone. The per-VPC annotations are then keyed by it: az-edge-router.virtualization.k8c.io/<zone>.nad-name, .local-ips, .peer-ip and .accept-prefixes. Use the same value as the topology.kubernetes.io/region node label and the subnets’ topology.kubernetes.io/zone label. Leave it empty for a single-zone installation, which uses the unsuffixed annotations. A router without a zone skips VPCs that carry zone-scoped annotations.string
imagePullSecretsImagePullSecrets is a list of references to secrets for pulling images.LocalObjectReference array
transitSubnetTransitSubnet configures the per-VPC /30 transit address pool.AZTransitSubnetSpec
vpcsVPCs configures how VPCs are discovered and attached.AZVPCsSpec
peerAZEdgeRoutersPeerAZEdgeRouters lists other AZEdgeRouter CRs (same namespace) whose resolved VPCs should also get transit NICs on this router’s FRR pods.string array
vpcEdgeRoutersVPCEdgeRouters lists per-VPC EdgeRouter objects that this AZ router should peer with. Not used yet.AZVPCEdgeRouterRef array
asnASN is the BGP autonomous system number. Required when EVPNPeers, BGPPeers or InternalPeers are configured. EVPNPeers and BGPPeers may be used together: EVPNPeers carries EVPN Type 5 cross-zone routing while BGPPeers carries plain IPv4 unicast advertisement (aggregated anycast and/or OVN subnets) to an external router.integer
evpnPeersEVPNPeers lists the BGP peers for EVPN Type 5 route exchange. These are typically other AZEdgeRouter instances in remote regions/AZs.AZEVPNPeer array
evpnUnderlayPrefixesEVPNUnderlayPrefixes is the list of CIDR blocks covering the VTEP underlay addresses of all AZ edge routers. When non-empty, static routes for these prefixes are installed via the VLAN gateway so that EVPN VTEP resolution works without relying on the default route.string array
bgpPeersBGPPeers lists the external upstream BGP peers reached over the VLAN (net1) for plain IPv4 unicast advertisement. They carry the anycast blocks learned from internalPeers, re-advertised with next-hop-self, and the OVN subnets when ovnTransitMode is bgp-per-vrf. May be used together with evpnPeers.AZBGPPeer array
ovnTransitModeOVNTransitMode selects how OVN tenant subnets are advertised to the external router, preserving per-tenant VRF isolation: - “evpn” (default): EVPN Type 5 via EVPNPeers (VXLAN dataplane). - “bgp-per-vrf”: one plain-BGP session per VPC, sourced from that VPC’s VRF over a per-tenant VLAN subinterface, landing the subnet in a matching VRF on the external router.string
internalPeersInternalPeers enables per-VPC BGP peering with in-VPC speakers (e.g. FRR or MetalLB) that advertise static anycast blocks. Learned prefixes are re-advertised with next-hop-self (3-party aggregation), so the external router only ever routes to this AZ router’s VLAN IP. Requires an external advertisement plane to re-advertise into: either BGPPeers (the default-VRF anycast plane) or OVNTransitMode “bgp-per-vrf” (where each VPC’s own fabric session carries the anycast, since there is no default-VRF session to aggregate through). With neither, this is inert.AZInternalPeersSpec
perVRFTransitPerVRFTransit configures the per-tenant underlay VLAN attachments used when OVNTransitMode is “bgp-per-vrf”. kube-ovn presents the pod an access-style interface (no VLAN trunking), so each VPC VRF gets its OWN underlay VLAN NAD + subnet — a dedicated Multus interface bound to that VRF — over which a per-VRF BGP session peers the external router in a matching VRF.AZPerVRFTransitSpec

Back to Group

AZEdgeRouterStatus

AZEdgeRouterStatus defines the observed state of AZEdgeRouter.

FieldDescriptionSchemeRequired
observedGenerationObservedGeneration is the metadata.generation this status was computed from. It is set on every completed reconcile, which is what makes the operator write status even when NOTHING else in it changed — in particular when zero VPCs are attached, where every other field stays at its zero value and the status update would otherwise be skipped as a no-op. It is the signal the FRR init container waits on: “the operator has processed this spec”, which is distinguishable from “the operator has not run yet”. Waiting for a non-empty ResolvedAZVPCs instead cannot tell those apart, so a router with no VPC attached never started.integer
apiServerProxyVIPAPIServerProxyVIP is the in-VPC apiserver proxy address the operator resolved from its own –internal-apiserver-url, published here because the SIDECAR needs it to program the per-VPC route and masquerade for APIServerProxy VPCs, and reads only this CR. Empty unless spec.apiServerViaInternalProxy is set.string
readyReplicasReadyReplicas is the number of ready FRR pod replicas.integer
vpcCountVPCCount is the number of VPCs currently attached.integer
peerCountPeerCount is the number of peer AZEdgeRouters resolved.integer
conditionsConditions is the list of status conditions.Condition array
resolvedAZVPCsResolvedAZVPCs is the list of VPCs attached with their allocated transit IPs and routing table IDs.ResolvedAZVPC array
peerResolvedAZVPCsPeerResolvedAZVPCs contains VPCs resolved by peer AZEdgeRouters.PeerResolvedAZVPCs array
learnedBGPRoutesLearnedBGPRoutes tracks the (prefix, nexthop) anycast routes learned from internal speakers and programmed as VPC static ECMP routes on the tenant VPCs. Recorded for ownership so stale routes are pruned when a speaker withdraws.LearnedBGPRoute array
bgpSessionsBGPSessions lists the live BGP neighbours of every replica, published by the frr-config-watcher sidecars. Sorted by replica, VRF, neighbour and address family so an unchanged set never rewrites the status.BGPSessionStatus array
resolvedEVPNPeersResolvedEVPNPeers is populated by the EVPNRouteReflector controller with the RR replica IPs (as EVPN-only neighbors). The frr-config-watcher sidecar merges these with spec.EVPNPeers so the AZ router peers an in-cluster, operator-managed route reflector without any static peer configuration. Mirrors EdgeRouter.EVPNPeer array

Back to Group

AZVPCsSpec

AZVPCsSpec configures how VPCs are discovered and attached in AZ mode.

FieldDescriptionSchemeRequired
autoDiscoveryAutoDiscovery enables automatic discovery of kube-ovn VPC objects via LabelSelector. When false, VPCs must be listed explicitly in List.boolean
labelSelectorLabelSelector selects kube-ovn VPC objects to attach to this AZEdgeRouter. Only used when AutoDiscovery is true.LabelSelector
namespacesNamespaces bounds which namespaces auto-discovery looks in for wrapper VPCs, which are namespaced. Empty means only the router’s own namespace. * means every namespace, so one platform router can carry the VPCs of every tenant. A VPC is attached only if its namespace is allowed and it carries the labels in labelSelector; an empty labelSelector matches every VPC, so set one to discover VPCs in other namespaces. Entries in list name their namespace themselves and are not bounded by this field, but a listed VPC of another namespace is attached only if its owner labelled it virtualization.k8c.io/edge-router-attach=true. The per-VPC routing annotations and labels (NAD, peers, ASNs, accepted prefixes, API server proxy, egress source, EVPN VNI) are not read from a VPC of another namespace, so set them in this spec; only the egress-enabled annotation is honoured. On this router, a VPC of another namespace is identified as <name>--<digest of the namespace>, while a VPC of the router’s own namespace keeps its plain name. Ignored for native kube-ovn VPCs, which are cluster-scoped.string array
subnetLabelSelectorSubnetLabelSelector filters which wrapper Subnet objects within each discovered/listed VPC are advertised by this AZEdgeRouter instance. This allows multiple AZEdgeRouters (one per region/zone) to share the same VPCs while each only handling the subnets pinned to its own zone. When empty, all subnets belonging to the VPC are included.LabelSelector
listList is the explicit set of VPCs to attach when autoDiscovery is false. Use namespace on an entry for a VPC outside the router’s namespace.AZVPCRef array

Back to Group

AZVPCRef

AZVPCRef identifies a kube-ovn VPC to attach to the AZEdgeRouter.

FieldDescriptionSchemeRequired
nameName is the name of the kube-ovn VPC object.string
namespaceNamespace is the namespace of the VPC, for wrapper VPCs outside the router’s own namespace. Empty means the router’s own namespace. Ignored for native kube-ovn VPCs, which are cluster-scoped.string
egressToSourceEgressToSource is an optional fixed source IP for SNAT of traffic from this VPC, instead of masquerade. The same address is used on every replica, so with replicaCount greater than 1 a reply may arrive at a replica that does not own it. Prefer egressToSourceBySubnet, which takes one IP per replica, when you run more than one replica.string
egressToSourceBySubnetEgressToSourceBySubnet overrides egressToSource for specific subnets of this VPC, keyed by IPv4 CIDR in canonical form (for example 10.0.0.0/24, not 10.0.0.5/24). Subnets not listed fall back to egressToSource, or to plain masquerade if that is unset. Use it when a subnet must present a distinct, stable external source IP. Each value lists one IP per replica, because return traffic may reach a different replica than the one that sent the request. A list shorter than spec.replicaCount is rejected and the override does not apply. Every IP used here must also be added to spec.excludeIps of the Subnet it is drawn from, otherwise that Subnet may assign it to another NIC. The operator does not do this for you.object (keys:string, values:string array)

Back to Group

AZVPCVLANRef

AZVPCVLANRef maps one VPC to its pre-provisioned external underlay VLAN. The VLAN is referenced either as an UnderlaySubnet (the operator/platform provisions the ProviderNetwork+Vlan+Subnet+NAD) or, for a VLAN whose NAD already exists (e.g. a shared fabric NAD created directly), by NAD name. The two sources are mutually exclusive, and both are optional: naming neither is a policy-only override (for example advertiseOVNSubnets for a VPC whose VLAN comes from its az-edge-router.virtualization.k8c.io annotations). Naming both is rejected.

FieldDescriptionSchemeRequired
vpcVPC is the kube-ovn VPC name; must match a VPC this router resolves. A VPC of another namespace is written <namespace>/<name>; a bare name means the router’s own namespace.string
underlaySubnetUnderlaySubnet is the name of the pre-provisioned UnderlaySubnet (bundling the ProviderNetwork, the 802.1Q Vlan and the IP Subnet) that carries this VPC’s external VLAN. The operator attaches its auto-created NAD and enslaves the interface to the VPC’s VRF. Mutually exclusive with NADName.string
nadNameNADName references a PRE-EXISTING NetworkAttachmentDefinition (in the router’s namespace) backing this VPC’s external VLAN, as an alternative to UnderlaySubnet. Use this to attach to a NAD provisioned outside the AZ operator — e.g. a shared fabric NAD also used by a per-VPC EdgeRouter. The provider is derived as “..ovn”, matching kube-ovn’s NAD provider convention in both backends. Mutually exclusive with UnderlaySubnet.string
vlanIDVLANID is the 802.1Q VLAN tag that the NAD named in nadName carries traffic on. Set it when you reference a raw NAD, so that VPCs sharing the same physical VLAN can be told apart from VPCs that happen to use the same ID for unrelated networks. It is ignored when underlaySubnet is used, because the tag is then read from the UnderlaySubnet. Zero means unknown.integer
localIPsLocalIPs are the AZ router’s per-replica IPs on this VLAN — one per replica, within the UnderlaySubnet’s CIDR. The operator builds the external-VLAN NAD’s ip_pool annotation from this list so each StatefulSet replica gets its own stable IP; the external router peers each as a BGP neighbor (ECMP).string array
localASNLocalASN overrides AZEdgeRouterSpec.ASN as the LOCAL autonomous system number for this VPC’s own per-VRF BGP instance (“router bgp vrf ”). Zero (the default) inherits the router-wide ASN, same sentinel convention AZEdgeRouterSpec.ASN itself uses. Set this when VPCs sharing one advertisement VLAN need to present distinct AS numbers to the fabric — e.g. so the external router can apply AS-path-based policy per VPC instead of relying solely on neighbor IP or prefix content. Does not affect the default (non-per-VRF) BGP instance or the REMOTE peer ASN (see AZVPCFabricPeer.ASN for that). NOT SUPPORTED together with EVPN on the same VPC (a non-zero ResolvedAZVPC.VNI, from the backend or an EVPNPolicy): the EVPN RD/RT are always derived from the router-wide ASN, independent of this override, so combining the two would silently put the VRF’s BGP session under one ASN and its RD/RT under another. The operator rejects the combination (ExternalVLANError) rather than guessing which one should win.integer
peerIPPeerIP is the external router’s IP on this VLAN, the BGP neighbor that every replica peers with. Superseded by peers, which can carry more than one neighbor. It is still honoured: it is treated as a single peer that is sent everything and carries the VRF default route. Setting both is rejected unless peerIP repeats one of the peers. The value must be a plain IP address.string
peersPeers are the external BGP neighbors on this VPC’s VLAN, replacing PeerIP. More than one because the fabric may put the tenant’s SERVICE plane and its WORKLOAD plane on different routers: one neighbor takes the VPC’s OVN subnets, another takes only the anycast blocks learned from in-VPC speakers. Both sit on this VPC’s single underlay VLAN and are told apart by what each is sent, not by which wire they are on — per-tenant L2 separation would need a second NAD per VPC and is deliberately not this field.AZVPCFabricPeer array
advertiseOVNSubnetsAdvertiseOVNSubnets overrides AZPerVRFTransitSpec.AdvertiseOVNSubnets for THIS VPC only, so one tenant can run SNAT-only egress (its fabric VRF never learns tenant space) while the tenants beside it stay directly routed — or the inverse, carving one directly-routed tenant out of an otherwise SNAT-only router. Absent inherits the router-wide setting; the session itself, the VPC’s static routes and its BFD /32 are unaffected either way.boolean
acceptPrefixesAcceptPrefixes overrides AZPerVRFTransitSpec.AcceptPrefixes for THIS VPC only — what its own external fabric peer(s) may inject into its VRF via BGP. Absent inherits the router-wide list (empty there means deny everything). See AZPerVRFTransitSpec.AcceptPrefixes for why this exists.AZAcceptPrefix array

Back to Group

AZVPCFabricPeer

AZVPCFabricPeer is one external BGP neighbor on a VPC’s underlay VLAN, in the "bgp-per-vrf" OVN transit mode.

Every field except IP is an override of something inherited, so the zero value is "behave like the single peerIP always did". The two Advertise* flags map onto the two clauses of the per-VRF egress filter the router already builds — OVN subnets, and the anycast blocks learned from in-VPC speakers — which is what lets one VLAN carry a workload peer and a service peer at once.

FieldDescriptionSchemeRequired
ipIP is the neighbor’s address on this VPC’s underlay VLAN. Pattern-validated at admission for the same reason as AcceptPrefixes: this value renders verbatim into the FRR template (“neighbor {{ .IP }} …”, “ip route 0.0.0.0/0 {{ .IP }} …”), so an embedded newline would inject extra config lines. EffectivePeers additionally rejects it at runtime for callers (e.g. the VPC annotation path) that build an AZVPCFabricPeer outside admission.string
asnASN is the neighbor’s autonomous system number. Zero inherits AZPerVRFTransitSpec.PeerASN, which is the common case; set it to face a transit AS and a service AS from the same VPC. Mirrors ExternalNeighbor.ASN on the per-VPC EdgeRouter.integer
advertiseOVNSubnetsAdvertiseOVNSubnets sends this VPC’s OVN tenant subnets to this neighbor. Absent inherits the per-VPC AdvertiseOVNSubnets, then the router-wide one, then true. This is an EXPORT policy and nothing else: it does not decide whether the neighbor carries the VRF’s default route (see DefaultRoute) and does not touch the VPC’s static routes or its BFD session. A peer with this false is SNAT-only egress, not an unrouted one.boolean
advertiseAnycastAdvertiseAnycast sends the anycast blocks learned from this VPC’s in-VPC speakers (internalPeers) to this neighbor, which makes it a service peer. When unset, anycast is advertised on the router’s default-VRF bgpPeers if any exist, and not to per-VRF sessions. If another peer of the same VPC sets it to true, anycast is withdrawn from all peers that did not ask for it. Setting false opts a peer out. Ignored for a VPC with no internal speakers.boolean
defaultRouteDefaultRoute makes this neighbor a VRF default gateway (“ip route 0.0.0.0/0 ” inside the VPC’s VRF). Absent means CANDIDATE — EXCEPT for a peer with MultihopTTL > 1, which is never an implicit candidate: nothing installs a /32 to a multihop peer, so its default route could never resolve its own nexthop and would sit installed-but-inactive, leaving the VPC with silent no-egress. Set this true explicitly on a multihop peer only when it is reachable some other way (e.g. an IGP-learned route). Every OTHER candidate gets a route, so two fabric devices on this VLAN are ECMP rather than one being silently preferred; one peer stays one route, which is today’s behaviour. Marking any peer true narrows the set to the marked ones — the way to keep a transit peer out of it, along with setting false here. Deliberately NOT derived from the Advertise* flags: a SNAT-only transit peer advertises nothing and is still the egress gateway, which makes it flag-identical to a service peer. The role has to be stated, and on the annotation surface the key name states it.boolean
multihopTTLMultihopTTL is the eBGP multihop TTL, for a neighbor that is not on this VLAN’s subnet. Zero or 1 is single-hop.integer
bfdBFD enables BFD on this session. Absent inherits spec.bfd.external.enabled, which today turns every external neighbor on or off together; set it to face one fabric device that requires BFD beside one that does not.boolean

Back to Group

EffectiveFabricPeer

EffectiveFabricPeer is one fabric peer with every inherited default already applied, so nothing downstream repeats the precedence rules or handles a nil.

FieldDescriptionSchemeRequired
IPstring
ASNinteger
AdvertiseOVNSubnetsboolean
AdvertiseAnycastboolean
DefaultRouteboolean
MultihopTTLinteger
BFDboolean

Back to Group

FabricPeerDefaults

FabricPeerDefaults carries the facts a peer inherits from outside itself. Passed in rather than read from the CR so that peers arriving from a VPC’s annotations resolve through exactly the same code as peers written in the spec — and so the planned VPC wrapper API becomes a third caller rather than a second implementation.

FieldDescriptionSchemeRequired
PeerASNPeerASN is AZPerVRFTransitSpec.PeerASN.integer
AdvertiseOVNSubnetsAdvertiseOVNSubnets is the already-resolved per-VPC default, i.e. what AZPerVRFTransitSpec.AdvertiseOVNSubnetsForVPC reports for this VPC.boolean
AdvertiseAnycastAdvertiseAnycast is “the router has no default-VRF BGP plane” — see AZVPCFabricPeer.AdvertiseAnycast.boolean
BFDBFD is spec.bfd.external.enabled.boolean

Back to Group

ConfigWatcherSpec

ConfigWatcherSpec configures the configuration watcher sidecar.

FieldDescriptionSchemeRequired
enabledEnabled indicates whether the config watcher sidecar is enabled.boolean
intervalInterval is the polling interval in seconds for the config watcher.integer

Back to Group

AZVPCEdgeRouterRef

AZVPCEdgeRouterRef identifies a per-VPC EdgeRouter CR to peer with.

FieldDescriptionSchemeRequired
nameName is the name of the per-VPC EdgeRouter CR.string
namespaceNamespace is the namespace. Defaults to the AZEdgeRouter’s namespace.string

Back to Group

AZAcceptPrefix

AZAcceptPrefix is one entry in a bgp-per-vrf fabric accept-list: what an external fabric peer may inject into a VPC’s VRF via BGP. Distinct from the internal-speaker accept-list (internalPeers.acceptPrefixes), which bounds a different direction and peer. For debugging, the fabric accept-list is rendered as the prefix-list PL-EXT-IN-<vrf> in the router’s FRR configuration.

FieldDescriptionSchemeRequired
cidrCIDR is the IPv4 network to accept from the fabric peer.string
allowedPrefixLengthAllowedPrefixLength, when set, also accepts any more-specific prefix of cidr up to a /N mask, instead of only the exact CIDR. 0 (the default) accepts only the exact CIDR. Must be between the CIDR’s own mask length and 32; an entry outside that range is dropped.integer

Back to Group

AZBGPPeer

AZBGPPeer defines an upstream BGP peer for plain IPv4 unicast route advertisement. Used by BGPPeers, alone or together with EVPNPeers — enables the AZEdgeRouter to advertise per-VPC subnets to an external router without EVPN/VXLAN encapsulation.

FieldDescriptionSchemeRequired
ipIP is the peer’s IP address.string
asnASN is the peer’s autonomous system number.integer
multihopTTLMultihopTTL is the eBGP multihop TTL. 0 or 1 means single-hop.integer

Back to Group

AZEVPNPeer

AZEVPNPeer defines a BGP peer for EVPN Type 5 route exchange between AZEdgeRouters.

FieldDescriptionSchemeRequired
ipIP is the peer’s IP address.string
asnASN is the peer’s autonomous system number.integer
multihopTTLMultihopTTL is the eBGP multihop TTL. 0 or 1 means single-hop.integer

Back to Group

AZExternalVLAN

AZExternalVLAN holds the resolved per-VRF underlay VLAN attachment for one VPC in "bgp-per-vrf" mode. The pod attaches an access-style interface (VLAN tagging is on the upstream provider network), so no 802.1q VLAN ID is tracked here; that is only needed once trunk-port attachment (ovs-cni) is introduced.

FieldDescriptionSchemeRequired
nadNameNADName is the operator-created Multus NAD for this VPC’s external VLAN.string
vlanIDVLANID is the resolved 802.1Q VLAN tag this attachment rides — AZVPCVLANRef.VLANID for a raw NADName reference, or UnderlaySubnet.Spec.VlanID (authoritative) for an UnderlaySubnet reference. Zero means unknown; see AZVPCVLANRef.VLANID for why that falls back to grouping by NADName rather than being treated as a real VLAN.integer
interfaceNameInterfaceName is the Multus-assigned NIC name inside the pod (e.g. “net4”).string
localIPsLocalIPs holds the AZ router’s per-replica IPs (bare, no prefix) on the underlay VLAN — one entry per replica, e.g. [“172.30.0.2”, “172.30.0.3”]. The external VLAN NAD’s ip_pool annotation is built from this list so each StatefulSet replica gets its own stable IP, and the external router peers each replica as a BGP neighbor (ECMP across replicas). Mirrors ResolvedAZVPC.TransitIPPool.string array
localASNLocalASN is the RESOLVED local autonomous system number for this VPC’s own per-VRF BGP instance (“router bgp vrf ”): AZVPCVLANRef.LocalASN if set, else AZEdgeRouterSpec.ASN. Reported here, rather than only in spec, so status is the single source of truth for what ASN the FRR config builder actually rendered.integer
peerIPPeerIP is the external router’s IP on the underlay VLAN (the shared BGP neighbor that every replica peers with). With several peers this reports the one carrying the VRF default route, or the first otherwise. Kept populated because it is what existing readers — the dashboard among them — already display; Peers is the complete answer.string
peersPeers are all the fabric neighbors on this VLAN with their defaults resolved, so what the router actually configured is readable without re-deriving the precedence rules from the spec.AZResolvedFabricPeer array
acceptPrefixesAcceptPrefixes is the resolved inbound accept-list for this VPC’s external fabric peers, in precedence order: the VLAN reference’s acceptPrefixes, then the VPC’s fabric-accept-prefixes annotation, then the AZ-wide perVRFTransit.acceptPrefixes. An empty list denies every prefix from the fabric peers, which is the safe default. For debugging, this renders as the prefix-list PL-EXT-IN-<vrf> in the router’s FRR configuration.AZAcceptPrefix array

Back to Group

AZInternalPeersSpec

AZInternalPeersSpec configures per-VPC peering with in-VPC BGP speakers that advertise static anycast blocks for aggregation toward the external router.

FieldDescriptionSchemeRequired
enabledEnabled turns on the per-VPC internal peer-group. Requires an external advertisement plane — BGPPeers or OVNTransitMode “bgp-per-vrf”.boolean
asnASN is the internal speakers’ autonomous system number. Zero means the session is configured as “remote-as external” (accept any peer ASN).integer
acceptPrefixesAcceptPrefixes bounds what the AZ router learns from internal speakers, typically the anycast super-block(s). An empty list accepts nothing, so a misconfigured speaker cannot inject arbitrary routes toward the external router. It is the default for every VPC; perVPC overrides it. Entries are IPv4 CIDRs. For debugging, this renders as the prefix-list METALLB-IN in the router’s FRR configuration.string array
perVPCPerVPC narrows AcceptPrefixes for individual VPCs. Each VPC’s internal peer-group filters on its own accept-list, so a speaker in one tenant VPC cannot inject another tenant’s anycast block — which a single AZ-wide list permits, since every VRF then shares one filter. A VPC with no entry here uses AcceptPrefixes unchanged.AZInternalPeersVPCOverride array
multihopTTLMultihopTTL is the eBGP multihop TTL for the internal session; the speaker sits one or more hops away behind the tenant VPC logical router.integer
bfdBFD enables BFD on the internal session.boolean

Back to Group

AZInternalPeersVPCOverride

AZInternalPeersVPCOverride narrows the internal-speaker accept-list for one VPC.

FieldDescriptionSchemeRequired
vpcVPC is the kube-ovn VPC name; must match a VPC this router resolves. An entry naming an unresolved VPC has no effect. A VPC of another namespace is written <namespace>/<name>; a bare name means the router’s own namespace.string
acceptPrefixesAcceptPrefixes replaces the AZ-wide internalPeers.acceptPrefixes for this VPC. An explicitly empty list accepts nothing from this VPC’s speakers, while omitting the field inherits the AZ-wide list. Entries are IPv4 CIDRs.string array

Back to Group

AZPerVRFTransitSpec

AZPerVRFTransitSpec configures per-tenant underlay VLAN attachments for the "bgp-per-vrf" OVN transit mode. The platform pre-provisions one UnderlaySubnet (ProviderNetwork + Vlan + Subnet) per tenant VLAN; the operator maps each own VPC to its UnderlaySubnet, attaches a NAD to it, allocates per-replica IPs, enslaves the interface to the VPC’s VRF, and peers the external router over it.

FieldDescriptionSchemeRequired
peerASNPeerASN is the external router’s autonomous system number for the per-VRF eBGP sessions.integer
vpcVLANsVPCVLANs maps each own VPC to the pre-provisioned underlay VLAN subnet it uses for its external per-VRF attachment.AZVPCVLANRef array
advertiseOVNSubnetsAdvertiseOVNSubnets controls whether each VPC’s OVN tenant subnets (and its transit subnet) are advertised to that VPC’s per-VRF fabric peer. Defaults to true, which suits a fabric that routes directly to tenant subnets. Set false for SNAT-only tenant egress, where the fabric must NOT learn tenant space: the tenant subnets are then reachable only via the router’s egress addresses, and the per-VRF session carries just the anycast blocks learned from in-VPC speakers (see InternalPeers). Without this, the per-VRF session advertises every subnet in status.resolvedAZVPCs[].subnets unconditionally. This is the router-wide default; VPCVLANs[].AdvertiseOVNSubnets overrides it for an individual VPC.boolean
acceptPrefixesAcceptPrefixes bounds what a VPC’s external per-VRF fabric peer(s) may inject INTO that VPC’s VRF via BGP — the inbound counterpart to the outbound egress filter AdvertisedSubnets/AdvertiseOVNSubnets already builds. Without it, “no bgp ebgp-requires-policy” (required so the session can come up without EITHER direction configured) leaves the peer free to advertise ANY prefix — including another tenant’s subnet on a shared advertisement VLAN — with nothing on this router checking it. Empty (the default) denies every inbound prefix: DefaultRoutePeers are rendered as STATIC routes, not learned via BGP, so no bgp-per-vrf deployment today depends on receiving anything from these sessions. Set this only for the rare case a fabric device needs to push something specific (e.g. a BGP-learned default instead of a static one). This is the router-wide default; VPCVLANs[].AcceptPrefixes overrides it for an individual VPC, and a VPC’s own fabric-accept-prefixes annotation feeds the override the same way it does for NADName/PeerIP/LocalASN.AZAcceptPrefix array

Back to Group

AZResolvedFabricPeer

AZResolvedFabricPeer is one fabric neighbor as the router configured it.

FieldDescriptionSchemeRequired
ipIP is the neighbor’s address on the underlay VLAN.string
asnASN is the neighbor’s ASN, after inheriting perVRFTransit.peerASN.integer
advertiseOVNSubnetsAdvertiseOVNSubnets reports whether this neighbor is sent the VPC’s OVN subnets.boolean
advertiseAnycastAdvertiseAnycast reports whether it is sent the anycast blocks learned in-VPC.boolean
defaultRouteDefaultRoute reports whether it carries the VRF’s default route. Exactly one neighbor per VPC can, and none is allowed.boolean
bfdBFD reports whether the session runs BFD.boolean
multihopTTLMultihopTTL is the eBGP multihop TTL configured for the session; 0 is single-hop.integer

Back to Group

AZTransitSubnetSpec

AZTransitSubnetSpec configures the transit address pool used to create per-VPC /30 point-to-point subnets in the management VPC. Each tenant VPC gets its own /30 Subnet CR named "-", providing a firewalling boundary between tenants with no implicit inter-VPC L2 path.

For VPC at sorted index i with replicaCount R, a block of size S=nextPow2(R+3) is allocated (minimum 4, i.e. /30 for R=1). The +3 reserves the network, gateway and broadcast addresses, so a transit IP never lands on the broadcast (which kube-ovn refuses to assign):

base + S*i + 0        network
base + S*i + 1        management VPC LR gateway  → GatewayIP
base + S*i + 2 ..R+1  FRR pod transit IPs        → TransitIPPool[0..R-1]
base + S*i + S-1      broadcast (always above the transit IPs)

For R=1: S=4 → /30 (gw .1, transit .2, broadcast .3). For R=2: S=8 → /29 (gw .1, transit .2/.3, broadcast .7). For R=3–5: S=8 → /29.

FieldDescriptionSchemeRequired
subnetNameSubnetName is the base name prefix for the operator-managed per-VPC transit Subnet CRs. Each VPC gets a Subnet named “-”.string
cidrCIDR is the address pool from which per-VPC /30 transit subnets are carved. Must not overlap kube-ovn’s join subnet (100.64.0.0/16) or any provider VLAN range.string

Back to Group

AZEdgeRouterRef

AZEdgeRouterRef references an AZEdgeRouter and one of the VPCs (VRFs) it serves.

FieldDescriptionSchemeRequired
nameName is the name of the AZEdgeRouter.string
namespaceNamespace is the namespace of the AZEdgeRouter.string
vpcVPC is the kube-ovn VPC name (the VRF on the AZ router) this policy applies to.string

Back to Group

ResolvedAZVPC

ResolvedAZVPC holds the resolved attachment state for a single VPC. Populated by the operator; read by the frr-config-watcher sidecar to configure per-VPC VRF devices and ip rules on the EdgeRouter pod.

FieldDescriptionSchemeRequired
nameName is the router-local key of the VPC: its own name when it is in the router’s namespace, <name>--<digest of the namespace> when it is in another. Per-VPC resources of the router are derived from it.string
namespaceNamespace is the namespace of the VPC when it is not the router’s own. Empty for a VPC of the router’s namespace and for cluster-scoped VPCs.string
vpcNameVPCName is the name of the VPC object when it differs from name, that is, for a VPC of another namespace.string
gatewayIPGatewayIP is the management VPC logical router’s IP on this VPC’s dedicated /30 transit subnet (e.g. “172.31.128.1”).string
transitIPTransitIP is the IP/prefix allocated for replica 0 of this VPC’s OVN Logical Router Port on its transit subnet (e.g. “172.31.128.2/30”). For single-replica deployments this is the only transit IP.string
transitIPPoolTransitIPPool holds the bare transit IPs for all replicas (no prefix). When ReplicaCount > 1 there is one entry per replica, e.g. [“172.31.128.2”, “172.31.128.3”] for two replicas. The kube-ovn ip_pool annotation is built from this list so each StatefulSet replica gets its own, stable transit IP.string array
routingTableRoutingTable is the Linux routing table ID assigned to this VPC’s VRF.integer
apiServerProxyAPIServerProxy reports that this VPC is allowed to reach the infra cluster’s API server through the router’s in-VPC apiserver proxy, resolved from the VPC’s apiserver-proxy annotation. The sidecar reads it from here rather than from the VPC object, which it has no client for.boolean
apiServerProxySubnetsAPIServerProxySubnets narrows the source CIDRs allowed to use it. Empty means every subnet of this VPC.string array
transitNICIndexTransitNICIndex is the stable Multus NIC index (the N in “netN”) for this VPC’s transit NIC. Allocated once when the VPC is first resolved and preserved across reconciles, so onboarding/off-boarding another VPC never renumbers an already- attached VPC’s NICs — required for dynamic-transit-NIC hot-plug (a running interface cannot be renumbered). 0 means not yet allocated.integer
externalNICIndexExternalNICIndex is the stable Multus NIC index for this VPC’s per-VRF external VLAN NIC (“bgp-per-vrf” transit mode only; 0 otherwise). Allocated once alongside TransitNICIndex from the same free pool so transit and external NICs never collide and never shift when the VPC set changes. AZExternalVLAN.InterfaceName is derived from it once the underlay VLAN is ready.integer
vniVNI is the VXLAN Network Identifier for this VPC’s EVPN VRF. When non-zero, the AZ EdgeRouter configures EVPN Type 5 routes for this VPC.integer
rdRD overrides the auto-derived EVPN Route Distinguisher for this VPC’s VRF. Set from a bound EVPNPolicy (see EVPNPolicyTarget.AZEdgeRouterRef); empty auto-derives “:”.string
importRTsImportRTs overrides the auto-derived import Route Targets for this VPC’s VRF. Set from a bound EVPNPolicy; empty auto-derives the symmetric “:” target. Use this for cross-VRF route leaking / asymmetric import that the symmetric default cannot express.string array
exportRTsExportRTs overrides the auto-derived export Route Targets for this VPC’s VRF. Set from a bound EVPNPolicy; empty auto-derives the symmetric “:” target.string array
subnetsSubnets is the list of CIDR blocks belonging to this VPC’s wrapper Subnets.string array
acceptPrefixesAcceptPrefixes is the resolved inbound accept-list for this VPC’s external fabric peers, in precedence order: the VLAN reference’s acceptPrefixes, then the VPC’s fabric-accept-prefixes annotation, then the AZ-wide perVRFTransit.acceptPrefixes. An empty list denies every prefix from the fabric peers, which is the safe default. For debugging, this renders as the prefix-list PL-EXT-IN-<vrf> in the router’s FRR configuration.AZAcceptPrefix array
egressEnabledEgressEnabled controls whether this VPC’s traffic should be SNAT’d/masqueraded by the AZ EdgeRouter pod. The operator always resolves it: true unless the VPC carries the egress-enabled=false annotation. Being a bool with omitempty, false is left out on the wire, so read an absent value as off.boolean
egressToSourceEgressToSource specifies an optional static source IP to SNAT traffic from this VPC to. When empty, MASQUERADE is used on the transit interface.string
egressToSourceBySubnetEgressToSourceBySubnet is the resolved per-subnet override of EgressToSource, keyed by canonical IPv4 CIDR, one IP per replica. See AZVPCRef.EgressToSourceBySubnet for why this exists and why it is per-replica; this is simply that value copied onto status once resolved (spec/annotation precedence already applied), the same way EgressToSource itself is.object (keys:string, values:string array)
externalVLANExternalVLAN is the per-VRF underlay VLAN attachment allocated for this VPC in “bgp-per-vrf” OVN transit mode. Populated by the operator; read by the frr-config-watcher to enslave the interface to the VPC’s VRF and by the config builder to peer the external router over it.AZExternalVLAN
externalVLANErrorExternalVLANError explains why this VPC has NO external VLAN attachment when its configuration asked for one — a malformed annotation, or a peer list that cannot be rendered. Recorded because the failure is otherwise invisible: the VPC is skipped so that one tenant’s mistake cannot take down every other tenant’s session, which means the only evidence was a line in the operator log. The symptom — a VPC that is attached and simply has no fabric session — looks identical to a fabric problem from the outside. Cleared as soon as the attachment resolves.string

Back to Group

PeerResolvedAZVPCs

PeerResolvedAZVPCs groups the resolved VPCs from a single peer AZEdgeRouter.

FieldDescriptionSchemeRequired
edgeRouterNameEdgeRouterName is the name of the peer AZEdgeRouter CR.string
namespaceNamespace is the namespace of the peer AZEdgeRouter’s transit NADs.string
vpcsVPCs is the list of resolved VPCs from the peer AZEdgeRouter.ResolvedAZVPC array

Back to Group

LearnedBGPRoute

LearnedBGPRoute is a single (prefix, nexthop) pair learned from an internal BGP peer.

FieldDescriptionSchemeRequired
cidrCIDR is the destination IP prefix learned from the internal peer.string
nextHopIPNextHopIP is the IP address of the internal peer that advertised this prefix.string

Back to Group

NADRef

NADRef is a reference to a NetworkAttachmentDefinition resource.

FieldDescriptionSchemeRequired
nameName is the name of the NetworkAttachmentDefinition.string
namespaceNamespace is the namespace of the NetworkAttachmentDefinition.string

Back to Group

EdgeRouterImage

EdgeRouterImage holds the container image references shared by EdgeRouter and AZEdgeRouter components.

FieldDescriptionSchemeRequired
frrFRR is the image for the FRouting container.string
netshootNetshoot is the image for the netshoot debug container.string
configWatcherConfigWatcher is the image for the frr-config-watcher sidecar container. Defaults to the operator image when empty.string

Back to Group

EdgeRouterResources

EdgeRouterResources defines resource requirements for each EdgeRouter container.

FieldDescriptionSchemeRequired
initInit defines resource requirements for the init container.ResourceRequirements
frrFRR defines resource requirements for the FRouting container.ResourceRequirements
netshootNetshoot defines resource requirements for the netshoot sidecar container.ResourceRequirements
configWatcherConfigWatcher defines resource requirements for the config watcher sidecar container.ResourceRequirements

Back to Group

NetshootSpec

NetshootSpec configures the netshoot debug sidecar.

FieldDescriptionSchemeRequired
enabledEnabled indicates whether the netshoot sidecar is enabled.boolean

Back to Group

BFDSessionStatus

BFDSessionStatus describes the status of a single BFD session.

FieldDescriptionSchemeRequired
peerIPPeerIP is the IP address of the BFD peer.string
podNamePodName is the name of the FRR pod that owns this session. Set only for external BFD sessions (one entry per pod per peer).string
statusStatus is the current state of the BFD session (e.g., “up”, “down”, “admin_down”, “unknown”).string
lastCheckTimeLastCheckTime is the timestamp of the most recent status query for this peer.metav1.Time

Back to Group

BFDSideSpec

BFDSideSpec configures BFD for one side (internal or external) of a BGP session.

FieldDescriptionSchemeRequired
enabledEnabled indicates whether BFD is enabled for this side.boolean
ipIP is the local IP address used for BFD sessions on this side.string

Back to Group

BFDSpec

BFDSpec defines the Bidirectional Forwarding Detection configuration.

FieldDescriptionSchemeRequired
minTxMinTx is the minimum BFD transmission interval in milliseconds.integer
minRxMinRx is the minimum BFD receive interval in milliseconds.integer
multiMulti is the BFD detection multiplier.integer
internalInternal configures BFD for the internal peering side.BFDSideSpec
externalExternal configures BFD for the external peering side.BFDSideSpec

Back to Group

BGPSessionStatus

BGPSessionStatus is one BGP neighbour of one router replica, as FRR reports it (show bgp vrf all summary json). It covers every session the replica has — the external fabric peers as well as the in-VPC speakers that connect to a listen range — which is otherwise only visible by running vtysh inside the pod.

FieldDescriptionSchemeRequired
replicaReplica is the router pod the session belongs to (each replica peers on its own).string
vrfVRF is the VRF the session lives in (“default” for the global table).string
neighborNeighbor is the peer address. For a dynamic peer it is the address the peer connected from, which is how an in-VPC MetalLB speaker shows up.string
addressFamilyAddressFamily is “ipv4”, “ipv6” or “evpn”: the address family the session carries. A neighbour that negotiates several appears once per family.string
remoteASNRemoteASN is the peer’s autonomous system number.integer
hostnameHostname is the hostname the peer announced (BGP hostname capability), e.g. the node a MetalLB speaker runs on.string
stateState is FRR’s session state: Established, Active, Connect, OpenSent, …string
dynamicDynamic is true when the peer was accepted through a bgp listen range (an in-VPC speaker) rather than configured explicitly (an external fabric peer).boolean
prefixesReceivedPrefixesReceived is the number of prefixes the peer advertised to this replica.integer
prefixesSentPrefixesSent is the number of prefixes this replica advertised to the peer.integer
establishedAtEstablishedAt is when the current session came up. It is an absolute timestamp rather than an uptime so it stays constant while the session lasts and does not rewrite the status on every read. Unset unless the session is Established.metav1.Time

Back to Group

AZEdgeRouterList

AZEdgeRouterList contains a list of AZEdgeRouter.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]AZEdgeRoutertrue

Back to Group

EVPNPeer

EVPNPeer describes a single BGP peer used exclusively for EVPN route exchange. Populated into an AZEdgeRouter’s status by the EVPNRouteReflector controller.

FieldDescriptionSchemeRequired
ipIP is the IP address of the EVPN peer (RR replica NAD IP).string
asnASN is the BGP Autonomous System Number of the EVPN peer.integer
multihopTTLMultihopTTL is the eBGP multihop TTL. Required when the peer is on a different VLAN reachable via L3 routing (typically 3).integer

Back to Group

ExternalNeighbor

ExternalNeighbor represents a single external BGP neighbor.

FieldDescriptionSchemeRequired
ipIP is the IP address of the external neighbor.string
asnASN is the remote Autonomous System Number for this neighbor. When 0 (unset) the peer-wide external ASN is used. Set it to peer multiple upstreams in different ASNs from a single router — e.g. a per-region external router and a shared global transit router in distinct ASNs.integer
passwordSecretPasswordSecret is an optional reference to a secret containing the BGP session password. Using a pointer ensures omitempty suppresses the field when not set.corev1.SecretKeySelector
advertiseInternalRoutesAdvertiseInternalRoutes controls whether routes learned from internal peers (e.g. MetalLB speakers) are included in the outbound prefix list for this neighbor.boolean
advertisedCIDRsAdvertisedCIDRs is an explicit allowlist of CIDR prefixes to advertise to this neighbor. When set, it replaces the peer-wide advertised subnets for this neighbor.string array
subnetLabelSelectorSubnetLabelSelector, when set, discovers subnets matching these labels and advertises their CIDRs to this neighbor, overriding the peer-wide advertisement.LabelSelector
multihopTTLMultihopTTL is the eBGP multihop TTL for this neighbor. Required when the peer is not on the external NAD’s subnet (reachable only via L3 through the VLAN gateway). Renders as “neighbor ebgp-multihop ”. Zero/unset leaves the eBGP default.integer

Back to Group

EVPNPolicy

EVPNPolicy is an admin-managed object that defines BGP EVPN Type 5 routing policy for one or more EdgeRouter instances. It specifies the VNI, Route Distinguisher, and import/export Route Targets that control cross-VPC reachability.

The operator resolves the policy and writes the result into each target EdgeRouter’s status (status.resolvedEVPNVRFs), where the frr-config-watcher sidecar reads it to generate per-VRF FRR configuration. Users deploying EdgeRouter objects do not need access to EVPNPolicy objects.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMeta
specEVPNPolicySpec
statusEVPNPolicyStatus

Back to Group

EVPNPolicyList

EVPNPolicyList contains a list of EVPNPolicy.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]EVPNPolicytrue

Back to Group

EVPNPolicySpec

EVPNPolicySpec defines the desired EVPN routing policy.

FieldDescriptionSchemeRequired
vniVNI is the VXLAN Network Identifier for this policy’s VRF.integer
rdRD is the BGP Route Distinguisher (e.g. “65002:200”).string
exportRTsExportRTs is the list of BGP Route Targets attached to prefixes advertised by this VRF. Peer VRFs that import a matching RT will install these routes.string array
importRTsImportRTs is the list of BGP Route Targets this VRF accepts. Routes advertised with a matching export RT are installed into this VRF.string array
targetsTargets lists the AZEdgeRouter VPCs (VRFs) this policy applies to. For each target the policy’s RD/ImportRTs/ExportRTs override the AZ router’s auto-derived symmetric “:” values on that VPC’s EVPN VRF.EVPNPolicyTarget array

Back to Group

EVPNPolicyStatus

EVPNPolicyStatus reflects the observed state of the policy application.

FieldDescriptionSchemeRequired
conditionsConditions is the list of status conditions for this EVPNPolicy.Condition array

Back to Group

EVPNPolicyTarget

EVPNPolicyTarget binds this policy to one VPC (VRF) served by an AZEdgeRouter.

FieldDescriptionSchemeRequired
azEdgeRouterRefAZEdgeRouterRef references the AZEdgeRouter and the VPC (VRF) this policy applies to. The policy’s RD/ImportRTs/ExportRTs override the AZ router’s auto-derived symmetric “:” values for that VPC’s EVPN VRF (the VNI itself is taken from the VPC).AZEdgeRouterRef

Back to Group

EVPNRRImage

EVPNRRImage holds the container image references for the route reflector.

FieldDescriptionSchemeRequired
frrFRR is the image for the FRRouting container (e.g. quay.io/frrouting/frr:10.5.0).string
configWatcherConfigWatcher is the image for the frr-config-watcher sidecar that detects ConfigMap changes and triggers in-place FRR reloads without pod restarts. (e.g. docker.io/soer3n/edge-router:v0.0.27-dev)string

Back to Group

EVPNRRResources

EVPNRRResources defines resource requirements for the route reflector containers.

FieldDescriptionSchemeRequired
frrFRR defines resource requirements for the FRouting container.ResourceRequirements
configWatcherConfigWatcher defines resource requirements for the config watcher sidecar container.ResourceRequirements

Back to Group

EVPNRouteReflector

EVPNRouteReflector is an admin-managed object that deploys a dedicated FRR BGP route reflector for EVPN Type 5 routes. It discovers EdgeRouter objects matching the selector, establishes iBGP sessions with them (same AS as the edge routers) using the l2vpn evpn address family only, and reflects EVPN routes between them with next-hop unchanged so that VXLAN data-plane traffic flows directly between edge router VTEPs. Each replica is assigned a pre-defined IP from spec.ips (by StatefulSet ordinal) on the dedicated NAD. The controller writes the RR peer info into each targeted EdgeRouter’s status.resolvedEVPNPeers so the frr-config-watcher sidecar adds the RR as an EVPN-only neighbor without requiring any manual EdgeRouter configuration.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ObjectMeta
specEVPNRouteReflectorSpec
statusEVPNRouteReflectorStatus

Back to Group

EVPNRouteReflectorList

EVPNRouteReflectorList contains a list of EVPNRouteReflector.

FieldDescriptionSchemeRequired
metadataRefer to Kubernetes API documentation for fields of metadata.ListMetafalse
items[]EVPNRouteReflectortrue

Back to Group

EVPNRouteReflectorSpec

EVPNRouteReflectorSpec defines the desired state of the route reflector.

FieldDescriptionSchemeRequired
asnASN is the BGP Autonomous System Number for this route reflector.integer
replicaCountReplicaCount is the number of RR pod replicas. Must equal len(IPs).integer
ipsIPs is the list of pre-defined IPs for the RR pods, one per replica by StatefulSet ordinal. These IPs are assigned on the NAD interface and are used as BGP router-IDs. len(IPs) must equal ReplicaCount.string array
subnetSubnet is the name of the OVN Subnet the RR pods attach to on their primary (eth0) interface, via the ovn.kubernetes.io/logical_switch annotation. This may be a plain overlay subnet — e.g. a subnet of a management VPC — in which case no dedicated VLAN/NAD is needed: the RR peers edge routers over the overlay and only reflects EVPN control-plane routes (VXLAN dataplane flows directly between edge router VTEPs, never through the RR). The pod IPs come from spec.ips via ip_pool.string
nadNAD is a legacy reference to a dedicated VLAN NetworkAttachmentDefinition. It is no longer consumed — the RR attaches to Subnet on eth0 — and is retained only for backward compatibility. Leave unset for overlay-attached route reflectors.NADRef
gatewayGateway is a legacy default-gateway IP on the (VLAN) NAD subnet. No longer consumed; retained for backward compatibility. Leave unset for overlay RRs.string
multihopTTLMultihopTTL is the BGP multihop TTL for sessions to edge routers on a different subnet, reachable via L3 routing (typically 3). The dynamic (listen-range) iBGP sessions do not use it.integer
imageImage holds the container image references for the RR pod.EVPNRRImage
azEdgeRouterSelectorAZEdgeRouterSelector selects AZEdgeRouter objects to relay EVPN Type 5 routes for. Because AZ router pod IPs are IPAM-assigned (not static), they are peered dynamically via bgp listen ranges (see PeerListenRanges) rather than as explicit neighbors; the controller injects the RR IPs into each matching AZEdgeRouter’s status.resolvedEVPNPeers so its sidecar adds the RR as an EVPN neighbor. A nil selector selects none (opt-in); an empty selector matches all AZEdgeRouters.LabelSelector
peerListenRangesPeerListenRanges is the list of CIDRs from which the RR accepts dynamic EVPN sessions via bgp listen range, i.e. the overlay/management subnets the selected AZEdgeRouters peer from. Required to relay AZ routers (their IPs are dynamic).string array
nodeSelectorNodeSelector constrains the route reflector pods to nodes matching these labels. Use this to ensure the RR pods are scheduled on nodes that have the required ProviderNetwork interfaces (VLANs / bridges).object (keys:string, values:string)
imagePullSecretsImagePullSecrets is a list of references to secrets used for pulling images.LocalObjectReference array
resourcesResources defines the resource requirements for each container in the RR pod.EVPNRRResources

Back to Group

EVPNRouteReflectorStatus

EVPNRouteReflectorStatus reflects the observed state of the route reflector.

FieldDescriptionSchemeRequired
readyReplicasReadyReplicas is the number of ready RR pod replicas.integer
conditionsConditions is the list of status conditions for this EVPNRouteReflector.Condition array

Back to Group