From 2edc79459fb89618dc496aa348660fc256b1579e Mon Sep 17 00:00:00 2001 From: Chin2691 Date: Wed, 15 Jul 2026 14:09:21 +0530 Subject: [PATCH] fix(kubevirt): validate additionalNetworks name format via CEL Adds CEL validation to KubevirtNetwork.Name requiring the / format with DNS label segments, and reduces MaxLength from 255 to 55 to stay within the KubeVirt DNS label limit for generated interface names (63 - len("iface20_") = 55). Changes AdditionalNetworks list type to map with name as the key to enforce uniqueness at the API level. Includes envtest coverage for valid and invalid name formats, and extends crdify-config.yaml to mirror openshift/api policy so verify-crd-schema warns on intentional API tightenings. Fixes: https://redhat.atlassian.net/browse/OCPBUGS-87991 Co-authored-by: Cursor --- api/hypershift/v1beta1/kubevirt.go | 12 +- .../AAA_ungated.yaml | 18 +- .../GCPPlatform.yaml | 18 +- .../OSStreams.yaml | 18 +- .../OpenStack.yaml | 18 +- .../stable.nodepools.kubevirt.testsuite.yaml | 341 ++++++++++++++++++ .../nodepools-CustomNoUpgrade.crd.yaml | 18 +- .../nodepools-Default.crd.yaml | 18 +- .../nodepools-TechPreviewNoUpgrade.crd.yaml | 18 +- docs/content/reference/aggregated-docs.md | 7 +- docs/content/reference/api.md | 7 +- .../api/hypershift/v1beta1/kubevirt.go | 12 +- 12 files changed, 485 insertions(+), 20 deletions(-) create mode 100644 cmd/install/assets/crds/hypershift-operator/tests/nodepools.hypershift.openshift.io/stable.nodepools.kubevirt.testsuite.yaml diff --git a/api/hypershift/v1beta1/kubevirt.go b/api/hypershift/v1beta1/kubevirt.go index cc83e14d45bc..915557bd6e1f 100644 --- a/api/hypershift/v1beta1/kubevirt.go +++ b/api/hypershift/v1beta1/kubevirt.go @@ -169,6 +169,8 @@ type KubevirtNodePoolPlatform struct { // additionalNetworks specify the extra networks attached to the nodes // // +optional + // +listType=map + // +listMapKey=name // +kubebuilder:validation:MaxItems=20 AdditionalNetworks []KubevirtNetwork `json:"additionalNetworks,omitempty"` @@ -198,8 +200,14 @@ type KubevirtNodePoolPlatform struct { type KubevirtNetwork struct { // name specify the network attached to the nodes // it is a value with the format "[namespace]/[name]" to reference the - // multus network attachment definition - // +kubebuilder:validation:MaxLength=255 + // multus network attachment definition, where namespace and name consist + // only of lowercase alphanumeric characters and hyphens, and start and + // end with alphanumeric characters + // +kubebuilder:validation:MaxLength=55 + // MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + // The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + // giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + // +kubebuilder:validation:XValidation:rule="self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$')",message="name must be in the format / where namespace and name consist only of lowercase alphanumeric characters and hyphens, and start and end with alphanumeric characters" // +required Name string `json:"name"` } diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml index 2dd3ed7489bd..d1a84f4d57f1 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/AAA_ungated.yaml @@ -1103,14 +1103,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml index 32068675f5e4..f737ac5d0d04 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/GCPPlatform.yaml @@ -1371,14 +1371,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OSStreams.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OSStreams.yaml index d931fdf9fa01..a03d8c0a867c 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OSStreams.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OSStreams.yaml @@ -1136,14 +1136,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml index 52db786bf579..c592d18b7d0d 100644 --- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml +++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/nodepools.hypershift.openshift.io/OpenStack.yaml @@ -1103,14 +1103,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/cmd/install/assets/crds/hypershift-operator/tests/nodepools.hypershift.openshift.io/stable.nodepools.kubevirt.testsuite.yaml b/cmd/install/assets/crds/hypershift-operator/tests/nodepools.hypershift.openshift.io/stable.nodepools.kubevirt.testsuite.yaml new file mode 100644 index 000000000000..29b3b5d23bf9 --- /dev/null +++ b/cmd/install/assets/crds/hypershift-operator/tests/nodepools.hypershift.openshift.io/stable.nodepools.kubevirt.testsuite.yaml @@ -0,0 +1,341 @@ +apiVersion: apiextensions.k8s.io/v1 +name: "NodePool KubeVirt additionalNetworks validation" +crdName: nodepools.hypershift.openshift.io +version: v1beta1 +tests: + onCreate: + # --- additionalNetworks name format validation --- + - name: when additionalNetworks name is valid namespace/name format it should pass + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-ns/my-nad" + type: KubeVirt + + - name: when additionalNetworks has multiple valid networks it should pass + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "ns-a/nad-1" + - name: "ns-b/nad-2" + type: KubeVirt + + - name: when additionalNetworks name has no slash it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "just-a-name" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has multiple slashes it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "ns/sub/name" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has empty namespace it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "/my-nad" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has empty name segment it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-ns/" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has whitespace in namespace it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: " /name" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has whitespace in name segment it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-ns/my nad" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has dot in name segment it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-ns/my.nad" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has uppercase characters it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "My-ns/my-nad" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks name has underscore in namespace it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my_ns/my-nad" + type: KubeVirt + expectedError: "name must be in the format /" + + - name: when additionalNetworks has duplicate names it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "ns/nad1" + - name: "ns/nad1" + type: KubeVirt + expectedError: "Duplicate value" + + - name: when additionalNetworks name is at max length 55 it should pass + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-namespace-name-that-is-long/my-nad-name-also-long-ab" + type: KubeVirt + + - name: when additionalNetworks name exceeds max length 55 it should fail + initial: | + apiVersion: hypershift.openshift.io/v1beta1 + kind: NodePool + spec: + arch: amd64 + clusterName: some-cluster + management: + autoRepair: false + upgradeType: Replace + release: + image: quay.io/openshift-release-dev/ocp-release:4.17.0-rc.0-x86_64 + replicas: 0 + platform: + kubevirt: + rootVolume: + type: Persistent + persistent: + size: 32Gi + additionalNetworks: + - name: "my-namespace-name-that-is-long/my-nad-name-also-long-abc" + type: KubeVirt + expectedError: "Too long" diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml index fcc3e06a9f47..edd0c6aaa6fa 100644 --- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml +++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-CustomNoUpgrade.crd.yaml @@ -1407,14 +1407,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml index 1f54fc9e8976..718dbdb8a76c 100644 --- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml +++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-Default.crd.yaml @@ -1139,14 +1139,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml index 6208185af00f..258a4e9cc0ad 100644 --- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml +++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/nodepools-TechPreviewNoUpgrade.crd.yaml @@ -1407,14 +1407,28 @@ spec: description: |- name specify the network attached to the nodes it is a value with the format "[namespace]/[name]" to reference the - multus network attachment definition - maxLength: 255 + multus network attachment definition, where namespace and name consist + only of lowercase alphanumeric characters and hyphens, and start and + end with alphanumeric characters + MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + maxLength: 55 type: string + x-kubernetes-validations: + - message: name must be in the format / + where namespace and name consist only of lowercase + alphanumeric characters and hyphens, and start and + end with alphanumeric characters + rule: self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$') required: - name type: object maxItems: 20 type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map attachDefaultNetwork: default: true description: |- diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md index 2ed11311c089..f9bb8e225324 100644 --- a/docs/content/reference/aggregated-docs.md +++ b/docs/content/reference/aggregated-docs.md @@ -52261,7 +52261,12 @@ string

name specify the network attached to the nodes it is a value with the format “[namespace]/[name]” to reference the -multus network attachment definition

+multus network attachment definition, where namespace and name consist +only of lowercase alphanumeric characters and hyphens, and start and +end with alphanumeric characters +MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). +The generated name is “iface{N}{namespace}-{name}” where N≤20 (MaxItems), +giving a max prefix of “iface20” (8 chars), leaving 55 chars for namespace/name.

diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md index 6aa258dfa858..2af726d77371 100644 --- a/docs/content/reference/api.md +++ b/docs/content/reference/api.md @@ -12364,7 +12364,12 @@ string

name specify the network attached to the nodes it is a value with the format “[namespace]/[name]” to reference the -multus network attachment definition

+multus network attachment definition, where namespace and name consist +only of lowercase alphanumeric characters and hyphens, and start and +end with alphanumeric characters +MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). +The generated name is “iface{N}{namespace}-{name}” where N≤20 (MaxItems), +giving a max prefix of “iface20” (8 chars), leaving 55 chars for namespace/name.

diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/kubevirt.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/kubevirt.go index cc83e14d45bc..915557bd6e1f 100644 --- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/kubevirt.go +++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/kubevirt.go @@ -169,6 +169,8 @@ type KubevirtNodePoolPlatform struct { // additionalNetworks specify the extra networks attached to the nodes // // +optional + // +listType=map + // +listMapKey=name // +kubebuilder:validation:MaxItems=20 AdditionalNetworks []KubevirtNetwork `json:"additionalNetworks,omitempty"` @@ -198,8 +200,14 @@ type KubevirtNodePoolPlatform struct { type KubevirtNetwork struct { // name specify the network attached to the nodes // it is a value with the format "[namespace]/[name]" to reference the - // multus network attachment definition - // +kubebuilder:validation:MaxLength=255 + // multus network attachment definition, where namespace and name consist + // only of lowercase alphanumeric characters and hyphens, and start and + // end with alphanumeric characters + // +kubebuilder:validation:MaxLength=55 + // MaxLength=55: KubeVirt requires Interface.Name to be a DNS label (max 63 chars). + // The generated name is "iface{N}_{namespace}-{name}" where N≤20 (MaxItems), + // giving a max prefix of "iface20_" (8 chars), leaving 55 chars for namespace/name. + // +kubebuilder:validation:XValidation:rule="self.matches('^[a-z0-9]([a-z0-9-]*[a-z0-9])?/[a-z0-9]([a-z0-9-]*[a-z0-9])?$')",message="name must be in the format / where namespace and name consist only of lowercase alphanumeric characters and hyphens, and start and end with alphanumeric characters" // +required Name string `json:"name"` }