From 41d522e200d20e45952877df985c30b8c6185c09 Mon Sep 17 00:00:00 2001
From: Oren Cohen
Date: Tue, 5 May 2026 14:18:13 +0300
Subject: [PATCH] fix(api): OCPBUGS-84303: add IPv6 OVN join subnet config to
prevent dual-stack routing collision
When a KubeVirt hosted cluster and its management cluster both use
OVN-Kubernetes with dual-stack networking, they each default to
fd98::/64 for the IPv6 join switch subnet. External IPv6 LoadBalancer
traffic targeting VM pods is SNAT'd to the management cluster's join IP
(e.g. fd98::2). Inside the VM, the guest cluster's OVN intercepts the
response because it also owns fd98::/64, black-holing the packet.
This commit fixes the issue in two ways:
1. Automatic KubeVirt default: for KubeVirt hosted clusters with
OVNKubernetes, the reconciler now sets IPv6.InternalJoinSubnet to
fd99::/64 by default, avoiding the collision with the management
cluster's fd98::/64. This mirrors the existing V4InternalSubnet
override (100.66.0.0/16) already in place for IPv4.
2. User-facing API: adds OVNIPv6Config type to OVNKubernetesConfig,
allowing explicit configuration of IPv6 internalJoinSubnet and
internalTransitSwitchSubnet for any platform. This maps to the
upstream operatorv1.IPv6OVNKubernetesConfig and includes IPv6 CIDR
format validation via CEL rules.
Also extends CIDR overlap validation in the HostedCluster webhook to
cover IPv6 OVN subnets, and adds envtest CRD validation cases.
Fixes: https://redhat.atlassian.net/browse/OCPBUGS-84303
Signed-off-by: Oren Cohen
Assisted-by: Claude
---
api/hypershift/v1beta1/operator.go | 74 ++
.../v1beta1/zz_generated.deepcopy.go | 16 +
.../AAA_ungated.yaml | 88 ++
.../AutoNodeKarpenter.yaml | 88 ++
.../ClusterUpdateAcceptRisks.yaml | 88 ++
.../ClusterVersionOperatorConfiguration.yaml | 88 ++
.../ExternalOIDC.yaml | 88 ++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 88 ++
.../ExternalOIDCWithUpstreamParity.yaml | 88 ++
.../GCPPlatform.yaml | 88 ++
.../HCPEtcdBackup.yaml | 88 ++
...perShiftOnlyDynamicResourceAllocation.yaml | 88 ++
.../ImageStreamImportMode.yaml | 88 ++
.../KMSEncryptionProvider.yaml | 88 ++
.../OpenStack.yaml | 88 ++
.../AAA_ungated.yaml | 88 ++
.../AutoNodeKarpenter.yaml | 88 ++
.../ClusterUpdateAcceptRisks.yaml | 88 ++
.../ClusterVersionOperatorConfiguration.yaml | 88 ++
.../ExternalOIDC.yaml | 88 ++
...ernalOIDCWithUIDAndExtraClaimMappings.yaml | 88 ++
.../ExternalOIDCWithUpstreamParity.yaml | 88 ++
.../GCPPlatform.yaml | 88 ++
.../HCPEtcdBackup.yaml | 88 ++
...perShiftOnlyDynamicResourceAllocation.yaml | 88 ++
.../ImageStreamImportMode.yaml | 88 ++
.../KMSEncryptionProvider.yaml | 88 ++
.../OpenStack.yaml | 88 ++
.../hypershift/v1beta1/ovnipv6config.go | 47 +
.../hypershift/v1beta1/ovnkubernetesconfig.go | 9 +
client/applyconfiguration/utils.go | 2 +
...e.hostedclusters.networking.testsuite.yaml | 863 ++++++++++++++++++
...usters-Hypershift-CustomNoUpgrade.crd.yaml | 88 ++
...hostedclusters-Hypershift-Default.crd.yaml | 88 ++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 88 ++
...planes-Hypershift-CustomNoUpgrade.crd.yaml | 88 ++
...dcontrolplanes-Hypershift-Default.crd.yaml | 88 ++
...s-Hypershift-TechPreviewNoUpgrade.crd.yaml | 88 ++
.../resources/network/reconcile.go | 28 +-
.../resources/network/reconcile_test.go | 172 +++-
.../controllers/resources/resources.go | 21 +-
docs/content/reference/aggregated-docs.md | 86 ++
docs/content/reference/api.md | 86 ++
.../hostedcluster/hostedcluster_controller.go | 44 +
.../hostedcluster_controller_test.go | 157 +++-
.../api/hypershift/v1beta1/operator.go | 74 ++
.../v1beta1/zz_generated.deepcopy.go | 16 +
47 files changed, 4495 insertions(+), 16 deletions(-)
create mode 100644 client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
diff --git a/api/hypershift/v1beta1/operator.go b/api/hypershift/v1beta1/operator.go
index ee74790f5ba0..f06961b2273c 100644
--- a/api/hypershift/v1beta1/operator.go
+++ b/api/hypershift/v1beta1/operator.go
@@ -4,6 +4,20 @@ import (
operatorv1 "github.com/openshift/api/operator/v1"
)
+const (
+ // KubevirtDefaultV6InternalJoinSubnet is the default IPv6 OVN join subnet
+ // for KubeVirt hosted clusters. The upstream OVN-Kubernetes default is fd98::/64,
+ // but KubeVirt guests use fd99::/64 to avoid collisions with the management
+ // cluster's join subnet when both run OVN-Kubernetes.
+ KubevirtDefaultV6InternalJoinSubnet = "fd99::/64"
+
+ // KubevirtDefaultV4InternalSubnet is the default IPv4 OVN internal subnet
+ // for KubeVirt hosted clusters. The upstream OVN-Kubernetes default gateway
+ // router LRP CIDR is 100.64.0.0/16 and the default UDNs is 100.65.0.0/16.
+ // KubeVirt guests use 100.66.0.0/16 to avoid collisions with the management cluster.
+ KubevirtDefaultV4InternalSubnet = "100.66.0.0/16"
+)
+
// +kubebuilder:validation:Enum="";Normal;Debug;Trace;TraceAll
type LogLevel string
@@ -38,6 +52,7 @@ type ClusterVersionOperatorSpec struct {
OperatorLogLevel LogLevel `json:"operatorLogLevel,omitempty"`
}
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)", message="ovnKubernetesConfig is immutable once set and cannot be removed"
type ClusterNetworkOperatorSpec struct {
// disableMultiNetwork when set to true disables the Multus CNI plugin and related components
// in the hosted cluster. This prevents the installation of multus daemon sets in the
@@ -62,7 +77,11 @@ type ClusterNetworkOperatorSpec struct {
// OVNKubernetesConfig contains OVN-Kubernetes specific configuration options.
// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L400-L471
// +kubebuilder:validation:XValidation:rule="!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet) || !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet != self.ipv4.internalTransitSwitchSubnet", message="internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
+// +kubebuilder:validation:XValidation:rule="!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet) || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet != self.ipv6.internalTransitSwitchSubnet", message="ipv6 internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.mtu) || has(self.mtu)",message="mtu is immutable once set and cannot be removed"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || has(self.ipv6)", message="ipv6 is immutable once set and cannot be removed"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet) || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))", message="ipv6.internalJoinSubnet cannot be removed once set"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet) || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))", message="ipv6.internalTransitSwitchSubnet cannot be removed once set"
// +kubebuilder:validation:MinProperties=1
type OVNKubernetesConfig struct {
// ipv4 allows users to configure IP settings for IPv4 connections. When omitted,
@@ -71,6 +90,15 @@ type OVNKubernetesConfig struct {
// +optional
IPv4 *OVNIPv4Config `json:"ipv4,omitempty"`
+ // ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ // this means no opinions and the default configuration is used. Check individual
+ // fields within ipv6 for details of default values.
+ // For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ // set ipv6.internalJoinSubnet to a value different from the management cluster's
+ // join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ // +optional
+ IPv6 OVNIPv6Config `json:"ipv6,omitzero"`
+
// mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
// This must be 100 bytes smaller than the uplink MTU.
// When unset, the cluster-network-operator will determine the MTU automatically
@@ -126,6 +154,52 @@ type OVNIPv4Config struct {
InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
}
+// OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L541-L570
+// +kubebuilder:validation:MinProperties=1
+type OVNIPv6Config struct {
+ // internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ // by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ // architecture that connects the cluster routers on each node together to enable
+ // east west traffic. The subnet chosen should not overlap with other networks
+ // specified for OVN-Kubernetes as well as other networks used on the host.
+ // When omitted, this means no opinion and the platform is left to choose a reasonable
+ // default which is subject to change over time.
+ // The current default subnet is fd97::/64.
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ // IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ // The prefix length must be in the range /0 to /125 inclusive.
+ // This field is immutable once set.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).ip().family() == 6", message="Subnet must be in valid IPv6 CIDR format (e.g., fd97::/64)"
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).prefixLength() <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="internalTransitSwitchSubnet is immutable"
+ // +optional
+ InternalTransitSwitchSubnet string `json:"internalTransitSwitchSubnet,omitempty"`
+ // internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ // default one is being already used by something else. It must not overlap with
+ // any other subnet being used by OpenShift or by the node network. The size of the
+ // subnet must be larger than the number of nodes.
+ // The current default value is fd98::/64.
+ // For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ // automatically use fd99::/64 to avoid collisions with the management cluster's
+ // default join subnet (fd98::/64).
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ // IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ // The prefix length must be in the range /0 to /125 inclusive.
+ // This field is immutable once set.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).ip().family() == 6", message="Subnet must be in valid IPv6 CIDR format (e.g., fd98::/64)"
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).prefixLength() <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="internalJoinSubnet is immutable"
+ // +optional
+ InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
+}
+
// IngressOperatorSpec is the specification of the desired behavior of the Ingress Operator.
type IngressOperatorSpec struct {
// endpointPublishingStrategy is used to publish the default ingress controller endpoints.
diff --git a/api/hypershift/v1beta1/zz_generated.deepcopy.go b/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 1ba98f438a46..574e585b4222 100644
--- a/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -3958,6 +3958,21 @@ func (in *OVNIPv4Config) DeepCopy() *OVNIPv4Config {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OVNIPv6Config) DeepCopyInto(out *OVNIPv6Config) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNIPv6Config.
+func (in *OVNIPv6Config) DeepCopy() *OVNIPv6Config {
+ if in == nil {
+ return nil
+ }
+ out := new(OVNIPv6Config)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = *in
@@ -3966,6 +3981,7 @@ func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = new(OVNIPv4Config)
**out = **in
}
+ out.IPv6 = in.IPv6
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNKubernetesConfig.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
index bfb02b5417ee..e54871482443 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AAA_ungated.yaml
@@ -3118,6 +3118,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3145,9 +3214,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
index edd20bc7bd97..c59b4f7089af 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/AutoNodeKarpenter.yaml
@@ -3245,6 +3245,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3272,9 +3341,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index 8f516f4fce3d..66ea68922dfc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -3109,6 +3109,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3136,9 +3205,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 7fdee82f7644..cf3719d494b5 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -3109,6 +3109,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3136,9 +3205,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
index fbabbd81852a..0bfd462da2d5 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDC.yaml
@@ -3442,6 +3442,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3469,9 +3538,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 9a628fd1e9dc..cd7cc521e749 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -3582,6 +3582,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3609,9 +3678,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 79f43c9a8b80..c3049cfb29c7 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -3563,6 +3563,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3590,9 +3659,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
index b914e5c54625..150408d43625 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/GCPPlatform.yaml
@@ -3109,6 +3109,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3136,9 +3205,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
index 2e533f729c66..0889b0a79fec 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -3174,6 +3174,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3201,9 +3270,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index 894b65fa84e9..3c242c80f7da 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -3131,6 +3131,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3158,9 +3227,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
index 55d6d2fda030..8680b5635fe5 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -3127,6 +3127,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3154,9 +3223,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
index ee3000e356c0..bee2eb707983 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -3185,6 +3185,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3212,9 +3281,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
index c8991b80bd5a..f1cdcb9b41dc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedclusters.hypershift.openshift.io/OpenStack.yaml
@@ -3109,6 +3109,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3136,9 +3205,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
index dd571e490c7c..5f3224b03610 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AAA_ungated.yaml
@@ -3002,6 +3002,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3029,9 +3098,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
index 2d17d950869b..ca3f328e2cbc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/AutoNodeKarpenter.yaml
@@ -3131,6 +3131,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3158,9 +3227,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
index d31de0d4b587..dbf6d4dd208c 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterUpdateAcceptRisks.yaml
@@ -2993,6 +2993,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3020,9 +3089,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
index 120511f48cf0..abe56bcfebe0 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ClusterVersionOperatorConfiguration.yaml
@@ -2993,6 +2993,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3020,9 +3089,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
index 5f76bbf48e51..b0a9a37df860 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDC.yaml
@@ -3326,6 +3326,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3353,9 +3422,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
index 540b77443c0e..dcb4e94c6690 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUIDAndExtraClaimMappings.yaml
@@ -3466,6 +3466,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3493,9 +3562,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
index 833b3fdbcb9f..30f757532736 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ExternalOIDCWithUpstreamParity.yaml
@@ -3447,6 +3447,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3474,9 +3543,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
index 649e4f7894b0..87968666058c 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/GCPPlatform.yaml
@@ -2993,6 +2993,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3020,9 +3089,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
index a6a52da20e1a..b90a10c47cb2 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HCPEtcdBackup.yaml
@@ -3058,6 +3058,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3085,9 +3154,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
index c43d47e96d49..4285bf139f01 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/HyperShiftOnlyDynamicResourceAllocation.yaml
@@ -3015,6 +3015,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3042,9 +3111,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
index ea472e73807a..23c56e749d2a 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/ImageStreamImportMode.yaml
@@ -3011,6 +3011,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3038,9 +3107,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
index 174be75197cd..c45dcc56f937 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/KMSEncryptionProvider.yaml
@@ -3069,6 +3069,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3096,9 +3165,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
index 1cebfc2a0dc8..f2fedda876cc 100644
--- a/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
+++ b/api/hypershift/v1beta1/zz_generated.featuregated-crd-manifests/hostedcontrolplanes.hypershift.openshift.io/OpenStack.yaml
@@ -2993,6 +2993,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3020,9 +3089,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go b/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
new file mode 100644
index 000000000000..2205ac30a97e
--- /dev/null
+++ b/client/applyconfiguration/hypershift/v1beta1/ovnipv6config.go
@@ -0,0 +1,47 @@
+/*
+
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta1
+
+// OVNIPv6ConfigApplyConfiguration represents a declarative configuration of the OVNIPv6Config type for use
+// with apply.
+type OVNIPv6ConfigApplyConfiguration struct {
+ InternalTransitSwitchSubnet *string `json:"internalTransitSwitchSubnet,omitempty"`
+ InternalJoinSubnet *string `json:"internalJoinSubnet,omitempty"`
+}
+
+// OVNIPv6ConfigApplyConfiguration constructs a declarative configuration of the OVNIPv6Config type for use with
+// apply.
+func OVNIPv6Config() *OVNIPv6ConfigApplyConfiguration {
+ return &OVNIPv6ConfigApplyConfiguration{}
+}
+
+// WithInternalTransitSwitchSubnet sets the InternalTransitSwitchSubnet field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the InternalTransitSwitchSubnet field is set to the value of the last call.
+func (b *OVNIPv6ConfigApplyConfiguration) WithInternalTransitSwitchSubnet(value string) *OVNIPv6ConfigApplyConfiguration {
+ b.InternalTransitSwitchSubnet = &value
+ return b
+}
+
+// WithInternalJoinSubnet sets the InternalJoinSubnet field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the InternalJoinSubnet field is set to the value of the last call.
+func (b *OVNIPv6ConfigApplyConfiguration) WithInternalJoinSubnet(value string) *OVNIPv6ConfigApplyConfiguration {
+ b.InternalJoinSubnet = &value
+ return b
+}
diff --git a/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go b/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
index 6d3627c54206..ec04a89fa382 100644
--- a/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
+++ b/client/applyconfiguration/hypershift/v1beta1/ovnkubernetesconfig.go
@@ -21,6 +21,7 @@ package v1beta1
// with apply.
type OVNKubernetesConfigApplyConfiguration struct {
IPv4 *OVNIPv4ConfigApplyConfiguration `json:"ipv4,omitempty"`
+ IPv6 *OVNIPv6ConfigApplyConfiguration `json:"ipv6,omitempty"`
MTU *int32 `json:"mtu,omitempty"`
}
@@ -38,6 +39,14 @@ func (b *OVNKubernetesConfigApplyConfiguration) WithIPv4(value *OVNIPv4ConfigApp
return b
}
+// WithIPv6 sets the IPv6 field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the IPv6 field is set to the value of the last call.
+func (b *OVNKubernetesConfigApplyConfiguration) WithIPv6(value *OVNIPv6ConfigApplyConfiguration) *OVNKubernetesConfigApplyConfiguration {
+ b.IPv6 = value
+ return b
+}
+
// WithMTU sets the MTU field in the declarative configuration to the given value
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
// If called multiple times, the MTU field is set to the value of the last call.
diff --git a/client/applyconfiguration/utils.go b/client/applyconfiguration/utils.go
index a97e4b8fe858..fcc2dd919aa4 100644
--- a/client/applyconfiguration/utils.go
+++ b/client/applyconfiguration/utils.go
@@ -363,6 +363,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
return &hypershiftv1beta1.OperatorConfigurationApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("OVNIPv4Config"):
return &hypershiftv1beta1.OVNIPv4ConfigApplyConfiguration{}
+ case v1beta1.SchemeGroupVersion.WithKind("OVNIPv6Config"):
+ return &hypershiftv1beta1.OVNIPv6ConfigApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("OVNKubernetesConfig"):
return &hypershiftv1beta1.OVNKubernetesConfigApplyConfiguration{}
case v1beta1.SchemeGroupVersion.WithKind("PersistentVolumeEtcdStorageSpec"):
diff --git a/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.networking.testsuite.yaml b/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.networking.testsuite.yaml
index 66b1e94a8130..3b4ec77a92f2 100644
--- a/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.networking.testsuite.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/tests/hostedclusters.hypershift.openshift.io/stable.hostedclusters.networking.testsuite.yaml
@@ -619,3 +619,866 @@ tests:
servicePublishingStrategy:
type: Route
route: {}
+
+ - name: When ovnKubernetesConfig ipv6 is set and networkType is OVNKubernetes it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ internalTransitSwitchSubnet: "fd97:1::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ - name: When ovnKubernetesConfig has both ipv4 and ipv6 it should pass
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv4:
+ internalJoinSubnet: "10.10.0.0/16"
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+
+ - name: When ovnKubernetesConfig ipv6 has same internalJoinSubnet and internalTransitSwitchSubnet it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ internalTransitSwitchSubnet: "fd99::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "ipv6 internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
+
+ - name: When ovnKubernetesConfig ipv6 internalJoinSubnet has invalid CIDR it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "not-a-cidr"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "Subnet must be in valid IPv6 CIDR format"
+
+ - name: When ovnKubernetesConfig ipv6 internalTransitSwitchSubnet has invalid CIDR it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalTransitSwitchSubnet: "not-a-cidr"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "Subnet must be in valid IPv6 CIDR format"
+
+ - name: When ovnKubernetesConfig ipv6 internalJoinSubnet has prefix length greater than 125 it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/126"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "subnet must be in the range /0 to /125 inclusive"
+
+ - name: When ovnKubernetesConfig ipv6 internalTransitSwitchSubnet has prefix length greater than 125 it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalTransitSwitchSubnet: "fd97::/126"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "subnet must be in the range /0 to /125 inclusive"
+
+ - name: When ovnKubernetesConfig ipv6 is empty object it should fail MinProperties validation
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6: {}
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "should have at least 1 properties"
+
+ onUpdate:
+ - name: When ovnKubernetesConfig is removed after being set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv4:
+ internalJoinSubnet: "10.10.0.0/16"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator: {}
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "ovnKubernetesConfig is immutable once set and cannot be removed"
+
+ - name: When ipv6 internalJoinSubnet is changed it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd98::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "internalJoinSubnet is immutable"
+
+ - name: When ipv6 internalTransitSwitchSubnet is changed it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalTransitSwitchSubnet: "fd97::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalTransitSwitchSubnet: "fd97:1::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "internalTransitSwitchSubnet is immutable"
+
+ - name: When ipv6 is removed after being set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ mtu: 1400
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ mtu: 1400
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "ipv6 is immutable once set and cannot be removed"
+
+ - name: When ipv6 internalJoinSubnet is removed after being set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ internalTransitSwitchSubnet: "fd97::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalTransitSwitchSubnet: "fd97::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "ipv6.internalJoinSubnet cannot be removed once set"
+
+ - name: When ipv6 internalTransitSwitchSubnet is removed after being set it should fail
+ initial: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ internalTransitSwitchSubnet: "fd97::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ updated: |
+ apiVersion: hypershift.openshift.io/v1beta1
+ kind: HostedCluster
+ spec:
+ networking:
+ networkType: OVNKubernetes
+ operatorConfiguration:
+ clusterNetworkOperator:
+ ovnKubernetesConfig:
+ ipv6:
+ internalJoinSubnet: "fd99::/64"
+ dns:
+ baseDomain: example.com
+ platform:
+ type: AWS
+ pullSecret:
+ name: secret
+ release:
+ image: quay.io/openshift-release-dev/ocp-release:4.15.11-x86_64
+ secretEncryption:
+ aescbc:
+ activeKey:
+ name: key
+ type: aescbc
+ services:
+ - service: APIServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: OAuthServer
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Konnectivity
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ - service: Ignition
+ servicePublishingStrategy:
+ type: Route
+ route: {}
+ expectedError: "ipv6.internalTransitSwitchSubnet cannot be removed once set"
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
index 23efa259fd20..6fdf7c941f1b 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-CustomNoUpgrade.crd.yaml
@@ -4027,6 +4027,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -4054,9 +4123,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
index 053f49bd94df..5274769fbd37 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-Default.crd.yaml
@@ -3611,6 +3611,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3638,9 +3707,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
index 807ffe110c25..0d580f42d75a 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedclusters-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -3938,6 +3938,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3965,9 +4034,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
index 381b5f25d2dc..18a63bc6079a 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-CustomNoUpgrade.crd.yaml
@@ -3913,6 +3913,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3940,9 +4009,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
index 6f1e2814a3bd..949ee682b06b 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-Default.crd.yaml
@@ -3495,6 +3495,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3522,9 +3591,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
ingressOperator:
description: |-
ingressOperator specifies the configuration for the Ingress Operator in the hosted cluster.
diff --git a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
index ff77c7e8ba7b..c17d19d32c3d 100644
--- a/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
+++ b/cmd/install/assets/crds/hypershift-operator/zz_generated.crd-manifests/hostedcontrolplanes-Hypershift-TechPreviewNoUpgrade.crd.yaml
@@ -3824,6 +3824,75 @@ spec:
rule: self.matches('^[0-9]{1,3}\\..*') && int(self.split('/')[0].split('.')[0])
> 0
type: object
+ ipv6:
+ description: |-
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ this means no opinions and the default configuration is used. Check individual
+ fields within ipv6 for details of default values.
+ For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ set ipv6.internalJoinSubnet to a value different from the management cluster's
+ join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ minProperties: 1
+ properties:
+ internalJoinSubnet:
+ description: |-
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ default one is being already used by something else. It must not overlap with
+ any other subnet being used by OpenShift or by the node network. The size of the
+ subnet must be larger than the number of nodes.
+ The current default value is fd98::/64.
+ For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ automatically use fd99::/64 to avoid collisions with the management cluster's
+ default join subnet (fd98::/64).
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd98::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalJoinSubnet is immutable
+ rule: self == oldSelf
+ internalTransitSwitchSubnet:
+ description: |-
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ architecture that connects the cluster routers on each node together to enable
+ east west traffic. The subnet chosen should not overlap with other networks
+ specified for OVN-Kubernetes as well as other networks used on the host.
+ When omitted, this means no opinion and the platform is left to choose a reasonable
+ default which is subject to change over time.
+ The current default subnet is fd97::/64.
+ The subnet must be large enough to accommodate one IP per node in your cluster.
+ The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ The prefix length must be in the range /0 to /125 inclusive.
+ This field is immutable once set.
+ maxLength: 48
+ minLength: 3
+ type: string
+ x-kubernetes-validations:
+ - message: Subnet must be in valid IPv6 CIDR format
+ (e.g., fd97::/64)
+ rule: isCIDR(self) && cidr(self).ip().family() ==
+ 6
+ - message: subnet must be in the range /0 to /125
+ inclusive
+ rule: isCIDR(self) && cidr(self).prefixLength()
+ <= 125
+ - message: internalTransitSwitchSubnet is immutable
+ rule: self == oldSelf
+ type: object
mtu:
description: |-
mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
@@ -3851,9 +3920,28 @@ spec:
rule: '!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet)
|| !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet
!= self.ipv4.internalTransitSwitchSubnet'
+ - message: ipv6 internalJoinSubnet and internalTransitSwitchSubnet
+ must not be the same
+ rule: '!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet)
+ || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet
+ != self.ipv6.internalTransitSwitchSubnet'
- message: mtu is immutable once set and cannot be removed
rule: '!has(oldSelf.mtu) || has(self.mtu)'
+ - message: ipv6 is immutable once set and cannot be removed
+ rule: '!has(oldSelf.ipv6) || has(self.ipv6)'
+ - message: ipv6.internalJoinSubnet cannot be removed once
+ set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))'
+ - message: ipv6.internalTransitSwitchSubnet cannot be removed
+ once set
+ rule: '!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet)
+ || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))'
type: object
+ x-kubernetes-validations:
+ - message: ovnKubernetesConfig is immutable once set and cannot
+ be removed
+ rule: '!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)'
clusterVersionOperator:
description: clusterVersionOperator specifies the configuration
for the Cluster Version Operator in the hosted cluster.
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
index 22ddaa1ee605..1d22a3e2d4a5 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile.go
@@ -33,11 +33,10 @@ const kubevirtDefaultVXLANPort = uint32(9879)
// 9880 is a currently unassigned IANA port in the user port range.
const kubevirtDefaultGenevePort = uint32(9880)
-// The default OVN gateway router LRP CIDR is 100.64.0.0/16 and the default UDNs
-// is 100.65.0.0/16. We need to avoid that for kubernetes which runs nested.
-const kubevirtDefaultV4InternalSubnet = "100.66.0.0/16"
+const kubevirtDefaultV4InternalSubnet = hyperv1.KubevirtDefaultV4InternalSubnet
+const kubevirtDefaultV6InternalJoinSubnet = hyperv1.KubevirtDefaultV6InternalJoinSubnet
-func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.NetworkType, platformType hyperv1.PlatformType, disableMultiNetwork bool, ovnConfig *hyperv1.OVNKubernetesConfig) {
+func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.NetworkType, platformType hyperv1.PlatformType, disableMultiNetwork bool, ovnConfig *hyperv1.OVNKubernetesConfig, hasIPv6Network bool) {
switch platformType {
case hyperv1.KubevirtPlatform:
// Modify vxlan port to avoid collisions with management cluster's default vxlan port.
@@ -61,6 +60,14 @@ func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.N
if network.Spec.DefaultNetwork.OVNKubernetesConfig.GenevePort == nil {
network.Spec.DefaultNetwork.OVNKubernetesConfig.GenevePort = &port
}
+ if hasIPv6Network {
+ if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6 == nil {
+ network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ if network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6.InternalJoinSubnet == "" {
+ network.Spec.DefaultNetwork.OVNKubernetesConfig.IPv6.InternalJoinSubnet = kubevirtDefaultV6InternalJoinSubnet
+ }
+ }
}
case hyperv1.PowerVSPlatform:
if networkType == hyperv1.OVNKubernetes {
@@ -95,6 +102,19 @@ func ReconcileNetworkOperator(network *operatorv1.Network, networkType hyperv1.N
ovnCfg.IPv4.InternalTransitSwitchSubnet = ovnConfig.IPv4.InternalTransitSwitchSubnet
}
}
+ // Apply IPv6 configuration
+ if ovnConfig.IPv6.InternalJoinSubnet != "" {
+ if ovnCfg.IPv6 == nil {
+ ovnCfg.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ ovnCfg.IPv6.InternalJoinSubnet = ovnConfig.IPv6.InternalJoinSubnet
+ }
+ if ovnConfig.IPv6.InternalTransitSwitchSubnet != "" {
+ if ovnCfg.IPv6 == nil {
+ ovnCfg.IPv6 = &operatorv1.IPv6OVNKubernetesConfig{}
+ }
+ ovnCfg.IPv6.InternalTransitSwitchSubnet = ovnConfig.IPv6.InternalTransitSwitchSubnet
+ }
// Apply MTU configuration
if ovnConfig.MTU > 0 {
ovnCfg.MTU = ptr.To(uint32(ovnConfig.MTU))
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
index 534dd6587f6c..8222e38dabe4 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/network/reconcile_test.go
@@ -16,6 +16,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
vxlanPort := kubevirtDefaultVXLANPort
genevePort := kubevirtDefaultGenevePort
v4InternalSubnet := kubevirtDefaultV4InternalSubnet
+ v6InternalJoinSubnet := kubevirtDefaultV6InternalJoinSubnet
fakePort := uint32(11111)
testsCases := []struct {
@@ -25,6 +26,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
inputPlatformType hyperv1.PlatformType
disableMultiNetwork bool
ovnConfig *hyperv1.OVNKubernetesConfig
+ hasIPv6Network bool
expectedNetwork *operatorv1.Network
}{
{
@@ -33,6 +35,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
inputNetworkType: hyperv1.OVNKubernetes,
inputPlatformType: hyperv1.KubevirtPlatform,
disableMultiNetwork: false,
+ hasIPv6Network: true,
expectedNetwork: &operatorv1.Network{
ObjectMeta: NetworkOperator().ObjectMeta,
Spec: operatorv1.NetworkSpec{
@@ -43,6 +46,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
GenevePort: &genevePort,
V4InternalSubnet: v4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -119,6 +125,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
inputNetworkType: hyperv1.OVNKubernetes,
inputPlatformType: hyperv1.KubevirtPlatform,
disableMultiNetwork: false,
+ hasIPv6Network: true,
expectedNetwork: &operatorv1.Network{
ObjectMeta: NetworkOperator().ObjectMeta,
Spec: operatorv1.NetworkSpec{
@@ -129,6 +136,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
GenevePort: &fakePort,
V4InternalSubnet: kubevirtDefaultV4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -153,6 +163,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
inputNetworkType: hyperv1.OVNKubernetes,
inputPlatformType: hyperv1.KubevirtPlatform,
disableMultiNetwork: false,
+ hasIPv6Network: true,
expectedNetwork: &operatorv1.Network{
ObjectMeta: NetworkOperator().ObjectMeta,
Spec: operatorv1.NetworkSpec{
@@ -163,6 +174,9 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
V4InternalSubnet: "100.66.0.0/16",
GenevePort: &genevePort,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
},
},
},
@@ -362,6 +376,7 @@ func TestReconcileDefaultIngressController(t *testing.T) {
inputNetworkType: hyperv1.OVNKubernetes,
inputPlatformType: hyperv1.KubevirtPlatform,
disableMultiNetwork: false,
+ hasIPv6Network: true,
ovnConfig: &hyperv1.OVNKubernetesConfig{
MTU: 1300,
},
@@ -375,7 +390,10 @@ func TestReconcileDefaultIngressController(t *testing.T) {
OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
GenevePort: &genevePort,
V4InternalSubnet: v4InternalSubnet,
- MTU: ptr.To(uint32(1300)),
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: v6InternalJoinSubnet,
+ },
+ MTU: ptr.To(uint32(1300)),
},
},
},
@@ -433,12 +451,162 @@ func TestReconcileDefaultIngressController(t *testing.T) {
},
},
},
+ {
+ name: "When IPv6 subnets configured for OVN Kubernetes it should propagate to network operator",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.AWSPlatform,
+ disableMultiNetwork: false,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd97:1::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd97:1::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When OVN config has IPv4 and IPv6 subnets it should propagate both",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.AWSPlatform,
+ disableMultiNetwork: false,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv4: &hyperv1.OVNIPv4Config{
+ InternalJoinSubnet: "192.168.1.0/24",
+ },
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ IPv4: &operatorv1.IPv4OVNKubernetesConfig{
+ InternalJoinSubnet: "192.168.1.0/24",
+ },
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When KubeVirt with OVNKubernetes and user-specified IPv6 join subnet it should not override",
+ inputNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fdaa::/64",
+ },
+ },
+ },
+ },
+ },
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.KubevirtPlatform,
+ disableMultiNetwork: false,
+ hasIPv6Network: true,
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ GenevePort: &genevePort,
+ V4InternalSubnet: v4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fdaa::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When KubeVirt with OVNKubernetes and user-specified IPv6 via ovnConfig it should override the KubeVirt default",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.KubevirtPlatform,
+ disableMultiNetwork: false,
+ hasIPv6Network: true,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fdbb::/64",
+ },
+ },
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ GenevePort: &genevePort,
+ V4InternalSubnet: v4InternalSubnet,
+ IPv6: &operatorv1.IPv6OVNKubernetesConfig{
+ InternalJoinSubnet: "fdbb::/64",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "When KubeVirt with OVNKubernetes and no IPv6 networks it should not set IPv6 join subnet default",
+ inputNetwork: NetworkOperator(),
+ inputNetworkType: hyperv1.OVNKubernetes,
+ inputPlatformType: hyperv1.KubevirtPlatform,
+ disableMultiNetwork: false,
+ hasIPv6Network: false,
+ expectedNetwork: &operatorv1.Network{
+ ObjectMeta: NetworkOperator().ObjectMeta,
+ Spec: operatorv1.NetworkSpec{
+ OperatorSpec: operatorv1.OperatorSpec{
+ ManagementState: "Managed",
+ },
+ DefaultNetwork: operatorv1.DefaultNetworkDefinition{
+ OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{
+ GenevePort: &genevePort,
+ V4InternalSubnet: v4InternalSubnet,
+ },
+ },
+ },
+ },
+ },
}
for _, tc := range testsCases {
t.Run(tc.name, func(t *testing.T) {
g := NewGomegaWithT(t)
- ReconcileNetworkOperator(tc.inputNetwork, tc.inputNetworkType, tc.inputPlatformType, tc.disableMultiNetwork, tc.ovnConfig)
+ ReconcileNetworkOperator(tc.inputNetwork, tc.inputNetworkType, tc.inputPlatformType, tc.disableMultiNetwork, tc.ovnConfig, tc.hasIPv6Network)
g.Expect(tc.inputNetwork).To(BeEquivalentTo(tc.expectedNetwork))
})
}
diff --git a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
index 3bb1de30a1a0..b7dfa2e746cf 100644
--- a/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
+++ b/control-plane-operator/hostedclusterconfigoperator/controllers/resources/resources.go
@@ -675,7 +675,7 @@ func (r *reconciler) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result
ovnConfig = hcp.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig
}
if _, err := r.CreateOrUpdate(ctx, r.client, networkOperator, func() error {
- networkoperator.ReconcileNetworkOperator(networkOperator, hcp.Spec.Networking.NetworkType, hcp.Spec.Platform.Type, util.IsDisableMultiNetwork(hcp), ovnConfig)
+ networkoperator.ReconcileNetworkOperator(networkOperator, hcp.Spec.Networking.NetworkType, hcp.Spec.Platform.Type, util.IsDisableMultiNetwork(hcp), ovnConfig, hasIPv6Network(hcp))
return nil
}); err != nil {
errs = append(errs, fmt.Errorf("failed to reconcile network operator: %w", err))
@@ -3635,6 +3635,25 @@ func (r *reconciler) reconcileAzureCloudNodeManager(ctx context.Context, image s
return errs
}
+func hasIPv6Network(hcp *hyperv1.HostedControlPlane) bool {
+ for _, entry := range hcp.Spec.Networking.ClusterNetwork {
+ if net.IP(entry.CIDR.IP).To4() == nil {
+ return true
+ }
+ }
+ for _, entry := range hcp.Spec.Networking.ServiceNetwork {
+ if net.IP(entry.CIDR.IP).To4() == nil {
+ return true
+ }
+ }
+ for _, entry := range hcp.Spec.Networking.MachineNetwork {
+ if net.IP(entry.CIDR.IP).To4() == nil {
+ return true
+ }
+ }
+ return false
+}
+
// imageRegistryPlatformWithPVC returns true if the platform requires a PVC for the image registry.
func imageRegistryPlatformWithPVC(platform hyperv1.PlatformType) bool {
switch platform {
diff --git a/docs/content/reference/aggregated-docs.md b/docs/content/reference/aggregated-docs.md
index 1bb0e08dbc52..51a62d046216 100644
--- a/docs/content/reference/aggregated-docs.md
+++ b/docs/content/reference/aggregated-docs.md
@@ -44686,6 +44686,73 @@ The value must be in proper IPV4 CIDR format
+###OVNIPv6Config { #hypershift.openshift.io/v1beta1.OVNIPv6Config }
+
+(Appears on:
+OVNKubernetesConfig)
+
+
+
OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L541-L570
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+internalTransitSwitchSubnet
+
+string
+
+ |
+
+(Optional)
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+architecture that connects the cluster routers on each node together to enable
+east west traffic. The subnet chosen should not overlap with other networks
+specified for OVN-Kubernetes as well as other networks used on the host.
+When omitted, this means no opinion and the platform is left to choose a reasonable
+default which is subject to change over time.
+The current default subnet is fd97::/64.
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+The prefix length must be in the range /0 to /125 inclusive.
+This field is immutable once set.
+ |
+
+
+
+internalJoinSubnet
+
+string
+
+ |
+
+(Optional)
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+default one is being already used by something else. It must not overlap with
+any other subnet being used by OpenShift or by the node network. The size of the
+subnet must be larger than the number of nodes.
+The current default value is fd98::/64.
+For KubeVirt hosted clusters, if this field is not set, HyperShift will
+automatically use fd99::/64 to avoid collisions with the management cluster’s
+default join subnet (fd98::/64).
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+The prefix length must be in the range /0 to /125 inclusive.
+This field is immutable once set.
+ |
+
+
+
###OVNKubernetesConfig { #hypershift.openshift.io/v1beta1.OVNKubernetesConfig }
(Appears on:
@@ -44721,6 +44788,25 @@ fields within ipv4 for details of default values.
+ipv6,omitzero
+
+
+OVNIPv6Config
+
+
+ |
+
+(Optional)
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+this means no opinions and the default configuration is used. Check individual
+fields within ipv6 for details of default values.
+For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+set ipv6.internalJoinSubnet to a value different from the management cluster’s
+join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ |
+
+
+
mtu
int32
diff --git a/docs/content/reference/api.md b/docs/content/reference/api.md
index d7b624088949..9317828c00da 100644
--- a/docs/content/reference/api.md
+++ b/docs/content/reference/api.md
@@ -14238,6 +14238,73 @@ The value must be in proper IPV4 CIDR format
|
+###OVNIPv6Config { #hypershift.openshift.io/v1beta1.OVNIPv6Config }
+
+(Appears on:
+OVNKubernetesConfig)
+
+
+
OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L541-L570
+
+
+
+
+| Field |
+Description |
+
+
+
+
+
+internalTransitSwitchSubnet
+
+string
+
+ |
+
+(Optional)
+ internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+architecture that connects the cluster routers on each node together to enable
+east west traffic. The subnet chosen should not overlap with other networks
+specified for OVN-Kubernetes as well as other networks used on the host.
+When omitted, this means no opinion and the platform is left to choose a reasonable
+default which is subject to change over time.
+The current default subnet is fd97::/64.
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+The prefix length must be in the range /0 to /125 inclusive.
+This field is immutable once set.
+ |
+
+
+
+internalJoinSubnet
+
+string
+
+ |
+
+(Optional)
+ internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+default one is being already used by something else. It must not overlap with
+any other subnet being used by OpenShift or by the node network. The size of the
+subnet must be larger than the number of nodes.
+The current default value is fd98::/64.
+For KubeVirt hosted clusters, if this field is not set, HyperShift will
+automatically use fd99::/64 to avoid collisions with the management cluster’s
+default join subnet (fd98::/64).
+The subnet must be large enough to accommodate one IP per node in your cluster.
+The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+The prefix length must be in the range /0 to /125 inclusive.
+This field is immutable once set.
+ |
+
+
+
###OVNKubernetesConfig { #hypershift.openshift.io/v1beta1.OVNKubernetesConfig }
(Appears on:
@@ -14273,6 +14340,25 @@ fields within ipv4 for details of default values.
+ipv6,omitzero
+
+
+OVNIPv6Config
+
+
+ |
+
+(Optional)
+ ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+this means no opinions and the default configuration is used. Check individual
+fields within ipv6 for details of default values.
+For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+set ipv6.internalJoinSubnet to a value different from the management cluster’s
+join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ |
+
+
+
mtu
int32
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
index a55c37ffcb96..7c05dca82288 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
@@ -4363,6 +4363,50 @@ func validateSliceNetworkCIDRs(hc *hyperv1.HostedCluster) field.ErrorList {
}
}
}
+
+ if hc.Spec.Networking.NetworkType == hyperv1.OVNKubernetes {
+ var ipv4JoinSubnet string
+ if hc.Spec.OperatorConfiguration != nil && hc.Spec.OperatorConfiguration.ClusterNetworkOperator != nil &&
+ hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig != nil &&
+ hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv4 != nil {
+ ipv4JoinSubnet = hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv4.InternalJoinSubnet
+ }
+ // The reconciler defaults KubeVirt IPv4 internal subnet to avoid collision
+ // with the management cluster; include the effective value so overlaps are caught at admission time.
+ if ipv4JoinSubnet == "" && hc.Spec.Platform.Type == hyperv1.KubevirtPlatform {
+ _, cidr, err := net.ParseCIDR(hyperv1.KubevirtDefaultV4InternalSubnet)
+ if err == nil {
+ ce := cidrEntry{*cidr, *field.NewPath("spec", "operatorConfiguration", "clusterNetworkOperator", "ovnKubernetesConfig", "ipv4", "v4InternalSubnet (default)")}
+ cidrEntries = append(cidrEntries, ce)
+ }
+ }
+
+ var ipv6JoinSubnet, ipv6TransitSubnet string
+ if hc.Spec.OperatorConfiguration != nil && hc.Spec.OperatorConfiguration.ClusterNetworkOperator != nil &&
+ hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig != nil {
+ ipv6JoinSubnet = hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv6.InternalJoinSubnet
+ ipv6TransitSubnet = hc.Spec.OperatorConfiguration.ClusterNetworkOperator.OVNKubernetesConfig.IPv6.InternalTransitSwitchSubnet
+ }
+ // The reconciler defaults KubeVirt IPv6 join subnet to avoid collision with the
+ // management cluster; include the effective value so overlaps are caught at admission time.
+ if ipv6JoinSubnet == "" && hc.Spec.Platform.Type == hyperv1.KubevirtPlatform {
+ ipv6JoinSubnet = hyperv1.KubevirtDefaultV6InternalJoinSubnet
+ }
+ if ipv6JoinSubnet != "" {
+ _, cidr, err := net.ParseCIDR(ipv6JoinSubnet)
+ if err == nil {
+ ce := cidrEntry{*cidr, *field.NewPath("spec", "operatorConfiguration", "clusterNetworkOperator", "ovnKubernetesConfig", "ipv6", "internalJoinSubnet")}
+ cidrEntries = append(cidrEntries, ce)
+ }
+ }
+ if ipv6TransitSubnet != "" {
+ _, cidr, err := net.ParseCIDR(ipv6TransitSubnet)
+ if err == nil {
+ ce := cidrEntry{*cidr, *field.NewPath("spec", "operatorConfiguration", "clusterNetworkOperator", "ovnKubernetesConfig", "ipv6", "internalTransitSwitchSubnet")}
+ cidrEntries = append(cidrEntries, ce)
+ }
+ }
+ }
return compareCIDREntries(cidrEntries)
}
diff --git a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
index 27878c702132..3511c35041f5 100644
--- a/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
+++ b/hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
@@ -3839,13 +3839,14 @@ func TestComputeAWSEndpointServiceCondition(t *testing.T) {
func TestValidateSliceNetworkCIDRs(t *testing.T) {
tests := []struct {
- name string
- mn []hyperv1.MachineNetworkEntry
- cn []hyperv1.ClusterNetworkEntry
- sn []hyperv1.ServiceNetworkEntry
- networkType hyperv1.NetworkType
- ovnConfig *hyperv1.OVNKubernetesConfig
- wantErr bool
+ name string
+ mn []hyperv1.MachineNetworkEntry
+ cn []hyperv1.ClusterNetworkEntry
+ sn []hyperv1.ServiceNetworkEntry
+ networkType hyperv1.NetworkType
+ platformType hyperv1.PlatformType
+ ovnConfig *hyperv1.OVNKubernetesConfig
+ wantErr bool
}{
{
name: "given a conflicting IPv6 clusterNetwork overlapped with machineNetwork, it should fail",
@@ -3990,6 +3991,143 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
},
wantErr: false,
},
+ {
+ name: "When OVN-Kubernetes with valid IPv6 InternalJoinSubnet it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When OVN-Kubernetes with valid IPv6 InternalTransitSwitchSubnet it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalTransitSwitchSubnet: "fd97:1::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When OVN-Kubernetes IPv6 InternalJoinSubnet overlaps with MachineNetwork it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "When OVN-Kubernetes IPv6 subnets overlap with each other it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ InternalTransitSwitchSubnet: "fd99::/48",
+ },
+ },
+ wantErr: true,
+ },
+ {
+ name: "When OVN-Kubernetes with both valid IPv4 and IPv6 subnets it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv4: &hyperv1.OVNIPv4Config{
+ InternalJoinSubnet: "100.64.0.0/16",
+ },
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fd99::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When OVN-Kubernetes with empty IPv6 subnet strings it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "",
+ InternalTransitSwitchSubnet: "",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv6 config and MachineNetwork overlaps default fd99::/64 it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: true,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv6 config and non-overlapping networks it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd03::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: false,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with explicit IPv6 join subnet it should use explicit value not default",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd99::/48")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd01::/64")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("fd02::/112")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: &hyperv1.OVNKubernetesConfig{
+ IPv6: hyperv1.OVNIPv6Config{
+ InternalJoinSubnet: "fdaa::/64",
+ },
+ },
+ wantErr: false,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv4 config and MachineNetwork overlaps default 100.66.0.0/16 it should fail",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("100.66.0.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: true,
+ },
+ {
+ name: "When KubeVirt OVN-Kubernetes with no IPv4 config and non-overlapping networks it should succeed",
+ mn: []hyperv1.MachineNetworkEntry{{CIDR: *ipnet.MustParseCIDR("192.168.1.0/24")}},
+ cn: []hyperv1.ClusterNetworkEntry{{CIDR: *ipnet.MustParseCIDR("10.128.0.0/14")}},
+ sn: []hyperv1.ServiceNetworkEntry{{CIDR: *ipnet.MustParseCIDR("172.30.0.0/16")}},
+ networkType: hyperv1.OVNKubernetes,
+ platformType: hyperv1.KubevirtPlatform,
+ ovnConfig: nil,
+ wantErr: false,
+ },
}
for _, tt := range tests {
@@ -4000,6 +4138,9 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
Namespace: "any",
},
Spec: hyperv1.HostedClusterSpec{
+ Platform: hyperv1.PlatformSpec{
+ Type: tt.platformType,
+ },
Networking: hyperv1.ClusterNetworking{
NetworkType: tt.networkType,
MachineNetwork: tt.mn,
@@ -4009,9 +4150,7 @@ func TestValidateSliceNetworkCIDRs(t *testing.T) {
},
}
- // Set OVN configuration if provided
if tt.ovnConfig != nil {
- //OperatorConfiguration
hc.Spec.OperatorConfiguration = &hyperv1.OperatorConfiguration{
ClusterNetworkOperator: &hyperv1.ClusterNetworkOperatorSpec{
OVNKubernetesConfig: tt.ovnConfig,
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
index ee74790f5ba0..f06961b2273c 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/operator.go
@@ -4,6 +4,20 @@ import (
operatorv1 "github.com/openshift/api/operator/v1"
)
+const (
+ // KubevirtDefaultV6InternalJoinSubnet is the default IPv6 OVN join subnet
+ // for KubeVirt hosted clusters. The upstream OVN-Kubernetes default is fd98::/64,
+ // but KubeVirt guests use fd99::/64 to avoid collisions with the management
+ // cluster's join subnet when both run OVN-Kubernetes.
+ KubevirtDefaultV6InternalJoinSubnet = "fd99::/64"
+
+ // KubevirtDefaultV4InternalSubnet is the default IPv4 OVN internal subnet
+ // for KubeVirt hosted clusters. The upstream OVN-Kubernetes default gateway
+ // router LRP CIDR is 100.64.0.0/16 and the default UDNs is 100.65.0.0/16.
+ // KubeVirt guests use 100.66.0.0/16 to avoid collisions with the management cluster.
+ KubevirtDefaultV4InternalSubnet = "100.66.0.0/16"
+)
+
// +kubebuilder:validation:Enum="";Normal;Debug;Trace;TraceAll
type LogLevel string
@@ -38,6 +52,7 @@ type ClusterVersionOperatorSpec struct {
OperatorLogLevel LogLevel `json:"operatorLogLevel,omitempty"`
}
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ovnKubernetesConfig) || has(self.ovnKubernetesConfig)", message="ovnKubernetesConfig is immutable once set and cannot be removed"
type ClusterNetworkOperatorSpec struct {
// disableMultiNetwork when set to true disables the Multus CNI plugin and related components
// in the hosted cluster. This prevents the installation of multus daemon sets in the
@@ -62,7 +77,11 @@ type ClusterNetworkOperatorSpec struct {
// OVNKubernetesConfig contains OVN-Kubernetes specific configuration options.
// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L400-L471
// +kubebuilder:validation:XValidation:rule="!has(self.ipv4) || !has(self.ipv4.internalJoinSubnet) || !has(self.ipv4.internalTransitSwitchSubnet) || self.ipv4.internalJoinSubnet != self.ipv4.internalTransitSwitchSubnet", message="internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
+// +kubebuilder:validation:XValidation:rule="!has(self.ipv6) || !has(self.ipv6.internalJoinSubnet) || !has(self.ipv6.internalTransitSwitchSubnet) || self.ipv6.internalJoinSubnet != self.ipv6.internalTransitSwitchSubnet", message="ipv6 internalJoinSubnet and internalTransitSwitchSubnet must not be the same"
// +kubebuilder:validation:XValidation:rule="!has(oldSelf.mtu) || has(self.mtu)",message="mtu is immutable once set and cannot be removed"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || has(self.ipv6)", message="ipv6 is immutable once set and cannot be removed"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalJoinSubnet) || (has(self.ipv6) && has(self.ipv6.internalJoinSubnet))", message="ipv6.internalJoinSubnet cannot be removed once set"
+// +kubebuilder:validation:XValidation:rule="!has(oldSelf.ipv6) || !has(oldSelf.ipv6.internalTransitSwitchSubnet) || (has(self.ipv6) && has(self.ipv6.internalTransitSwitchSubnet))", message="ipv6.internalTransitSwitchSubnet cannot be removed once set"
// +kubebuilder:validation:MinProperties=1
type OVNKubernetesConfig struct {
// ipv4 allows users to configure IP settings for IPv4 connections. When omitted,
@@ -71,6 +90,15 @@ type OVNKubernetesConfig struct {
// +optional
IPv4 *OVNIPv4Config `json:"ipv4,omitempty"`
+ // ipv6 allows users to configure IP settings for IPv6 connections. When omitted,
+ // this means no opinions and the default configuration is used. Check individual
+ // fields within ipv6 for details of default values.
+ // For KubeVirt hosted clusters using dual-stack networking, it is recommended to
+ // set ipv6.internalJoinSubnet to a value different from the management cluster's
+ // join subnet (default fd98::/64) to avoid IPv6 routing conflicts.
+ // +optional
+ IPv6 OVNIPv6Config `json:"ipv6,omitzero"`
+
// mtu is the MTU to use for the tunnel interface on hosted cluster nodes.
// This must be 100 bytes smaller than the uplink MTU.
// When unset, the cluster-network-operator will determine the MTU automatically
@@ -126,6 +154,52 @@ type OVNIPv4Config struct {
InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
}
+// OVNIPv6Config contains IPv6-specific configuration options for OVN-Kubernetes.
+// https://github.com/openshift/api/blob/6d3c4e25a8d3aeb57ad61649d80c38cbd27d1cc8/operator/v1/types_network.go#L541-L570
+// +kubebuilder:validation:MinProperties=1
+type OVNIPv6Config struct {
+ // internalTransitSwitchSubnet is a v6 subnet in IPv6 CIDR format used internally
+ // by OVN-Kubernetes for the distributed transit switch in the OVN Interconnect
+ // architecture that connects the cluster routers on each node together to enable
+ // east west traffic. The subnet chosen should not overlap with other networks
+ // specified for OVN-Kubernetes as well as other networks used on the host.
+ // When omitted, this means no opinion and the platform is left to choose a reasonable
+ // default which is subject to change over time.
+ // The current default subnet is fd97::/64.
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be a valid IPv6 CIDR (e.g. fd97::/64). IPv4 addresses,
+ // IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ // The prefix length must be in the range /0 to /125 inclusive.
+ // This field is immutable once set.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).ip().family() == 6", message="Subnet must be in valid IPv6 CIDR format (e.g., fd97::/64)"
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).prefixLength() <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="internalTransitSwitchSubnet is immutable"
+ // +optional
+ InternalTransitSwitchSubnet string `json:"internalTransitSwitchSubnet,omitempty"`
+ // internalJoinSubnet is a v6 subnet used internally by ovn-kubernetes in case the
+ // default one is being already used by something else. It must not overlap with
+ // any other subnet being used by OpenShift or by the node network. The size of the
+ // subnet must be larger than the number of nodes.
+ // The current default value is fd98::/64.
+ // For KubeVirt hosted clusters, if this field is not set, HyperShift will
+ // automatically use fd99::/64 to avoid collisions with the management cluster's
+ // default join subnet (fd98::/64).
+ // The subnet must be large enough to accommodate one IP per node in your cluster.
+ // The value must be a valid IPv6 CIDR (e.g. fd98::/64). IPv4 addresses,
+ // IPv4-mapped IPv6 addresses, and dual-stack addresses are not permitted.
+ // The prefix length must be in the range /0 to /125 inclusive.
+ // This field is immutable once set.
+ // +kubebuilder:validation:MaxLength=48
+ // +kubebuilder:validation:MinLength=3
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).ip().family() == 6", message="Subnet must be in valid IPv6 CIDR format (e.g., fd98::/64)"
+ // +kubebuilder:validation:XValidation:rule="isCIDR(self) && cidr(self).prefixLength() <= 125", message="subnet must be in the range /0 to /125 inclusive"
+ // +kubebuilder:validation:XValidation:rule="self == oldSelf", message="internalJoinSubnet is immutable"
+ // +optional
+ InternalJoinSubnet string `json:"internalJoinSubnet,omitempty"`
+}
+
// IngressOperatorSpec is the specification of the desired behavior of the Ingress Operator.
type IngressOperatorSpec struct {
// endpointPublishingStrategy is used to publish the default ingress controller endpoints.
diff --git a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
index 1ba98f438a46..574e585b4222 100644
--- a/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/openshift/hypershift/api/hypershift/v1beta1/zz_generated.deepcopy.go
@@ -3958,6 +3958,21 @@ func (in *OVNIPv4Config) DeepCopy() *OVNIPv4Config {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *OVNIPv6Config) DeepCopyInto(out *OVNIPv6Config) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNIPv6Config.
+func (in *OVNIPv6Config) DeepCopy() *OVNIPv6Config {
+ if in == nil {
+ return nil
+ }
+ out := new(OVNIPv6Config)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = *in
@@ -3966,6 +3981,7 @@ func (in *OVNKubernetesConfig) DeepCopyInto(out *OVNKubernetesConfig) {
*out = new(OVNIPv4Config)
**out = **in
}
+ out.IPv6 = in.IPv6
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNKubernetesConfig.
|