diff --git a/api/v1alpha1/clusterconfig_types.go b/api/v1alpha1/clusterconfig_types.go index 111e1110e..97d9cb739 100644 --- a/api/v1alpha1/clusterconfig_types.go +++ b/api/v1alpha1/clusterconfig_types.go @@ -83,6 +83,10 @@ type AWSClusterConfigSpec struct { KubeadmClusterConfigSpec `json:",inline"` GenericClusterConfigSpec `json:",inline"` + // KubeProxy defines the configuration for kube-proxy. + // +kubebuilder:validation:Optional + KubeProxy *KubeProxy `json:"kubeProxy,omitempty"` + // +kubebuilder:validation:Optional Addons *AWSAddons `json:"addons,omitempty"` @@ -121,6 +125,10 @@ type DockerClusterConfigSpec struct { KubeadmClusterConfigSpec `json:",inline"` GenericClusterConfigSpec `json:",inline"` + // KubeProxy defines the configuration for kube-proxy. + // +kubebuilder:validation:Optional + KubeProxy *KubeProxy `json:"kubeProxy,omitempty"` + // +kubebuilder:validation:Optional Addons *DockerAddons `json:"addons,omitempty"` @@ -164,6 +172,10 @@ type NutanixClusterConfigSpec struct { KubeadmClusterConfigSpec `json:",inline"` GenericClusterConfigSpec `json:",inline"` + // KubeProxy defines the configuration for kube-proxy. + // +kubebuilder:validation:Optional + KubeProxy *KubeProxy `json:"kubeProxy,omitempty"` + // +kubebuilder:validation:Optional Addons *NutanixAddons `json:"addons,omitempty"` @@ -206,6 +218,10 @@ type EKSClusterConfigSpec struct { GenericClusterConfigSpec `json:",inline"` + // KubeProxy defines the configuration for kube-proxy. + // +kubebuilder:validation:Optional + KubeProxy *KubeProxy `json:"kubeProxy,omitempty"` + // +kubebuilder:validation:Optional Addons *AWSAddons `json:"addons,omitempty"` } @@ -243,10 +259,6 @@ type KubeadmClusterConfigSpec struct { // +kubebuilder:validation:Optional DNS *DNS `json:"dns,omitempty"` - // KubeProxy defines the configuration for kube-proxy. - // +kubebuilder:validation:Optional - KubeProxy *KubeProxy `json:"kubeProxy,omitempty"` - // MaxParallelImagePullsPerNode defines the maximum number of parallel image pulls performed by each kubelet. // If not set, the default value of 1 will be used. // If set to 0, the maximum number of parallel image pulls will be unlimited. @@ -425,14 +437,20 @@ const ( // KubeProxyModeNFTables indicates that kube-proxy should be installed in nftables // mode. KubeProxyModeNFTables KubeProxyMode = "nftables" + // KubeProxyModeDisabled indicates that kube-proxy should be disabled. + KubeProxyModeDisabled KubeProxyMode = "disabled" ) +// KubeProxy defines the configuration for kube-proxy. +// This struct is shared across all providers, but EKS only supports the disabled mode. +// The CRD is updated manually to reflect this. type KubeProxy struct { // Mode specifies the mode for kube-proxy: // - iptables means that kube-proxy is installed in iptables mode. // - nftables means that kube-proxy is installed in nftables mode. + // - disabled means that kube-proxy is disabled. // +kubebuilder:validation:Optional - // +kubebuilder:validation:Enum=iptables;nftables + // +kubebuilder:validation:Enum=iptables;nftables;disabled // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Value cannot be changed after cluster creation" Mode KubeProxyMode `json:"mode,omitempty"` } diff --git a/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml index fbcab348e..a7b611111 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_awsclusterconfigs.yaml @@ -716,9 +716,11 @@ spec: Mode specifies the mode for kube-proxy: - iptables means that kube-proxy is installed in iptables mode. - nftables means that kube-proxy is installed in nftables mode. + - disabled means that kube-proxy is disabled. enum: - iptables - nftables + - disabled type: string x-kubernetes-validations: - message: Value cannot be changed after cluster creation diff --git a/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml index c9d510cc0..1ab3255e5 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_dockerclusterconfigs.yaml @@ -531,9 +531,11 @@ spec: Mode specifies the mode for kube-proxy: - iptables means that kube-proxy is installed in iptables mode. - nftables means that kube-proxy is installed in nftables mode. + - disabled means that kube-proxy is disabled. enum: - iptables - nftables + - disabled type: string x-kubernetes-validations: - message: Value cannot be changed after cluster creation diff --git a/api/v1alpha1/crds/caren.nutanix.com_eksclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_eksclusterconfigs.yaml index eba7c58be..d4bb1dbea 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_eksclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_eksclusterconfigs.yaml @@ -16,397 +16,340 @@ spec: singular: eksclusterconfig scope: Namespaced versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: EKSClusterConfig is the Schema for the eksclusterconfigs API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: EKSClusterConfigSpec defines the desired state of ClusterConfig. - properties: - addons: - properties: - ccm: - description: CCM tells us to enable or disable the cloud provider - interface. - properties: - credentials: - description: A reference to the Secret for credential information - for the target Prism Central instance - properties: - secretRef: - description: A reference to the Secret containing the - credentials used by the CCM provider. - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - maxLength: 253 - minLength: 1 - type: string - required: - - name - type: object - required: - - secretRef - type: object - strategy: - default: HelmAddon - description: Addon strategy used to deploy the CCM to the - workload cluster. - enum: - - ClusterResourceSet - - HelmAddon - type: string - type: object - clusterAutoscaler: - description: ClusterAutoscaler tells us to enable or disable the - cluster-autoscaler addon. - properties: - strategy: - default: HelmAddon - description: |- - Addon strategy used to deploy cluster-autoscaler to the management cluster - targeting the workload cluster. - enum: - - ClusterResourceSet - - HelmAddon - type: string - type: object - cni: - description: CNI required for providing CNI configuration. - properties: - provider: - description: CNI provider to deploy. - enum: - - Calico - - Cilium - type: string - strategy: - default: HelmAddon - description: Addon strategy used to deploy the CNI provider - to the workload cluster. - enum: - - ClusterResourceSet - - HelmAddon - type: string - values: - description: Values contains the helm values for the CNI when - HelmAddon is the strategy. - properties: - sourceRef: - description: |- - SourceRef is an object reference to Configmap/Secret inside the same namespace - which contains inline YAML representing the values for the Helm chart. - properties: - kind: - description: Kind is the type of resource being referenced, - valid values are ('ConfigMap'). - enum: - - ConfigMap - type: string - name: - description: Name is the name of resource being referenced. - maxLength: 253 - minLength: 1 - type: string - required: - - kind - - name - type: object - type: object - required: - - provider - type: object - csi: - properties: - defaultStorage: - properties: - provider: - description: Name of the CSI Provider for the default - storage class. - enum: - - aws-ebs - - nutanix - - local-path - type: string - storageClassConfig: - description: Name of the default storage class config - the specified default provider. - maxLength: 242 - minLength: 1 - type: string - required: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: EKSClusterConfig is the Schema for the eksclusterconfigs API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: EKSClusterConfigSpec defines the desired state of ClusterConfig. + properties: + addons: + properties: + ccm: + description: CCM tells us to enable or disable the cloud provider interface. + properties: + credentials: + description: A reference to the Secret for credential information for the target Prism Central instance + properties: + secretRef: + description: A reference to the Secret containing the credentials used by the CCM provider. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + strategy: + default: HelmAddon + description: Addon strategy used to deploy the CCM to the workload cluster. + enum: + - ClusterResourceSet + - HelmAddon + type: string + type: object + clusterAutoscaler: + description: ClusterAutoscaler tells us to enable or disable the cluster-autoscaler addon. + properties: + strategy: + default: HelmAddon + description: |- + Addon strategy used to deploy cluster-autoscaler to the management cluster + targeting the workload cluster. + enum: + - ClusterResourceSet + - HelmAddon + type: string + type: object + cni: + description: CNI required for providing CNI configuration. + properties: + provider: + description: CNI provider to deploy. + enum: + - Calico + - Cilium + type: string + strategy: + default: HelmAddon + description: Addon strategy used to deploy the CNI provider to the workload cluster. + enum: + - ClusterResourceSet + - HelmAddon + type: string + values: + description: Values contains the helm values for the CNI when HelmAddon is the strategy. + properties: + sourceRef: + description: |- + SourceRef is an object reference to Configmap/Secret inside the same namespace + which contains inline YAML representing the values for the Helm chart. + properties: + kind: + description: Kind is the type of resource being referenced, valid values are ('ConfigMap'). + enum: + - ConfigMap + type: string + name: + description: Name is the name of resource being referenced. + maxLength: 253 + minLength: 1 + type: string + required: + - kind + - name + type: object + type: object + required: - provider - - storageClassConfig - type: object - providers: - properties: - aws-ebs: - properties: - credentials: - description: The reference to any secret used by the - CSI Provider. - properties: - secretRef: - description: A reference to the Secret containing - the credentials used by the CSI provider. + type: object + csi: + properties: + defaultStorage: + properties: + provider: + description: Name of the CSI Provider for the default storage class. + enum: + - aws-ebs + - nutanix + - local-path + type: string + storageClassConfig: + description: Name of the default storage class config the specified default provider. + maxLength: 242 + minLength: 1 + type: string + required: + - provider + - storageClassConfig + type: object + providers: + properties: + aws-ebs: + properties: + credentials: + description: The reference to any secret used by the CSI Provider. + properties: + secretRef: + description: A reference to the Secret containing the credentials used by the CSI provider. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + required: + - secretRef + type: object + storageClassConfigs: + additionalProperties: properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - maxLength: 253 - minLength: 1 + allowExpansion: + description: If the storage class should allow volume expanding + type: boolean + parameters: + additionalProperties: + type: string + description: Parameters passed into the storage class object. + type: object + reclaimPolicy: + default: Delete + description: PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes. + enum: + - Delete + - Retain + - Recycle type: string - required: - - name - type: object - required: - - secretRef - type: object - storageClassConfigs: - additionalProperties: - properties: - allowExpansion: - description: If the storage class should allow - volume expanding - type: boolean - parameters: - additionalProperties: + volumeBindingMode: + default: WaitForFirstConsumer + description: VolumeBindingMode indicates how PersistentVolumeClaims should be bound. + enum: + - Immediate + - WaitForFirstConsumer type: string - description: Parameters passed into the storage - class object. - type: object - reclaimPolicy: - default: Delete - description: PersistentVolumeReclaimPolicy describes - a policy for end-of-life maintenance of persistent - volumes. - enum: - - Delete - - Retain - - Recycle - type: string - volumeBindingMode: - default: WaitForFirstConsumer - description: VolumeBindingMode indicates how - PersistentVolumeClaims should be bound. - enum: - - Immediate - - WaitForFirstConsumer - type: string + type: object + description: StorageClassConfigs is a map of storage class configurations for this CSI provider. type: object - description: StorageClassConfigs is a map of storage - class configurations for this CSI provider. - type: object - strategy: - default: HelmAddon - description: Addon strategy used to deploy the CSI - provider to the workload cluster. - enum: + strategy: + default: HelmAddon + description: Addon strategy used to deploy the CSI provider to the workload cluster. + enum: + - ClusterResourceSet + - HelmAddon + type: string + required: + - storageClassConfigs + type: object + required: + - aws-ebs + type: object + snapshotController: + description: Deploy the CSI snapshot controller and associated CRDs. + properties: + strategy: + default: HelmAddon + description: Addon strategy used to deploy the snapshot controller to the workload cluster. + enum: - ClusterResourceSet - HelmAddon + type: string + type: object + required: + - defaultStorage + - providers + type: object + nfd: + description: NFD tells us to enable or disable the node feature discovery addon. + properties: + strategy: + default: HelmAddon + description: Addon strategy used to deploy Node Feature Discovery (NFD) to the workload cluster. + enum: + - ClusterResourceSet + - HelmAddon + type: string + type: object + registry: + properties: + provider: + default: CNCF Distribution + description: The OCI registry provider to deploy. + enum: + - CNCF Distribution + type: string + required: + - provider + type: object + serviceLoadBalancer: + properties: + configuration: + description: Configuration for the chosen ServiceLoadBalancer provider. + properties: + addressRanges: + description: |- + AddressRanges is a list of IPv4 address ranges the + provider uses to choose an address for a load balancer. + items: + description: AddressRange defines an IPv4 range. + properties: + end: + format: ipv4 + type: string + start: + format: ipv4 + type: string + required: + - end + - start + type: object + maxItems: 10 + minItems: 1 + type: array + required: + - addressRanges + type: object + provider: + description: |- + The LoadBalancer-type Service provider to deploy. Not required in infrastructures where + the CCM acts as the provider. + enum: + - MetalLB + type: string + required: + - provider + type: object + type: object + eks: + description: EKS cluster configuration. + properties: + identityRef: + description: |- + IdentityRef is a reference to an identity to be used when reconciling the managed control plane. + If no identity is specified, the default identity for this controller will be used. + properties: + kind: + description: Kind of the identity. + enum: + - AWSClusterControllerIdentity + - AWSClusterRoleIdentity + - AWSClusterStaticIdentity + type: string + name: + description: Name of the identity. + minLength: 1 + type: string + required: + - kind + - name + type: object + network: + description: AWS network configuration. + properties: + subnets: + description: AWS Subnet configuration. + items: + description: SubnetSpec configures an AWS Subnet. + properties: + id: + description: Existing Subnet ID to use for the cluster. + format: ^subnet-[0-9a-f]{8}(?:[0-9a-f]{9})?$ type: string required: - - storageClassConfigs + - id type: object - required: - - aws-ebs - type: object - snapshotController: - description: Deploy the CSI snapshot controller and associated - CRDs. - properties: - strategy: - default: HelmAddon - description: Addon strategy used to deploy the snapshot - controller to the workload cluster. - enum: - - ClusterResourceSet - - HelmAddon - type: string - type: object - required: - - defaultStorage - - providers - type: object - nfd: - description: NFD tells us to enable or disable the node feature - discovery addon. - properties: - strategy: - default: HelmAddon - description: Addon strategy used to deploy Node Feature Discovery - (NFD) to the workload cluster. - enum: - - ClusterResourceSet - - HelmAddon - type: string - type: object - registry: - properties: - provider: - default: CNCF Distribution - description: The OCI registry provider to deploy. - enum: - - CNCF Distribution - type: string - required: - - provider - type: object - serviceLoadBalancer: - properties: - configuration: - description: Configuration for the chosen ServiceLoadBalancer - provider. - properties: - addressRanges: - description: |- - AddressRanges is a list of IPv4 address ranges the - provider uses to choose an address for a load balancer. - items: - description: AddressRange defines an IPv4 range. - properties: - end: - format: ipv4 - type: string - start: - format: ipv4 - type: string - required: - - end - - start - type: object - maxItems: 10 - minItems: 1 - type: array - required: - - addressRanges - type: object - provider: - description: |- - The LoadBalancer-type Service provider to deploy. Not required in infrastructures where - the CCM acts as the provider. - enum: - - MetalLB - type: string - required: - - provider - type: object - type: object - eks: - description: EKS cluster configuration. - properties: - identityRef: - description: |- - IdentityRef is a reference to an identity to be used when reconciling the managed control plane. - If no identity is specified, the default identity for this controller will be used. - properties: - kind: - description: Kind of the identity. - enum: - - AWSClusterControllerIdentity - - AWSClusterRoleIdentity - - AWSClusterStaticIdentity - type: string - name: - description: Name of the identity. - minLength: 1 - type: string - required: - - kind - - name - type: object - network: - description: AWS network configuration. - properties: - subnets: - description: AWS Subnet configuration. - items: - description: SubnetSpec configures an AWS Subnet. + maxItems: 10 + type: array + vpc: properties: id: - description: Existing Subnet ID to use for the cluster. - format: ^subnet-[0-9a-f]{8}(?:[0-9a-f]{9})?$ + description: Existing VPC ID to use for the cluster. + format: ^vpc-[0-9a-f]{8}(?:[0-9a-f]{9})?$ type: string required: - - id + - id type: object - maxItems: 10 - type: array - vpc: - properties: - id: - description: Existing VPC ID to use for the cluster. - format: ^vpc-[0-9a-f]{8}(?:[0-9a-f]{9})?$ - type: string - required: - - id - type: object - type: object - region: - description: AWS region to create cluster in. - maxLength: 16 - minLength: 4 - type: string - type: object - globalImageRegistryMirror: - description: GlobalImageRegistryMirror sets default mirror configuration - for all the image registries. - properties: - credentials: - description: Credentials and CA certificate for the image registry - mirror - properties: - secretRef: - description: |- - A reference to the Secret containing the registry credentials and optional CA certificate - using the keys `username`, `password` and `ca.crt`. - This credentials Secret is not required for some registries, e.g. ECR. - properties: - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - maxLength: 253 - minLength: 1 - type: string - required: - - name - type: object - type: object - url: - description: Registry mirror URL. - format: uri - pattern: ^https?:// - type: string - required: - - url - type: object - imageRegistries: - items: + type: object + region: + description: AWS region to create cluster in. + maxLength: 16 + minLength: 4 + type: string + type: object + globalImageRegistryMirror: + description: GlobalImageRegistryMirror sets default mirror configuration for all the image registries. properties: credentials: - description: Credentials and CA certificate for the image registry + description: Credentials and CA certificate for the image registry mirror properties: secretRef: description: |- @@ -422,101 +365,144 @@ spec: minLength: 1 type: string required: - - name + - name type: object type: object url: - description: Registry URL. + description: Registry mirror URL. format: uri pattern: ^https?:// type: string required: - - url + - url type: object - maxItems: 32 - type: array - ntp: - description: NTP defines the NTP configuration for the cluster. - properties: - servers: - description: Servers is a list of NTP servers to use for time - synchronization. - items: - maxLength: 253 - type: string - maxItems: 16 - minItems: 1 - type: array - required: - - servers - type: object - proxy: - description: HTTPProxy required for providing proxy configuration. - properties: - additionalNo: - description: |- - AdditionalNo Proxy list that will be added to the automatically calculated - values that will apply no_proxy configuration for cluster internal network. - Default values: localhost,127.0.0.1,,,kubernetes - ,kubernetes.default,.svc,.svc. - items: - maxLength: 253 - minLength: 1 - type: string - maxItems: 128 - type: array - http: - description: HTTP proxy value. - maxLength: 2048 - minLength: 1 - type: string - https: - description: HTTPS proxy value. - maxLength: 2048 - minLength: 1 - type: string - type: object - users: - items: - description: User defines the input for a generated user in cloud-init. + imageRegistries: + items: + properties: + credentials: + description: Credentials and CA certificate for the image registry + properties: + secretRef: + description: |- + A reference to the Secret containing the registry credentials and optional CA certificate + using the keys `username`, `password` and `ca.crt`. + This credentials Secret is not required for some registries, e.g. ECR. + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + maxLength: 253 + minLength: 1 + type: string + required: + - name + type: object + type: object + url: + description: Registry URL. + format: uri + pattern: ^https?:// + type: string + required: + - url + type: object + maxItems: 32 + type: array + kubeProxy: + description: KubeProxy defines the configuration for kube-proxy. properties: - hashedPassword: + mode: description: |- - HashedPassword is a hashed password for the user, formatted as described - by the crypt(5) man page. See your distribution's documentation for - instructions to create a hashed password. - An empty string is not marshalled, because it is not a valid value. - maxLength: 106 - minLength: 1 - type: string - name: - description: Name specifies the user name. - maxLength: 256 + Mode specifies the mode for kube-proxy in EKS: - disabled means that kube-proxy is disabled (only supported mode for EKS). + enum: + - disabled type: string - sshAuthorizedKeys: - description: |- - SSHAuthorizedKeys is a list of public SSH keys to write to the - machine. Use the corresponding private SSH keys to authenticate. See SSH - documentation for instructions to create a key pair. + x-kubernetes-validations: + - message: Value cannot be changed after cluster creation + rule: self == oldSelf + type: object + ntp: + description: NTP defines the NTP configuration for the cluster. + properties: + servers: + description: Servers is a list of NTP servers to use for time synchronization. items: - maxLength: 256 + maxLength: 253 type: string - maxItems: 32 + maxItems: 16 + minItems: 1 type: array - sudo: + required: + - servers + type: object + proxy: + description: HTTPProxy required for providing proxy configuration. + properties: + additionalNo: description: |- - Sudo is a sudo user specification, formatted as described in the sudo - documentation. - An empty string is not marshalled, because it is not a valid value. - maxLength: 1024 + AdditionalNo Proxy list that will be added to the automatically calculated + values that will apply no_proxy configuration for cluster internal network. + Default values: localhost,127.0.0.1,,,kubernetes + ,kubernetes.default,.svc,.svc. + items: + maxLength: 253 + minLength: 1 + type: string + maxItems: 128 + type: array + http: + description: HTTP proxy value. + maxLength: 2048 + minLength: 1 + type: string + https: + description: HTTPS proxy value. + maxLength: 2048 minLength: 1 type: string - required: - - name type: object - maxItems: 32 - type: array - type: object - type: object - served: true - storage: true + users: + items: + description: User defines the input for a generated user in cloud-init. + properties: + hashedPassword: + description: |- + HashedPassword is a hashed password for the user, formatted as described + by the crypt(5) man page. See your distribution's documentation for + instructions to create a hashed password. + An empty string is not marshalled, because it is not a valid value. + maxLength: 106 + minLength: 1 + type: string + name: + description: Name specifies the user name. + maxLength: 256 + type: string + sshAuthorizedKeys: + description: |- + SSHAuthorizedKeys is a list of public SSH keys to write to the + machine. Use the corresponding private SSH keys to authenticate. See SSH + documentation for instructions to create a key pair. + items: + maxLength: 256 + type: string + maxItems: 32 + type: array + sudo: + description: |- + Sudo is a sudo user specification, formatted as described in the sudo + documentation. + An empty string is not marshalled, because it is not a valid value. + maxLength: 1024 + minLength: 1 + type: string + required: + - name + type: object + maxItems: 32 + type: array + type: object + type: object + served: true + storage: true diff --git a/api/v1alpha1/crds/caren.nutanix.com_kubeadmclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_kubeadmclusterconfigs.yaml index 4227361a7..84ded9f23 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_kubeadmclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_kubeadmclusterconfigs.yaml @@ -112,22 +112,6 @@ spec: type: string type: object type: object - kubeProxy: - description: KubeProxy defines the configuration for kube-proxy. - properties: - mode: - description: |- - Mode specifies the mode for kube-proxy: - - iptables means that kube-proxy is installed in iptables mode. - - nftables means that kube-proxy is installed in nftables mode. - enum: - - iptables - - nftables - type: string - x-kubernetes-validations: - - message: Value cannot be changed after cluster creation - rule: self == oldSelf - type: object kubernetesImageRepository: description: Sets the Kubernetes image repository used for the KubeadmControlPlane. maxLength: 2048 diff --git a/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml b/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml index a95bb73c2..62000b4ca 100644 --- a/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml +++ b/api/v1alpha1/crds/caren.nutanix.com_nutanixclusterconfigs.yaml @@ -719,9 +719,11 @@ spec: Mode specifies the mode for kube-proxy: - iptables means that kube-proxy is installed in iptables mode. - nftables means that kube-proxy is installed in nftables mode. + - disabled means that kube-proxy is disabled. enum: - iptables - nftables + - disabled type: string x-kubernetes-validations: - message: Value cannot be changed after cluster creation diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index bc30c1310..8aad3e929 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -159,6 +159,11 @@ func (in *AWSClusterConfigSpec) DeepCopyInto(out *AWSClusterConfigSpec) { } in.KubeadmClusterConfigSpec.DeepCopyInto(&out.KubeadmClusterConfigSpec) in.GenericClusterConfigSpec.DeepCopyInto(&out.GenericClusterConfigSpec) + if in.KubeProxy != nil { + in, out := &in.KubeProxy, &out.KubeProxy + *out = new(KubeProxy) + **out = **in + } if in.Addons != nil { in, out := &in.Addons, &out.Addons *out = new(AWSAddons) @@ -872,6 +877,11 @@ func (in *DockerClusterConfigSpec) DeepCopyInto(out *DockerClusterConfigSpec) { } in.KubeadmClusterConfigSpec.DeepCopyInto(&out.KubeadmClusterConfigSpec) in.GenericClusterConfigSpec.DeepCopyInto(&out.GenericClusterConfigSpec) + if in.KubeProxy != nil { + in, out := &in.KubeProxy, &out.KubeProxy + *out = new(KubeProxy) + **out = **in + } if in.Addons != nil { in, out := &in.Addons, &out.Addons *out = new(DockerAddons) @@ -1039,6 +1049,11 @@ func (in *EKSClusterConfigSpec) DeepCopyInto(out *EKSClusterConfigSpec) { (*in).DeepCopyInto(*out) } in.GenericClusterConfigSpec.DeepCopyInto(&out.GenericClusterConfigSpec) + if in.KubeProxy != nil { + in, out := &in.KubeProxy, &out.KubeProxy + *out = new(KubeProxy) + **out = **in + } if in.Addons != nil { in, out := &in.Addons, &out.Addons *out = new(AWSAddons) @@ -1545,11 +1560,6 @@ func (in *KubeadmClusterConfigSpec) DeepCopyInto(out *KubeadmClusterConfigSpec) *out = new(DNS) (*in).DeepCopyInto(*out) } - if in.KubeProxy != nil { - in, out := &in.KubeProxy, &out.KubeProxy - *out = new(KubeProxy) - **out = **in - } if in.MaxParallelImagePullsPerNode != nil { in, out := &in.MaxParallelImagePullsPerNode, &out.MaxParallelImagePullsPerNode *out = new(int32) @@ -1772,6 +1782,11 @@ func (in *NutanixClusterConfigSpec) DeepCopyInto(out *NutanixClusterConfigSpec) } in.KubeadmClusterConfigSpec.DeepCopyInto(&out.KubeadmClusterConfigSpec) in.GenericClusterConfigSpec.DeepCopyInto(&out.GenericClusterConfigSpec) + if in.KubeProxy != nil { + in, out := &in.KubeProxy, &out.KubeProxy + *out = new(KubeProxy) + **out = **in + } if in.Addons != nil { in, out := &in.Addons, &out.Addons *out = new(NutanixAddons) diff --git a/api/variables/aggregate_types.go b/api/variables/aggregate_types.go index 05eb5854a..267fde218 100644 --- a/api/variables/aggregate_types.go +++ b/api/variables/aggregate_types.go @@ -25,6 +25,8 @@ type ClusterConfigSpec struct { carenv1.KubeadmClusterConfigSpec `json:",inline"` carenv1.GenericClusterConfigSpec `json:",inline"` + KubeProxy *carenv1.KubeProxy `json:"kubeProxy,omitempty"` + Addons *Addons `json:"addons,omitempty"` ControlPlane *ControlPlaneSpec `json:"controlPlane,omitempty"` diff --git a/api/variables/getters.go b/api/variables/getters.go index 884cfbfc6..c95556d53 100644 --- a/api/variables/getters.go +++ b/api/variables/getters.go @@ -27,3 +27,29 @@ func RegistryAddon(cluster *clusterv1.Cluster) (*carenv1.RegistryAddon, error) { return spec.Addons.Registry, nil } + +// KubeProxyMode retrieves the kube-proxy mode from the cluster's topology variables. +// Returns nil if the kube-proxy mode is not defined. +func KubeProxyMode(cluster *clusterv1.Cluster) (*carenv1.KubeProxyMode, error) { + spec, err := UnmarshalClusterConfigVariable(cluster.Spec.Topology.Variables) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal cluster variable: %w", err) + } + if spec == nil { + return nil, nil + } + if spec.KubeProxy == nil { + return nil, nil + } + + return &spec.KubeProxy.Mode, nil +} + +// KubeProxyIsDisabled returns true if kube-proxy mode from the cluster's topology variables is disabled. +func KubeProxyIsDisabled(cluster *clusterv1.Cluster) (bool, error) { + mode, err := KubeProxyMode(cluster) + if err != nil { + return false, err + } + return mode != nil && *mode == carenv1.KubeProxyModeDisabled, nil +} diff --git a/common/pkg/capi/utils/annotations.go b/common/pkg/capi/utils/annotations.go deleted file mode 100644 index bfe87966d..000000000 --- a/common/pkg/capi/utils/annotations.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2025 Nutanix. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -package utils - -import ( - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" - controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" -) - -// ShouldSkipKubeProxy returns true if the cluster is configured to skip kube proxy installation. -func ShouldSkipKubeProxy(cluster *clusterv1.Cluster) bool { - if cluster.Spec.Topology != nil { - _, isSkipKubeProxy := cluster.Spec.Topology.ControlPlane.Metadata.Annotations[controlplanev1.SkipKubeProxyAnnotation] - return isSkipKubeProxy - } - return false -} diff --git a/docs/content/customization/generic/kube-proxy-mode.md b/docs/content/customization/generic/kube-proxy-mode.md index aef63adfd..010f3e466 100644 --- a/docs/content/customization/generic/kube-proxy-mode.md +++ b/docs/content/customization/generic/kube-proxy-mode.md @@ -60,10 +60,11 @@ metadata: name: spec: topology: - controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" + variables: + - name: clusterConfig + value: + kubeProxy: + mode: disabled ``` Applying this configuration will result in the following configuration being applied: diff --git a/examples/capi-quick-start/aws-cluster-cilium-helm-addon.yaml b/examples/capi-quick-start/aws-cluster-cilium-helm-addon.yaml index 80f8f314b..dad3d17a5 100644 --- a/examples/capi-quick-start/aws-cluster-cilium-helm-addon.yaml +++ b/examples/capi-quick-start/aws-cluster-cilium-helm-addon.yaml @@ -16,9 +16,6 @@ spec: topology: class: aws-quick-start controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" replicas: ${CONTROL_PLANE_MACHINE_COUNT} variables: - name: clusterConfig @@ -52,6 +49,8 @@ spec: encryptionAtRest: providers: - aescbc: {} + kubeProxy: + mode: disabled - name: workerConfig value: aws: diff --git a/examples/capi-quick-start/eks-cluster.yaml b/examples/capi-quick-start/eks-cluster.yaml index c61c90414..cdb62e242 100644 --- a/examples/capi-quick-start/eks-cluster.yaml +++ b/examples/capi-quick-start/eks-cluster.yaml @@ -62,10 +62,7 @@ metadata: spec: topology: class: eks-quick-start - controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" + controlPlane: {} variables: - name: clusterConfig value: @@ -89,6 +86,8 @@ spec: nfd: {} eks: region: us-west-2 + kubeProxy: + mode: disabled version: ${KUBERNETES_VERSION} workers: machineDeployments: diff --git a/examples/capi-quick-start/nutanix-cluster-cilium-helm-addon.yaml b/examples/capi-quick-start/nutanix-cluster-cilium-helm-addon.yaml index 203b9df81..094f84c1b 100644 --- a/examples/capi-quick-start/nutanix-cluster-cilium-helm-addon.yaml +++ b/examples/capi-quick-start/nutanix-cluster-cilium-helm-addon.yaml @@ -57,9 +57,7 @@ spec: topology: class: nutanix-quick-start controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" + metadata: {} replicas: ${CONTROL_PLANE_MACHINE_COUNT} variables: - name: clusterConfig @@ -124,6 +122,8 @@ spec: secretRef: name: ${CLUSTER_NAME}-dockerhub-credentials url: https://docker.io + kubeProxy: + mode: disabled nutanix: controlPlaneEndpoint: host: ${CONTROL_PLANE_ENDPOINT_IP} diff --git a/examples/capi-quick-start/nutanix-cluster-with-failuredomains-cilium-helm-addon.yaml b/examples/capi-quick-start/nutanix-cluster-with-failuredomains-cilium-helm-addon.yaml index 7bb37b1d1..0ba4c8594 100644 --- a/examples/capi-quick-start/nutanix-cluster-with-failuredomains-cilium-helm-addon.yaml +++ b/examples/capi-quick-start/nutanix-cluster-with-failuredomains-cilium-helm-addon.yaml @@ -93,9 +93,7 @@ spec: topology: class: nutanix-quick-start controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" + metadata: {} replicas: ${CONTROL_PLANE_MACHINE_COUNT} variables: - name: clusterConfig @@ -158,6 +156,8 @@ spec: secretRef: name: ${CLUSTER_NAME}-dockerhub-credentials url: https://docker.io + kubeProxy: + mode: disabled nutanix: controlPlaneEndpoint: host: ${CONTROL_PLANE_ENDPOINT_IP} diff --git a/hack/examples/patches/skip-kube-proxy.yaml b/hack/examples/patches/skip-kube-proxy.yaml index ac2a8781f..b6347282e 100644 --- a/hack/examples/patches/skip-kube-proxy.yaml +++ b/hack/examples/patches/skip-kube-proxy.yaml @@ -1,13 +1,7 @@ # Copyright 2025 Nutanix. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -apiVersion: cluster.x-k8s.io/v1beta1 -kind: Cluster -metadata: - name: not-used -spec: - topology: - controlPlane: - metadata: - annotations: - controlplane.cluster.x-k8s.io/skip-kube-proxy: "" +- op: "add" + path: "/spec/topology/variables/0/value/kubeProxy" + value: + mode: disabled diff --git a/make/go.mk b/make/go.mk index 6c0761abf..3588b8f99 100644 --- a/make/go.mk +++ b/make/go.mk @@ -248,6 +248,11 @@ go-generate: ; $(info $(M) running go generate) -exec yq --inplace \ '(.. | select(has("memorySize") or has("systemDiskSize")) | (.memorySize?, .systemDiskSize?) | del(.anyOf)) += {"type": "string"}' \ {} \; + # Update the EKSClusterConfig CRD to only allow the disabled kube-proxy mode. + # The underlying struct is shared across all providers and its not possible set it using the annotation. + yq --inplace \ + '.spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.kubeProxy.properties.mode |= (.description = "Mode specifies the mode for kube-proxy in EKS: - disabled means that kube-proxy is disabled (only supported mode for EKS)." | .enum = ["disabled"])' \ + api/v1alpha1/crds/caren.nutanix.com_eksclusterconfigs.yaml .PHONY: govulncheck govulncheck: ## Runs govulncheck for all modules in repository diff --git a/pkg/handlers/generic/lifecycle/cni/cilium/handler.go b/pkg/handlers/generic/lifecycle/cni/cilium/handler.go index 4c751eb86..287fda85f 100644 --- a/pkg/handlers/generic/lifecycle/cni/cilium/handler.go +++ b/pkg/handlers/generic/lifecycle/cni/cilium/handler.go @@ -21,10 +21,10 @@ import ( ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + apivariables "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables" commonhandlers "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/lifecycle" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables" - capiutils "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/addons" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/config" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/options" @@ -264,8 +264,13 @@ func runApply( // It is possible to disable kube-proxy and migrate to Cilium's kube-proxy replacement feature in a running cluster. // In this case, we need to wait for Cilium to be restarted with new configuration and then cleanup kube-proxy. - // If skip kube-proxy is not set, return early. - if !capiutils.ShouldSkipKubeProxy(cluster) { + // If kube-proxy is not disabled, return early. + kubeProxyIsDisabled, err := apivariables.KubeProxyIsDisabled(cluster) + if err != nil { + return fmt.Errorf("failed to get kube proxy mode: %w", err) + } + + if !kubeProxyIsDisabled { return nil } diff --git a/pkg/handlers/generic/lifecycle/cni/cilium/handler_integration_test.go b/pkg/handlers/generic/lifecycle/cni/cilium/handler_integration_test.go index 43408f396..487c0bfac 100644 --- a/pkg/handlers/generic/lifecycle/cni/cilium/handler_integration_test.go +++ b/pkg/handlers/generic/lifecycle/cni/cilium/handler_integration_test.go @@ -19,9 +19,10 @@ import ( clientgoscheme "k8s.io/client-go/kubernetes/scheme" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/controllers/remote" - controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1" + apivariables "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/addons" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/test/helpers" ) @@ -38,7 +39,7 @@ var _ = Describe("Test runApply", func() { cluster, remoteClient := setupTestCluster(ctx, c) strategy := addons.NewTestStrategy(nil) - By("Should not delete kube-proxy when skip kube-proxy is not set") + By("Should not delete kube-proxy when it is not disabled") err = runApply(ctx, c, cluster, strategy, cluster.Namespace, logr.Discard()) Expect(err).To(BeNil()) @@ -71,10 +72,10 @@ var _ = Describe("Test runApply", func() { Expect(err).To(BeNil()) Expect(configMap).ToNot(BeNil()) - By("Should not delete kube-proxy when Cilium DaemonSet is not updated") - cluster.Spec.Topology.ControlPlane.Metadata.Annotations = map[string]string{ - controlplanev1.SkipKubeProxyAnnotation: "", - } + By("Should delete kube-proxy when kube-proxy is disabled") + err = disableKubeProxy(cluster) + Expect(err).To(BeNil()) + // Speed up the test. waitTimeout = 1 * time.Second err = runApply(ctx, c, cluster, strategy, cluster.Namespace, logr.Discard()) @@ -264,3 +265,27 @@ func setupTestCluster( return cluster, remoteClient } + +func disableKubeProxy(cluster *clusterv1.Cluster) error { + spec, err := apivariables.UnmarshalClusterConfigVariable(cluster.Spec.Topology.Variables) + if err != nil { + return fmt.Errorf("failed to unmarshal cluster variable: %w", err) + } + + if spec == nil { + spec = &apivariables.ClusterConfigSpec{} + } + if spec.KubeProxy == nil { + spec.KubeProxy = &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeDisabled, + } + } + + variable, err := apivariables.MarshalToClusterVariable(v1alpha1.ClusterConfigVariableName, spec) + if err != nil { + return fmt.Errorf("failed to marshal cluster variable: %w", err) + } + cluster.Spec.Topology.Variables = apivariables.UpdateClusterVariable(variable, cluster.Spec.Topology.Variables) + + return nil +} diff --git a/pkg/handlers/generic/lifecycle/cni/cilium/template.go b/pkg/handlers/generic/lifecycle/cni/cilium/template.go index 110184203..f7337823b 100644 --- a/pkg/handlers/generic/lifecycle/cni/cilium/template.go +++ b/pkg/handlers/generic/lifecycle/cni/cilium/template.go @@ -10,11 +10,16 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" - capiutils "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils" + apivariables "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/variables" ) // templateValues enables kube-proxy replacement when kube-proxy is disabled. func templateValues(cluster *clusterv1.Cluster, text string) (string, error) { + kubeProxyIsDisabled, err := apivariables.KubeProxyIsDisabled(cluster) + if err != nil { + return "", fmt.Errorf("failed to check if kube-proxy is disabled: %w", err) + } + ciliumTemplate, err := template.New("").Parse(text) if err != nil { return "", fmt.Errorf("failed to parse template: %w", err) @@ -24,9 +29,9 @@ func templateValues(cluster *clusterv1.Cluster, text string) (string, error) { EnableKubeProxyReplacement bool } - // Assume when kube-proxy is skipped, we should enable Cilium's kube-proxy replacement feature. + // Assume when kube-proxy is disabled, we should enable Cilium's kube-proxy replacement feature. templateInput := input{ - EnableKubeProxyReplacement: capiutils.ShouldSkipKubeProxy(cluster), + EnableKubeProxyReplacement: kubeProxyIsDisabled, } var b bytes.Buffer diff --git a/pkg/handlers/generic/mutation/kubeproxymode/inject.go b/pkg/handlers/generic/mutation/kubeproxymode/inject.go index 19e318757..407b905cf 100644 --- a/pkg/handlers/generic/mutation/kubeproxymode/inject.go +++ b/pkg/handlers/generic/mutation/kubeproxymode/inject.go @@ -26,7 +26,6 @@ import ( "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/patches/selectors" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables" - capiutils "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils" ) const ( @@ -84,12 +83,6 @@ func (h *kubeProxyMode) Mutate( "holderRef", holderRef, ) - cluster, err := clusterGetter(ctx) - if err != nil { - log.Error(err, "failed to get cluster for kube proxy mode mutation") - return fmt.Errorf("failed to get cluster for kube proxy mode mutation: %w", err) - } - kubeProxyMode, err := variables.Get[v1alpha1.KubeProxyMode]( vars, h.variableName, @@ -108,10 +101,8 @@ func (h *kubeProxyMode) Mutate( kubeProxyMode, ) - isSkipProxy := capiutils.ShouldSkipKubeProxy(cluster) - - if kubeProxyMode == "" && !isSkipProxy { - log.V(5).Info("kube proxy mode is not set or skipped, skipping mutation") + if kubeProxyMode == "" { + log.V(5).Info("kube proxy mode is not set, skipping mutation") return nil } @@ -127,11 +118,10 @@ func (h *kubeProxyMode) Mutate( "patchedObjectName", client.ObjectKeyFromObject(obj), ).Info("adding kube proxy mode to control plane kubeadm config spec") - if isSkipProxy { - log.Info( - "cluster controlplane contains controlplane.cluster.x-k8s.io/skip-kube-proxy annotation, " + - "skipping kube-proxy addon", - ) + switch kubeProxyMode { + case v1alpha1.KubeProxyModeDisabled: + log.Info("disabling kube-proxy addon") + if obj.Spec.Template.Spec.KubeadmConfigSpec.InitConfiguration == nil { obj.Spec.Template.Spec.KubeadmConfigSpec.InitConfiguration = &bootstrapv1.InitConfiguration{} } @@ -144,9 +134,6 @@ func (h *kubeProxyMode) Mutate( } return nil - } - - switch kubeProxyMode { case v1alpha1.KubeProxyModeIPTables, v1alpha1.KubeProxyModeNFTables: return addKubeProxyConfigFileAndCommand(obj, kubeProxyMode) default: @@ -175,11 +162,8 @@ func (h *kubeProxyMode) Mutate( "patchedObjectName", client.ObjectKeyFromObject(obj), ).Info("adding kube proxy mode to AWSManagedControlPlaneTemplate spec") - if isSkipProxy { - log.Info( - "cluster controlplane contains controlplane.cluster.x-k8s.io/skip-kube-proxy annotation, " + - "skipping kube-proxy addon", - ) + if kubeProxyMode == v1alpha1.KubeProxyModeDisabled { + log.Info("disabling kube-proxy addon") obj.Spec.Template.Spec.KubeProxy.Disable = true } diff --git a/pkg/handlers/generic/mutation/kubeproxymode/inject_test.go b/pkg/handlers/generic/mutation/kubeproxymode/inject_test.go index 0ad612329..5cb20aa10 100644 --- a/pkg/handlers/generic/mutation/kubeproxymode/inject_test.go +++ b/pkg/handlers/generic/mutation/kubeproxymode/inject_test.go @@ -14,7 +14,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" - controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/api/v1alpha1" @@ -51,7 +50,11 @@ var _ = Describe("Generate kube proxy mode patches", func() { Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, - v1alpha1.AWSClusterConfigSpec{}, + v1alpha1.AWSClusterConfigSpec{ + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeDisabled, + }, + }, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -69,19 +72,6 @@ var _ = Describe("Generate kube proxy mode patches", func() { clusterv1.ProviderNameLabel: "aws", }, }, - Spec: clusterv1.ClusterSpec{ - Topology: &clusterv1.Topology{ - Version: "dummy-version", - Class: "dummy-class", - ControlPlane: clusterv1.ControlPlaneTopology{ - Metadata: clusterv1.ObjectMeta{ - Annotations: map[string]string{ - controlplanev1.SkipKubeProxyAnnotation: "", - }, - }, - }, - }, - }, }, }, { patchTest: capitest.PatchTestDef{ @@ -89,7 +79,11 @@ var _ = Describe("Generate kube proxy mode patches", func() { Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, - v1alpha1.DockerClusterConfigSpec{}, + v1alpha1.DockerClusterConfigSpec{ + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeDisabled, + }, + }, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -107,19 +101,6 @@ var _ = Describe("Generate kube proxy mode patches", func() { clusterv1.ProviderNameLabel: "docker", }, }, - Spec: clusterv1.ClusterSpec{ - Topology: &clusterv1.Topology{ - Version: "dummy-version", - Class: "dummy-class", - ControlPlane: clusterv1.ControlPlaneTopology{ - Metadata: clusterv1.ObjectMeta{ - Annotations: map[string]string{ - controlplanev1.SkipKubeProxyAnnotation: "", - }, - }, - }, - }, - }, }, }, { patchTest: capitest.PatchTestDef{ @@ -127,7 +108,11 @@ var _ = Describe("Generate kube proxy mode patches", func() { Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, - v1alpha1.NutanixClusterConfigSpec{}, + v1alpha1.NutanixClusterConfigSpec{ + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeDisabled, + }, + }, ), }, RequestItem: request.NewKubeadmControlPlaneTemplateRequestItem(""), @@ -145,19 +130,6 @@ var _ = Describe("Generate kube proxy mode patches", func() { clusterv1.ProviderNameLabel: "nutanix", }, }, - Spec: clusterv1.ClusterSpec{ - Topology: &clusterv1.Topology{ - Version: "dummy-version", - Class: "dummy-class", - ControlPlane: clusterv1.ControlPlaneTopology{ - Metadata: clusterv1.ObjectMeta{ - Annotations: map[string]string{ - controlplanev1.SkipKubeProxyAnnotation: "", - }, - }, - }, - }, - }, }, }, { patchTest: capitest.PatchTestDef{ @@ -165,11 +137,9 @@ var _ = Describe("Generate kube proxy mode patches", func() { Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, - v1alpha1.AWSClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeIPTables, - }, + v1alpha1.NutanixClusterConfigSpec{ + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeIPTables, }, }, ), @@ -215,10 +185,8 @@ mode: iptables capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, v1alpha1.AWSClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeIPTables, - }, + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeIPTables, }, }, ), @@ -264,10 +232,8 @@ mode: iptables capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, v1alpha1.DockerClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeIPTables, - }, + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeIPTables, }, }, ), @@ -313,10 +279,8 @@ mode: iptables capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, v1alpha1.NutanixClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeNFTables, - }, + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeNFTables, }, }, ), @@ -362,10 +326,8 @@ mode: nftables capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, v1alpha1.AWSClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeNFTables, - }, + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeNFTables, }, }, ), @@ -411,10 +373,8 @@ mode: nftables capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, v1alpha1.DockerClusterConfigSpec{ - KubeadmClusterConfigSpec: v1alpha1.KubeadmClusterConfigSpec{ - KubeProxy: &v1alpha1.KubeProxy{ - Mode: v1alpha1.KubeProxyModeNFTables, - }, + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeNFTables, }, }, ), @@ -459,7 +419,11 @@ mode: nftables Vars: []runtimehooksv1.Variable{ capitest.VariableWithValue( v1alpha1.ClusterConfigVariableName, - v1alpha1.EKSClusterConfigSpec{}, + v1alpha1.EKSClusterConfigSpec{ + KubeProxy: &v1alpha1.KubeProxy{ + Mode: v1alpha1.KubeProxyModeDisabled, + }, + }, ), }, RequestItem: testutils.NewEKSControlPlaneRequestItem("1234"), @@ -477,19 +441,6 @@ mode: nftables clusterv1.ProviderNameLabel: "eks", }, }, - Spec: clusterv1.ClusterSpec{ - Topology: &clusterv1.Topology{ - Version: "dummy-version", - Class: "dummy-class", - ControlPlane: clusterv1.ControlPlaneTopology{ - Metadata: clusterv1.ObjectMeta{ - Annotations: map[string]string{ - controlplanev1.SkipKubeProxyAnnotation: "", - }, - }, - }, - }, - }, }, }}