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. + |
+
(Appears on: @@ -44721,6 +44788,25 @@ fields within ipv4 for details of default values.
ipv6,omitzero
+
+
+OVNIPv6Config
+
+
+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
+(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. + |
+
(Appears on: @@ -14273,6 +14340,25 @@ fields within ipv4 for details of default values.
ipv6,omitzero
+
+
+OVNIPv6Config
+
+
+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.