diff --git a/.golangci.yml b/.golangci.yml index 1225427832cc..9ada4eaf3cd7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,6 +7,8 @@ run: skip-files: - "zz_generated.*\\.go$" - "vendored_openapi\\.go$" + # We don't want to invest time to fix new linter findings in old API types. + - "internal/apis/.*" allow-parallel-runners: true linters: @@ -115,26 +117,36 @@ linters-settings: - pkg: sigs.k8s.io/controller-runtime alias: ctrl # CABPK + - pkg: sigs.k8s.io/cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3 + alias: bootstrapv1alpha3 - pkg: sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4 alias: bootstrapv1alpha4 - pkg: sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1 alias: bootstrapv1 # KCP + - pkg: sigs.k8s.io/cluster-api/internal/apis/controlplane/kubeadm/v1alpha3 + alias: controlplanev1alpha3 - pkg: sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha4 alias: controlplanev1alpha4 - pkg: sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1 alias: controlplanev1 # CAPI + - pkg: sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3 + alias: clusterv1alpha3 - pkg: sigs.k8s.io/cluster-api/api/v1alpha4 alias: clusterv1alpha4 - pkg: sigs.k8s.io/cluster-api/api/v1beta1 alias: clusterv1 # CAPI exp + - pkg: sigs.k8s.io/cluster-api/internal/apis/core/exp/v1alpha3 + alias: expv1alpha3 - pkg: sigs.k8s.io/cluster-api/exp/api/v1alpha4 alias: expv1alpha4 - pkg: sigs.k8s.io/cluster-api/exp/api/v1beta1 alias: expv1 # CAPI exp addons + - pkg: sigs.k8s.io/cluster-api/internal/apis/core/exp/addons/v1alpha3 + alias: addonsv1alpha3 - pkg: sigs.k8s.io/cluster-api/exp/addons/api/v1alpha4 alias: addonsv1alpha4 - pkg: sigs.k8s.io/cluster-api/exp/addons/api/v1beta1 @@ -158,11 +170,15 @@ linters-settings: - pkg: sigs.k8s.io/cluster-api/internal/webhooks/runtime alias: runtimewebhooks # CAPD + - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha3 + alias: infrav1alpha3 - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha4 alias: infrav1alpha4 - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1 alias: infrav1 # CAPD exp + - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1alpha3 + alias: infraexpv1alpha3 - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1alpha4 alias: infraexpv1alpha4 - pkg: sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1 @@ -226,7 +242,7 @@ issues: # should be removed as the referenced deprecated types are removed from the project. - linters: - staticcheck - text: "SA1019: (clusterv1alpha4.*) is deprecated: This type will be removed in one of the next releases." + text: "SA1019: (clusterv1alpha3.*|clusterv1alpha4.*) is deprecated: This type will be removed in one of the next releases." - linters: - revive text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported" diff --git a/Makefile b/Makefile index 7f17ba7cc203..3c4a607f8363 100644 --- a/Makefile +++ b/Makefile @@ -280,6 +280,7 @@ generate-manifests-core: $(CONTROLLER_GEN) $(KUSTOMIZE) ## Generate manifests e. $(CONTROLLER_GEN) \ paths=./ \ paths=./api/... \ + paths=./internal/apis/core/... \ paths=./internal/controllers/... \ paths=./internal/webhooks/... \ paths=./$(EXP_DIR)/api/... \ @@ -311,6 +312,7 @@ generate-manifests-kubeadm-bootstrap: $(CONTROLLER_GEN) ## Generate manifests e. paths=./bootstrap/kubeadm/api/... \ paths=./bootstrap/kubeadm/internal/controllers/... \ paths=./bootstrap/kubeadm/internal/webhooks/... \ + paths=./internal/apis/bootstrap/kubeadm/... \ crd:crdVersions=v1 \ rbac:roleName=manager-role \ output:crd:dir=./bootstrap/kubeadm/config/crd/bases \ @@ -326,6 +328,7 @@ generate-manifests-kubeadm-control-plane: $(CONTROLLER_GEN) ## Generate manifest paths=./controlplane/kubeadm/api/... \ paths=./controlplane/kubeadm/internal/controllers/... \ paths=./controlplane/kubeadm/internal/webhooks/... \ + paths=./internal/apis/controlplane/kubeadm/... \ crd:crdVersions=v1 \ rbac:roleName=manager-role \ output:crd:dir=./controlplane/kubeadm/config/crd/bases \ @@ -438,8 +441,9 @@ generate-go-conversions-core: ## Run all generate-go-conversions-core-* targets .PHONY: generate-go-conversions-core-api generate-go-conversions-core-api: $(CONVERSION_GEN) ## Generate conversions go code for core api - $(MAKE) clean-generated-conversions SRC_DIRS="./api/v1alpha4" + $(MAKE) clean-generated-conversions SRC_DIRS="./internal/apis/core/v1alpha3,./api/v1alpha4" $(CONVERSION_GEN) \ + --input-dirs=./internal/apis/core/v1alpha3 \ --input-dirs=./api/v1alpha4 \ --build-tag=ignore_autogenerated_core \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ @@ -447,10 +451,14 @@ generate-go-conversions-core-api: $(CONVERSION_GEN) ## Generate conversions go c .PHONY: generate-go-conversions-core-exp generate-go-conversions-core-exp: $(CONVERSION_GEN) ## Generate conversions go code for core exp - $(MAKE) clean-generated-conversions SRC_DIRS="./$(EXP_DIR)/api/v1alpha4,./$(EXP_DIR)/addons/api/v1alpha4" + $(MAKE) clean-generated-conversions SRC_DIRS="./internal/apis/core/exp/v1alpha3,./internal/apis/core/exp/addons/v1alpha3,./$(EXP_DIR)/api/v1alpha4,./$(EXP_DIR)/addons/api/v1alpha4" $(CONVERSION_GEN) \ + --input-dirs=./internal/apis/core/exp/v1alpha3 \ --input-dirs=./$(EXP_DIR)/api/v1alpha4 \ + --input-dirs=./internal/apis/core/exp/addons/v1alpha3 \ --input-dirs=./$(EXP_DIR)/addons/api/v1alpha4 \ + --build-tag=ignore_autogenerated_core_exp \ + --extra-peer-dirs=sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3 \ --extra-peer-dirs=sigs.k8s.io/cluster-api/api/v1alpha4 \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ --go-header-file=./hack/boilerplate/boilerplate.generatego.txt @@ -460,6 +468,7 @@ generate-go-conversions-core-exp-ipam: $(CONVERSION_GEN) ## Generate conversions $(MAKE) clean-generated-conversions SRC_DIRS="./$(EXP_DIR)/ipam/api/v1alpha1" $(CONVERSION_GEN) \ --input-dirs=./$(EXP_DIR)/ipam/api/v1alpha1 \ + --build-tag=ignore_autogenerated_core_exp_ipam \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ --go-header-file=./hack/boilerplate/boilerplate.generatego.txt @@ -469,16 +478,18 @@ generate-go-conversions-core-runtime: $(CONVERSION_GEN) ## Generate conversions $(CONVERSION_GEN) \ --input-dirs=./internal/runtime/test/v1alpha1 \ --input-dirs=./internal/runtime/test/v1alpha2 \ - --build-tag=ignore_autogenerated_runtime \ + --build-tag=ignore_autogenerated_core_runtime \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ --go-header-file=./hack/boilerplate/boilerplate.generatego.txt .PHONY: generate-go-conversions-kubeadm-bootstrap generate-go-conversions-kubeadm-bootstrap: $(CONVERSION_GEN) ## Generate conversions go code for kubeadm bootstrap - $(MAKE) clean-generated-conversions SRC_DIRS="./bootstrap/kubeadm/api" + $(MAKE) clean-generated-conversions SRC_DIRS="./bootstrap/kubeadm/api,./internal/apis/bootstrap/kubeadm" $(CONVERSION_GEN) \ + --input-dirs=./internal/apis/bootstrap/kubeadm/v1alpha3 \ --input-dirs=./bootstrap/kubeadm/api/v1alpha4 \ --build-tag=ignore_autogenerated_kubeadm_bootstrap \ + --extra-peer-dirs=sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3 \ --extra-peer-dirs=sigs.k8s.io/cluster-api/api/v1alpha4 \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ --go-header-file=./hack/boilerplate/boilerplate.generatego.txt @@ -492,11 +503,14 @@ generate-go-conversions-kubeadm-bootstrap: $(CONVERSION_GEN) ## Generate convers .PHONY: generate-go-conversions-kubeadm-control-plane generate-go-conversions-kubeadm-control-plane: $(CONVERSION_GEN) ## Generate conversions go code for kubeadm control plane - $(MAKE) clean-generated-conversions SRC_DIRS="./controlplane/kubeadm/api" + $(MAKE) clean-generated-conversions SRC_DIRS="./controlplane/kubeadm/api,./internal/apis/controlplane/kubeadm" $(CONVERSION_GEN) \ + --input-dirs=./internal/apis/controlplane/kubeadm/v1alpha3 \ --input-dirs=./controlplane/kubeadm/api/v1alpha4 \ --build-tag=ignore_autogenerated_kubeadm_controlplane \ + --extra-peer-dirs=sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3 \ --extra-peer-dirs=sigs.k8s.io/cluster-api/api/v1alpha4 \ + --extra-peer-dirs=sigs.k8s.io/cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3 \ --extra-peer-dirs=sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1alpha4 \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE) \ --go-header-file=./hack/boilerplate/boilerplate.generatego.txt @@ -504,9 +518,12 @@ generate-go-conversions-kubeadm-control-plane: $(CONVERSION_GEN) ## Generate con .PHONY: generate-go-conversions-docker-infrastructure generate-go-conversions-docker-infrastructure: $(CONVERSION_GEN) ## Generate conversions go code for docker infrastructure provider cd $(CAPD_DIR); $(CONVERSION_GEN) \ + --input-dirs=./api/v1alpha3 \ --input-dirs=./api/v1alpha4 \ + --input-dirs=./$(EXP_DIR)/api/v1alpha3 \ --input-dirs=./$(EXP_DIR)/api/v1alpha4 \ --build-tag=ignore_autogenerated_capd \ + --extra-peer-dirs=sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3 \ --extra-peer-dirs=sigs.k8s.io/cluster-api/api/v1alpha4 \ --output-file-base=zz_generated.conversion $(CONVERSION_GEN_OUTPUT_BASE_CAPD) \ --go-header-file=../../../hack/boilerplate/boilerplate.generatego.txt @@ -544,11 +561,19 @@ generate-doctoc: TRACE=$(TRACE) ./hack/generate-doctoc.sh .PHONY: generate-e2e-templates -generate-e2e-templates: $(KUSTOMIZE) $(addprefix generate-e2e-templates-, v1.0 v1.4 v1.5 main) ## Generate cluster templates for all versions +generate-e2e-templates: $(KUSTOMIZE) $(addprefix generate-e2e-templates-, v0.3 v0.4 v1.0 v1.4 v1.5 main) ## Generate cluster templates for all versions DOCKER_TEMPLATES := test/e2e/data/infrastructure-docker INMEMORY_TEMPLATES := test/e2e/data/infrastructure-inmemory +.PHONY: generate-e2e-templates-v0.3 +generate-e2e-templates-v0.3: $(KUSTOMIZE) + $(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v0.3/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v0.3/cluster-template.yaml + +.PHONY: generate-e2e-templates-v0.4 +generate-e2e-templates-v0.4: $(KUSTOMIZE) + $(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v0.4/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v0.4/cluster-template.yaml + .PHONY: generate-e2e-templates-v1.0 generate-e2e-templates-v1.0: $(KUSTOMIZE) $(KUSTOMIZE) build $(DOCKER_TEMPLATES)/v1.0/cluster-template --load-restrictor LoadRestrictionsNone > $(DOCKER_TEMPLATES)/v1.0/cluster-template.yaml diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml index 6098877906cc..8c29323a0740 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigs.yaml @@ -16,6 +16,996 @@ spec: singular: kubeadmconfig scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "KubeadmConfig is the Schema for the kubeadmconfigs API. \n Deprecated: + This type will be removed in one of the next releases." + 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: KubeadmConfigSpec defines the desired state of KubeadmConfig. + Either ClusterConfiguration and InitConfiguration should be defined + or the JoinConfiguration should be defined. + properties: + clusterConfiguration: + description: ClusterConfiguration along with InitConfiguration are + the configurations necessary for the init command + properties: + apiServer: + description: APIServer contains extra settings for the API server + control plane component + properties: + certSANs: + description: CertSANs sets extra Subject Alternative Names + for the API Server signing cert. + items: + type: string + type: array + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass to + the control plane component. TODO: This is temporary and + ideally we would like to switch all components to use ComponentConfig + + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that will + be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod where + hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + timeoutForControlPlane: + description: TimeoutForControlPlane controls the timeout that + we use for API server to appear + type: string + type: object + 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 + certificatesDir: + description: 'CertificatesDir specifies where to store or look + for all required certificates. NB: if not provided, this will + default to `/etc/kubernetes/pki`' + type: string + clusterName: + description: The cluster name + type: string + controlPlaneEndpoint: + description: 'ControlPlaneEndpoint sets a stable IP address or + DNS name for the control plane; it can be a valid IP address + or a RFC-1123 DNS subdomain, both with optional TCP port. In + case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + + BindPort are used; in case the ControlPlaneEndpoint is specified + but without a TCP port, the BindPort is used. Possible usages + are: e.g. In a cluster with more than one control plane instances, + this field should be assigned the address of the external load + balancer in front of the control plane instances. e.g. in environments + with enforced node recycling, the ControlPlaneEndpoint could + be used for assigning a stable DNS to the control plane. NB: + This value defaults to the first value in the Cluster object + status.apiEndpoints array.' + type: string + controllerManager: + description: ControllerManager contains extra settings for the + controller manager control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass to + the control plane component. TODO: This is temporary and + ideally we would like to switch all components to use ComponentConfig + + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that will + be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod where + hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + dns: + description: DNS defines the options for the DNS add-on installed + in the cluster. + properties: + imageRepository: + description: ImageRepository sets the container registry to + pull images from. if not set, the ImageRepository defined + in ClusterConfiguration will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag for the image. + In case this value is set, kubeadm does not change automatically + the version of the above components during upgrades. + type: string + type: + description: Type defines the DNS add-on to be used + type: string + type: object + etcd: + description: 'Etcd holds configuration for etcd. NB: This value + defaults to a Local (stacked) etcd' + properties: + external: + description: External describes how to connect to an external + etcd cluster Local and External are mutually exclusive + properties: + caFile: + description: CAFile is an SSL Certificate Authority file + used to secure etcd communication. Required if using + a TLS connection. + type: string + certFile: + description: CertFile is an SSL certification file used + to secure etcd communication. Required if using a TLS + connection. + type: string + endpoints: + description: Endpoints of etcd members. Required for ExternalEtcd. + items: + type: string + type: array + keyFile: + description: KeyFile is an SSL key file used to secure + etcd communication. Required if using a TLS connection. + type: string + required: + - caFile + - certFile + - endpoints + - keyFile + type: object + local: + description: Local provides configuration knobs for configuring + the local etcd instance Local and External are mutually + exclusive + properties: + dataDir: + description: DataDir is the directory etcd will place + its data. Defaults to "/var/lib/etcd". + type: string + extraArgs: + additionalProperties: + type: string + description: ExtraArgs are extra arguments provided to + the etcd binary when run inside a static pod. + type: object + imageRepository: + description: ImageRepository sets the container registry + to pull images from. if not set, the ImageRepository + defined in ClusterConfiguration will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag for the + image. In case this value is set, kubeadm does not change + automatically the version of the above components during + upgrades. + type: string + peerCertSANs: + description: PeerCertSANs sets extra Subject Alternative + Names for the etcd peer signing cert. + items: + type: string + type: array + serverCertSANs: + description: ServerCertSANs sets extra Subject Alternative + Names for the etcd server signing cert. + items: + type: string + type: array + type: object + type: object + featureGates: + additionalProperties: + type: boolean + description: FeatureGates enabled by the user. + type: object + imageRepository: + description: ImageRepository sets the container registry to pull + images from. If empty, `k8s.gcr.io` will be used by default; + in case of kubernetes version is a CI build (kubernetes version + starts with `ci/` or `ci-cross/`) `gcr.io/k8s-staging-ci-images` + will be used as a default for control plane components and for + kube-proxy, while `k8s.gcr.io` will be used for all the other + images. + 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 + kubernetesVersion: + description: 'KubernetesVersion is the target version of the control + plane. NB: This value defaults to the Machine object spec.version' + type: string + networking: + description: 'Networking holds configuration for the networking + topology of the cluster. NB: This value defaults to the Cluster + object spec.clusterNetwork.' + properties: + dnsDomain: + description: DNSDomain is the dns domain used by k8s services. + Defaults to "cluster.local". + type: string + podSubnet: + description: PodSubnet is the subnet used by pods. If unset, + the API server will not allocate CIDR ranges for every node. + Defaults to a comma-delimited string of the Cluster object's + spec.clusterNetwork.services.cidrBlocks if that is set + type: string + serviceSubnet: + description: ServiceSubnet is the subnet used by k8s services. + Defaults to a comma-delimited string of the Cluster object's + spec.clusterNetwork.pods.cidrBlocks, or to "10.96.0.0/12" + if that's unset. + type: string + type: object + scheduler: + description: Scheduler contains extra settings for the scheduler + control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass to + the control plane component. TODO: This is temporary and + ideally we would like to switch all components to use ComponentConfig + + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that will + be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod where + hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + useHyperKubeImage: + description: UseHyperKubeImage controls if hyperkube should be + used for Kubernetes components instead of their respective separate + images + type: boolean + type: object + diskSetup: + description: DiskSetup specifies options for the creation of partition + tables and file systems on devices. + properties: + filesystems: + description: Filesystems specifies the list of file systems to + setup. + items: + description: Filesystem defines the file systems to be created. + properties: + device: + description: Device specifies the device name + type: string + extraOpts: + description: ExtraOpts defined extra options to add to the + command for creating the file system. + items: + type: string + type: array + filesystem: + description: Filesystem specifies the file system type. + type: string + label: + description: Label specifies the file system label to be + used. If set to None, no label is used. + type: string + overwrite: + description: Overwrite defines whether or not to overwrite + any existing filesystem. If true, any pre-existing file + system will be destroyed. Use with Caution. + type: boolean + partition: + description: 'Partition specifies the partition to use. + The valid options are: "auto|any", "auto", "any", "none", + and , where NUM is the actual partition number.' + type: string + replaceFS: + description: 'ReplaceFS is a special directive, used for + Microsoft Azure that instructs cloud-init to replace a + file system of . NOTE: unless you define a label, + this requires the use of the ''any'' partition directive.' + type: string + required: + - device + - filesystem + - label + type: object + type: array + partitions: + description: Partitions specifies the list of the partitions to + setup. + items: + description: Partition defines how to create and layout a partition. + properties: + device: + description: Device is the name of the device. + type: string + layout: + description: Layout specifies the device layout. If it is + true, a single partition will be created for the entire + device. When layout is false, it means don't partition + or ignore existing partitioning. + type: boolean + overwrite: + description: Overwrite describes whether to skip checks + and create the partition if a partition or filesystem + is found on the device. Use with caution. Default is 'false'. + type: boolean + tableType: + description: 'TableType specifies the tupe of partition + table. The following are supported: ''mbr'': default and + setups a MS-DOS partition table ''gpt'': setups a GPT + partition table' + type: string + required: + - device + - layout + type: object + type: array + type: object + files: + description: Files specifies extra files to be passed to user_data + upon creation. + items: + description: File defines the input for generating write_files in + cloud-init. + properties: + content: + description: Content is the actual content of the file. + type: string + contentFrom: + description: ContentFrom is a referenced source of content to + populate the file. + properties: + secret: + description: Secret represents a secret that should populate + this file. + properties: + key: + description: Key is the key in the secret's data map + for this value. + type: string + name: + description: Name of the secret in the KubeadmBootstrapConfig's + namespace to use. + type: string + required: + - key + - name + type: object + required: + - secret + type: object + encoding: + description: Encoding specifies the encoding of the file contents. + enum: + - base64 + - gzip + - gzip+base64 + type: string + owner: + description: Owner specifies the ownership of the file, e.g. + "root:root". + type: string + path: + description: Path specifies the full path on disk where to store + the file. + type: string + permissions: + description: Permissions specifies the permissions to assign + to the file, e.g. "0640". + type: string + required: + - path + type: object + type: array + format: + description: Format specifies the output format of the bootstrap data + enum: + - cloud-config + type: string + initConfiguration: + description: InitConfiguration along with ClusterConfiguration are + the configurations necessary for the init command + 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 + bootstrapTokens: + description: BootstrapTokens is respected at `kubeadm init` time + and describes a set of Bootstrap Tokens to create. This information + IS NOT uploaded to the kubeadm cluster configmap, partly because + of its sensitive nature + items: + description: BootstrapToken describes one bootstrap token, stored + as a Secret in the cluster. + properties: + description: + description: Description sets a human-friendly message why + this token exists and what it's used for, so other administrators + can know its purpose. + type: string + expires: + description: Expires specifies the timestamp when this token + expires. Defaults to being set dynamically at runtime + based on the TTL. Expires and TTL are mutually exclusive. + format: date-time + type: string + groups: + description: Groups specifies the extra groups that this + token will authenticate as when/if used for authentication + items: + type: string + type: array + token: + description: Token is used for establishing bidirectional + trust between nodes and control-planes. Used for joining + nodes in the cluster. + type: string + ttl: + description: TTL defines the time to live for this token. + Defaults to 24h. Expires and TTL are mutually exclusive. + type: string + usages: + description: Usages describes the ways in which this token + can be used. Can by default be used for establishing bidirectional + trust, but that can be changed here. + items: + type: string + type: array + required: + - token + type: object + type: array + 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 + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint of the API + server instance that's deployed on this control plane node In + HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint + in the sense that ControlPlaneEndpoint is the global endpoint + for the cluster, which then loadbalances the requests to each + individual API server. This configuration object lets you customize + what IP/DNS name and port the local API server advertises it's + accessible on. By default, kubeadm tries to auto-detect the + IP of the default interface and use that, but in case that process + fails you may set the desired value here. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address for the + API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for the API Server + to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + nodeRegistration: + description: NodeRegistration holds fields that relate to registering + the new control-plane node to the cluster. When used in the + context of control plane nodes, NodeRegistration should remain + consistent across both InitConfiguration and JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container runtime + info. This information will be annotated to the Node API + object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra arguments + to the kubelet. The arguments here are passed to the kubelet + command line via the environment file kubeadm writes at + runtime for the kubelet to source. This overrides the generic + base-level configuration in the kubelet-config-1.X ConfigMap + Flags have higher priority when parsing. These values are + local and specific to the node kubeadm is executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of the Node + API object that will be created in this `kubeadm init` or + `kubeadm join` operation. This field is also used in the + CommonName field of the kubelet's client certificate to + the API server. Defaults to the hostname of the node if + not provided. + type: string + taints: + description: 'Taints specifies the taints the Node API object + should be registered with. If this field is unset, i.e. + nil, in the `kubeadm init` process it will be defaulted + to []v1.Taint{''node-role.kubernetes.io/master=""''}. If + you don''t want to taint your control-plane node, set this + field to an empty slice, i.e. `taints: {}` in the YAML file. + This field is solely used for Node registration.' + items: + description: The node this Taint is attached to has the + "effect" on any pod that does not tolerate the Taint. + properties: + effect: + description: Required. The effect of the taint on pods + that do not tolerate the taint. Valid effects are + NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied to + a node. + type: string + timeAdded: + description: TimeAdded represents the time at which + the taint was added. It is only written for NoExecute + taints. + format: date-time + type: string + value: + description: The taint value corresponding to the taint + key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + joinConfiguration: + description: JoinConfiguration is the kubeadm configuration for the + join command + 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 + caCertPath: + description: 'CACertPath is the path to the SSL certificate authority + used to secure comunications between node and control-plane. + Defaults to "/etc/kubernetes/pki/ca.crt". TODO: revisit when + there is defaulting from k/k' + type: string + controlPlane: + description: ControlPlane defines the additional control plane + instance to be deployed on the joining node. If nil, no additional + control plane instance will be deployed. + properties: + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint of the + API server instance to be deployed on this node. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address for + the API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for the API + Server to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + type: object + discovery: + description: 'Discovery specifies the options for the kubelet + to use during the TLS Bootstrap process TODO: revisit when there + is defaulting from k/k' + properties: + bootstrapToken: + description: BootstrapToken is used to set the options for + bootstrap token based discovery BootstrapToken and File + are mutually exclusive + properties: + apiServerEndpoint: + description: APIServerEndpoint is an IP or domain name + to the API server from which info will be fetched. + type: string + caCertHashes: + description: 'CACertHashes specifies a set of public key + pins to verify when token-based discovery is used. The + root CA found during discovery must match one of these + values. Specifying an empty set disables root CA pinning, + which can be unsafe. Each hash is specified as ":", + where the only currently supported type is "sha256". + This is a hex-encoded SHA-256 hash of the Subject Public + Key Info (SPKI) object in DER-encoded ASN.1. These hashes + can be calculated using, for example, OpenSSL: openssl + x509 -pubkey -in ca.crt openssl rsa -pubin -outform + der 2>&/dev/null | openssl dgst -sha256 -hex' + items: + type: string + type: array + token: + description: Token is a token used to validate cluster + information fetched from the control-plane. + type: string + unsafeSkipCAVerification: + description: UnsafeSkipCAVerification allows token-based + discovery without CA verification via CACertHashes. + This can weaken the security of kubeadm since other + nodes can impersonate the control-plane. + type: boolean + required: + - token + - unsafeSkipCAVerification + type: object + file: + description: File is used to specify a file or URL to a kubeconfig + file from which to load cluster information BootstrapToken + and File are mutually exclusive + properties: + kubeConfigPath: + description: KubeConfigPath is used to specify the actual + file path or URL to the kubeconfig file from which to + load cluster information + type: string + required: + - kubeConfigPath + type: object + timeout: + description: Timeout modifies the discovery timeout + type: string + tlsBootstrapToken: + description: 'TLSBootstrapToken is a token used for TLS bootstrapping. + If .BootstrapToken is set, this field is defaulted to .BootstrapToken.Token, + but can be overridden. If .File is set, this field **must + be set** in case the KubeConfigFile does not contain any + other authentication information TODO: revisit when there + is defaulting from k/k' + type: string + type: object + 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 + nodeRegistration: + description: NodeRegistration holds fields that relate to registering + the new control-plane node to the cluster. When used in the + context of control plane nodes, NodeRegistration should remain + consistent across both InitConfiguration and JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container runtime + info. This information will be annotated to the Node API + object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra arguments + to the kubelet. The arguments here are passed to the kubelet + command line via the environment file kubeadm writes at + runtime for the kubelet to source. This overrides the generic + base-level configuration in the kubelet-config-1.X ConfigMap + Flags have higher priority when parsing. These values are + local and specific to the node kubeadm is executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of the Node + API object that will be created in this `kubeadm init` or + `kubeadm join` operation. This field is also used in the + CommonName field of the kubelet's client certificate to + the API server. Defaults to the hostname of the node if + not provided. + type: string + taints: + description: 'Taints specifies the taints the Node API object + should be registered with. If this field is unset, i.e. + nil, in the `kubeadm init` process it will be defaulted + to []v1.Taint{''node-role.kubernetes.io/master=""''}. If + you don''t want to taint your control-plane node, set this + field to an empty slice, i.e. `taints: {}` in the YAML file. + This field is solely used for Node registration.' + items: + description: The node this Taint is attached to has the + "effect" on any pod that does not tolerate the Taint. + properties: + effect: + description: Required. The effect of the taint on pods + that do not tolerate the taint. Valid effects are + NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied to + a node. + type: string + timeAdded: + description: TimeAdded represents the time at which + the taint was added. It is only written for NoExecute + taints. + format: date-time + type: string + value: + description: The taint value corresponding to the taint + key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + mounts: + description: Mounts specifies a list of mount points to be setup. + items: + description: MountPoints defines input for generated mounts in cloud-init. + items: + type: string + type: array + type: array + ntp: + description: NTP specifies NTP configuration + properties: + enabled: + description: Enabled specifies whether NTP should be enabled + type: boolean + servers: + description: Servers specifies which NTP servers to use + items: + type: string + type: array + type: object + postKubeadmCommands: + description: PostKubeadmCommands specifies extra commands to run after + kubeadm runs + items: + type: string + type: array + preKubeadmCommands: + description: PreKubeadmCommands specifies extra commands to run before + kubeadm runs + items: + type: string + type: array + useExperimentalRetryJoin: + description: "UseExperimentalRetryJoin replaces a basic kubeadm command + with a shell script with retries for joins. \n This is meant to + be an experimental temporary workaround on some environments where + joins fail due to timing (and other issues). The long term goal + is to add retries to kubeadm proper and use that functionality. + \n This will add about 40KB to userdata \n For more information, + refer to https://github.com/kubernetes-sigs/cluster-api/pull/2763#discussion_r397306055." + type: boolean + users: + description: Users specifies extra users to add + items: + description: User defines the input for a generated user in cloud-init. + properties: + gecos: + description: Gecos specifies the gecos to use for the user + type: string + groups: + description: Groups specifies the additional groups for the + user + type: string + homeDir: + description: HomeDir specifies the home directory to use for + the user + type: string + inactive: + description: Inactive specifies whether to mark the user as + inactive + type: boolean + lockPassword: + description: LockPassword specifies if password login should + be disabled + type: boolean + name: + description: Name specifies the user name + type: string + passwd: + description: Passwd specifies a hashed password for the user + type: string + primaryGroup: + description: PrimaryGroup specifies the primary group for the + user + type: string + shell: + description: Shell specifies the user's shell + type: string + sshAuthorizedKeys: + description: SSHAuthorizedKeys specifies a list of ssh authorized + keys for the user + items: + type: string + type: array + sudo: + description: Sudo specifies a sudo role for the user + type: string + required: + - name + type: object + type: array + verbosity: + description: Verbosity is the number for the kubeadm log level verbosity. + It overrides the `--v` flag in kubeadm commands. + format: int32 + type: integer + type: object + status: + description: KubeadmConfigStatus defines the observed state of KubeadmConfig. + properties: + bootstrapData: + description: "BootstrapData will be a cloud-init script for now. \n + Deprecated: Switch to DataSecretName." + format: byte + type: string + conditions: + description: Conditions defines current service state of the KubeadmConfig. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + dataSecretName: + description: DataSecretName is the name of the secret that stores + the bootstrap data script. + type: string + failureMessage: + description: FailureMessage will be set on non-retryable errors + type: string + failureReason: + description: FailureReason will be set on non-retryable errors + type: string + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + ready: + description: Ready indicates the BootstrapData field is ready to be + consumed + type: boolean + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of KubeadmConfig jsonPath: .metadata.creationTimestamp diff --git a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml index 0ad80adfb9e0..5b30cf21aa16 100644 --- a/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml +++ b/bootstrap/kubeadm/config/crd/bases/bootstrap.cluster.x-k8s.io_kubeadmconfigtemplates.yaml @@ -16,6 +16,984 @@ spec: singular: kubeadmconfigtemplate scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "KubeadmConfigTemplate is the Schema for the kubeadmconfigtemplates + API. \n Deprecated: This type will be removed in one of the next releases." + 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: KubeadmConfigTemplateSpec defines the desired state of KubeadmConfigTemplate. + properties: + template: + description: KubeadmConfigTemplateResource defines the Template structure. + properties: + spec: + description: KubeadmConfigSpec defines the desired state of KubeadmConfig. + Either ClusterConfiguration and InitConfiguration should be + defined or the JoinConfiguration should be defined. + properties: + clusterConfiguration: + description: ClusterConfiguration along with InitConfiguration + are the configurations necessary for the init command + properties: + apiServer: + description: APIServer contains extra settings for the + API server control plane component + properties: + certSANs: + description: CertSANs sets extra Subject Alternative + Names for the API Server signing cert. + items: + type: string + type: array + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to + pass to the control plane component. TODO: This + is temporary and ideally we would like to switch + all components to use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host + volumes, mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host + that will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the + pod where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod + template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access + to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + timeoutForControlPlane: + description: TimeoutForControlPlane controls the timeout + that we use for API server to appear + type: string + type: object + 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 + certificatesDir: + description: 'CertificatesDir specifies where to store + or look for all required certificates. NB: if not provided, + this will default to `/etc/kubernetes/pki`' + type: string + clusterName: + description: The cluster name + type: string + controlPlaneEndpoint: + description: 'ControlPlaneEndpoint sets a stable IP address + or DNS name for the control plane; it can be a valid + IP address or a RFC-1123 DNS subdomain, both with optional + TCP port. In case the ControlPlaneEndpoint is not specified, + the AdvertiseAddress + BindPort are used; in case the + ControlPlaneEndpoint is specified but without a TCP + port, the BindPort is used. Possible usages are: e.g. + In a cluster with more than one control plane instances, + this field should be assigned the address of the external + load balancer in front of the control plane instances. + e.g. in environments with enforced node recycling, + the ControlPlaneEndpoint could be used for assigning + a stable DNS to the control plane. NB: This value defaults + to the first value in the Cluster object status.apiEndpoints + array.' + type: string + controllerManager: + description: ControllerManager contains extra settings + for the controller manager control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to + pass to the control plane component. TODO: This + is temporary and ideally we would like to switch + all components to use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host + volumes, mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host + that will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the + pod where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod + template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access + to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + dns: + description: DNS defines the options for the DNS add-on + installed in the cluster. + properties: + imageRepository: + description: ImageRepository sets the container registry + to pull images from. if not set, the ImageRepository + defined in ClusterConfiguration will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag for + the image. In case this value is set, kubeadm does + not change automatically the version of the above + components during upgrades. + type: string + type: + description: Type defines the DNS add-on to be used + type: string + type: object + etcd: + description: 'Etcd holds configuration for etcd. NB: This + value defaults to a Local (stacked) etcd' + properties: + external: + description: External describes how to connect to + an external etcd cluster Local and External are + mutually exclusive + properties: + caFile: + description: CAFile is an SSL Certificate Authority + file used to secure etcd communication. Required + if using a TLS connection. + type: string + certFile: + description: CertFile is an SSL certification + file used to secure etcd communication. Required + if using a TLS connection. + type: string + endpoints: + description: Endpoints of etcd members. Required + for ExternalEtcd. + items: + type: string + type: array + keyFile: + description: KeyFile is an SSL key file used to + secure etcd communication. Required if using + a TLS connection. + type: string + required: + - caFile + - certFile + - endpoints + - keyFile + type: object + local: + description: Local provides configuration knobs for + configuring the local etcd instance Local and External + are mutually exclusive + properties: + dataDir: + description: DataDir is the directory etcd will + place its data. Defaults to "/var/lib/etcd". + type: string + extraArgs: + additionalProperties: + type: string + description: ExtraArgs are extra arguments provided + to the etcd binary when run inside a static + pod. + type: object + imageRepository: + description: ImageRepository sets the container + registry to pull images from. if not set, the + ImageRepository defined in ClusterConfiguration + will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag + for the image. In case this value is set, kubeadm + does not change automatically the version of + the above components during upgrades. + type: string + peerCertSANs: + description: PeerCertSANs sets extra Subject Alternative + Names for the etcd peer signing cert. + items: + type: string + type: array + serverCertSANs: + description: ServerCertSANs sets extra Subject + Alternative Names for the etcd server signing + cert. + items: + type: string + type: array + type: object + type: object + featureGates: + additionalProperties: + type: boolean + description: FeatureGates enabled by the user. + type: object + imageRepository: + description: ImageRepository sets the container registry + to pull images from. If empty, `k8s.gcr.io` will be + used by default; in case of kubernetes version is a + CI build (kubernetes version starts with `ci/` or `ci-cross/`) + `gcr.io/k8s-staging-ci-images` will be used as a default + for control plane components and for kube-proxy, while + `k8s.gcr.io` will be used for all the other images. + 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 + kubernetesVersion: + description: 'KubernetesVersion is the target version + of the control plane. NB: This value defaults to the + Machine object spec.version' + type: string + networking: + description: 'Networking holds configuration for the networking + topology of the cluster. NB: This value defaults to + the Cluster object spec.clusterNetwork.' + properties: + dnsDomain: + description: DNSDomain is the dns domain used by k8s + services. Defaults to "cluster.local". + type: string + podSubnet: + description: PodSubnet is the subnet used by pods. + If unset, the API server will not allocate CIDR + ranges for every node. Defaults to a comma-delimited + string of the Cluster object's spec.clusterNetwork.services.cidrBlocks + if that is set + type: string + serviceSubnet: + description: ServiceSubnet is the subnet used by k8s + services. Defaults to a comma-delimited string of + the Cluster object's spec.clusterNetwork.pods.cidrBlocks, + or to "10.96.0.0/12" if that's unset. + type: string + type: object + scheduler: + description: Scheduler contains extra settings for the + scheduler control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to + pass to the control plane component. TODO: This + is temporary and ideally we would like to switch + all components to use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host + volumes, mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host + that will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the + pod where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod + template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access + to the volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + useHyperKubeImage: + description: UseHyperKubeImage controls if hyperkube should + be used for Kubernetes components instead of their respective + separate images + type: boolean + type: object + diskSetup: + description: DiskSetup specifies options for the creation + of partition tables and file systems on devices. + properties: + filesystems: + description: Filesystems specifies the list of file systems + to setup. + items: + description: Filesystem defines the file systems to + be created. + properties: + device: + description: Device specifies the device name + type: string + extraOpts: + description: ExtraOpts defined extra options to + add to the command for creating the file system. + items: + type: string + type: array + filesystem: + description: Filesystem specifies the file system + type. + type: string + label: + description: Label specifies the file system label + to be used. If set to None, no label is used. + type: string + overwrite: + description: Overwrite defines whether or not to + overwrite any existing filesystem. If true, any + pre-existing file system will be destroyed. Use + with Caution. + type: boolean + partition: + description: 'Partition specifies the partition + to use. The valid options are: "auto|any", "auto", + "any", "none", and , where NUM is the actual + partition number.' + type: string + replaceFS: + description: 'ReplaceFS is a special directive, + used for Microsoft Azure that instructs cloud-init + to replace a file system of . NOTE: unless + you define a label, this requires the use of the + ''any'' partition directive.' + type: string + required: + - device + - filesystem + - label + type: object + type: array + partitions: + description: Partitions specifies the list of the partitions + to setup. + items: + description: Partition defines how to create and layout + a partition. + properties: + device: + description: Device is the name of the device. + type: string + layout: + description: Layout specifies the device layout. + If it is true, a single partition will be created + for the entire device. When layout is false, it + means don't partition or ignore existing partitioning. + type: boolean + overwrite: + description: Overwrite describes whether to skip + checks and create the partition if a partition + or filesystem is found on the device. Use with + caution. Default is 'false'. + type: boolean + tableType: + description: 'TableType specifies the tupe of partition + table. The following are supported: ''mbr'': default + and setups a MS-DOS partition table ''gpt'': setups + a GPT partition table' + type: string + required: + - device + - layout + type: object + type: array + type: object + files: + description: Files specifies extra files to be passed to user_data + upon creation. + items: + description: File defines the input for generating write_files + in cloud-init. + properties: + content: + description: Content is the actual content of the file. + type: string + contentFrom: + description: ContentFrom is a referenced source of content + to populate the file. + properties: + secret: + description: Secret represents a secret that should + populate this file. + properties: + key: + description: Key is the key in the secret's + data map for this value. + type: string + name: + description: Name of the secret in the KubeadmBootstrapConfig's + namespace to use. + type: string + required: + - key + - name + type: object + required: + - secret + type: object + encoding: + description: Encoding specifies the encoding of the + file contents. + enum: + - base64 + - gzip + - gzip+base64 + type: string + owner: + description: Owner specifies the ownership of the file, + e.g. "root:root". + type: string + path: + description: Path specifies the full path on disk where + to store the file. + type: string + permissions: + description: Permissions specifies the permissions to + assign to the file, e.g. "0640". + type: string + required: + - path + type: object + type: array + format: + description: Format specifies the output format of the bootstrap + data + enum: + - cloud-config + type: string + initConfiguration: + description: InitConfiguration along with ClusterConfiguration + are the configurations necessary for the init command + 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 + bootstrapTokens: + description: BootstrapTokens is respected at `kubeadm + init` time and describes a set of Bootstrap Tokens to + create. This information IS NOT uploaded to the kubeadm + cluster configmap, partly because of its sensitive nature + items: + description: BootstrapToken describes one bootstrap + token, stored as a Secret in the cluster. + properties: + description: + description: Description sets a human-friendly message + why this token exists and what it's used for, + so other administrators can know its purpose. + type: string + expires: + description: Expires specifies the timestamp when + this token expires. Defaults to being set dynamically + at runtime based on the TTL. Expires and TTL are + mutually exclusive. + format: date-time + type: string + groups: + description: Groups specifies the extra groups that + this token will authenticate as when/if used for + authentication + items: + type: string + type: array + token: + description: Token is used for establishing bidirectional + trust between nodes and control-planes. Used for + joining nodes in the cluster. + type: string + ttl: + description: TTL defines the time to live for this + token. Defaults to 24h. Expires and TTL are mutually + exclusive. + type: string + usages: + description: Usages describes the ways in which + this token can be used. Can by default be used + for establishing bidirectional trust, but that + can be changed here. + items: + type: string + type: array + required: + - token + type: object + type: array + 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 + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint + of the API server instance that's deployed on this control + plane node In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint + in the sense that ControlPlaneEndpoint is the global + endpoint for the cluster, which then loadbalances the + requests to each individual API server. This configuration + object lets you customize what IP/DNS name and port + the local API server advertises it's accessible on. + By default, kubeadm tries to auto-detect the IP of the + default interface and use that, but in case that process + fails you may set the desired value here. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address + for the API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for the + API Server to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + nodeRegistration: + description: NodeRegistration holds fields that relate + to registering the new control-plane node to the cluster. + When used in the context of control plane nodes, NodeRegistration + should remain consistent across both InitConfiguration + and JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container + runtime info. This information will be annotated + to the Node API object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra + arguments to the kubelet. The arguments here are + passed to the kubelet command line via the environment + file kubeadm writes at runtime for the kubelet to + source. This overrides the generic base-level configuration + in the kubelet-config-1.X ConfigMap Flags have higher + priority when parsing. These values are local and + specific to the node kubeadm is executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of + the Node API object that will be created in this + `kubeadm init` or `kubeadm join` operation. This + field is also used in the CommonName field of the + kubelet's client certificate to the API server. + Defaults to the hostname of the node if not provided. + type: string + taints: + description: 'Taints specifies the taints the Node + API object should be registered with. If this field + is unset, i.e. nil, in the `kubeadm init` process + it will be defaulted to []v1.Taint{''node-role.kubernetes.io/master=""''}. + If you don''t want to taint your control-plane node, + set this field to an empty slice, i.e. `taints: + {}` in the YAML file. This field is solely used + for Node registration.' + items: + description: The node this Taint is attached to + has the "effect" on any pod that does not tolerate + the Taint. + properties: + effect: + description: Required. The effect of the taint + on pods that do not tolerate the taint. Valid + effects are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Required. The taint key to be applied + to a node. + type: string + timeAdded: + description: TimeAdded represents the time at + which the taint was added. It is only written + for NoExecute taints. + format: date-time + type: string + value: + description: The taint value corresponding to + the taint key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + joinConfiguration: + description: JoinConfiguration is the kubeadm configuration + for the join command + 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 + caCertPath: + description: 'CACertPath is the path to the SSL certificate + authority used to secure comunications between node + and control-plane. Defaults to "/etc/kubernetes/pki/ca.crt". + TODO: revisit when there is defaulting from k/k' + type: string + controlPlane: + description: ControlPlane defines the additional control + plane instance to be deployed on the joining node. If + nil, no additional control plane instance will be deployed. + properties: + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint + of the API server instance to be deployed on this + node. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address + for the API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for + the API Server to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + type: object + discovery: + description: 'Discovery specifies the options for the + kubelet to use during the TLS Bootstrap process TODO: + revisit when there is defaulting from k/k' + properties: + bootstrapToken: + description: BootstrapToken is used to set the options + for bootstrap token based discovery BootstrapToken + and File are mutually exclusive + properties: + apiServerEndpoint: + description: APIServerEndpoint is an IP or domain + name to the API server from which info will + be fetched. + type: string + caCertHashes: + description: 'CACertHashes specifies a set of + public key pins to verify when token-based discovery + is used. The root CA found during discovery + must match one of these values. Specifying an + empty set disables root CA pinning, which can + be unsafe. Each hash is specified as ":", + where the only currently supported type is "sha256". + This is a hex-encoded SHA-256 hash of the Subject + Public Key Info (SPKI) object in DER-encoded + ASN.1. These hashes can be calculated using, + for example, OpenSSL: openssl x509 -pubkey -in + ca.crt openssl rsa -pubin -outform der 2>&/dev/null + | openssl dgst -sha256 -hex' + items: + type: string + type: array + token: + description: Token is a token used to validate + cluster information fetched from the control-plane. + type: string + unsafeSkipCAVerification: + description: UnsafeSkipCAVerification allows token-based + discovery without CA verification via CACertHashes. + This can weaken the security of kubeadm since + other nodes can impersonate the control-plane. + type: boolean + required: + - token + - unsafeSkipCAVerification + type: object + file: + description: File is used to specify a file or URL + to a kubeconfig file from which to load cluster + information BootstrapToken and File are mutually + exclusive + properties: + kubeConfigPath: + description: KubeConfigPath is used to specify + the actual file path or URL to the kubeconfig + file from which to load cluster information + type: string + required: + - kubeConfigPath + type: object + timeout: + description: Timeout modifies the discovery timeout + type: string + tlsBootstrapToken: + description: 'TLSBootstrapToken is a token used for + TLS bootstrapping. If .BootstrapToken is set, this + field is defaulted to .BootstrapToken.Token, but + can be overridden. If .File is set, this field **must + be set** in case the KubeConfigFile does not contain + any other authentication information TODO: revisit + when there is defaulting from k/k' + type: string + type: object + 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 + nodeRegistration: + description: NodeRegistration holds fields that relate + to registering the new control-plane node to the cluster. + When used in the context of control plane nodes, NodeRegistration + should remain consistent across both InitConfiguration + and JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container + runtime info. This information will be annotated + to the Node API object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra + arguments to the kubelet. The arguments here are + passed to the kubelet command line via the environment + file kubeadm writes at runtime for the kubelet to + source. This overrides the generic base-level configuration + in the kubelet-config-1.X ConfigMap Flags have higher + priority when parsing. These values are local and + specific to the node kubeadm is executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of + the Node API object that will be created in this + `kubeadm init` or `kubeadm join` operation. This + field is also used in the CommonName field of the + kubelet's client certificate to the API server. + Defaults to the hostname of the node if not provided. + type: string + taints: + description: 'Taints specifies the taints the Node + API object should be registered with. If this field + is unset, i.e. nil, in the `kubeadm init` process + it will be defaulted to []v1.Taint{''node-role.kubernetes.io/master=""''}. + If you don''t want to taint your control-plane node, + set this field to an empty slice, i.e. `taints: + {}` in the YAML file. This field is solely used + for Node registration.' + items: + description: The node this Taint is attached to + has the "effect" on any pod that does not tolerate + the Taint. + properties: + effect: + description: Required. The effect of the taint + on pods that do not tolerate the taint. Valid + effects are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Required. The taint key to be applied + to a node. + type: string + timeAdded: + description: TimeAdded represents the time at + which the taint was added. It is only written + for NoExecute taints. + format: date-time + type: string + value: + description: The taint value corresponding to + the taint key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + mounts: + description: Mounts specifies a list of mount points to be + setup. + items: + description: MountPoints defines input for generated mounts + in cloud-init. + items: + type: string + type: array + type: array + ntp: + description: NTP specifies NTP configuration + properties: + enabled: + description: Enabled specifies whether NTP should be enabled + type: boolean + servers: + description: Servers specifies which NTP servers to use + items: + type: string + type: array + type: object + postKubeadmCommands: + description: PostKubeadmCommands specifies extra commands + to run after kubeadm runs + items: + type: string + type: array + preKubeadmCommands: + description: PreKubeadmCommands specifies extra commands to + run before kubeadm runs + items: + type: string + type: array + useExperimentalRetryJoin: + description: "UseExperimentalRetryJoin replaces a basic kubeadm + command with a shell script with retries for joins. \n This + is meant to be an experimental temporary workaround on some + environments where joins fail due to timing (and other issues). + The long term goal is to add retries to kubeadm proper and + use that functionality. \n This will add about 40KB to userdata + \n For more information, refer to https://github.com/kubernetes-sigs/cluster-api/pull/2763#discussion_r397306055." + type: boolean + users: + description: Users specifies extra users to add + items: + description: User defines the input for a generated user + in cloud-init. + properties: + gecos: + description: Gecos specifies the gecos to use for the + user + type: string + groups: + description: Groups specifies the additional groups + for the user + type: string + homeDir: + description: HomeDir specifies the home directory to + use for the user + type: string + inactive: + description: Inactive specifies whether to mark the + user as inactive + type: boolean + lockPassword: + description: LockPassword specifies if password login + should be disabled + type: boolean + name: + description: Name specifies the user name + type: string + passwd: + description: Passwd specifies a hashed password for + the user + type: string + primaryGroup: + description: PrimaryGroup specifies the primary group + for the user + type: string + shell: + description: Shell specifies the user's shell + type: string + sshAuthorizedKeys: + description: SSHAuthorizedKeys specifies a list of ssh + authorized keys for the user + items: + type: string + type: array + sudo: + description: Sudo specifies a sudo role for the user + type: string + required: + - name + type: object + type: array + verbosity: + description: Verbosity is the number for the kubeadm log level + verbosity. It overrides the `--v` flag in kubeadm commands. + format: int32 + type: integer + type: object + type: object + required: + - template + type: object + type: object + served: false + storage: false - additionalPrinterColumns: - description: Time duration since creation of KubeadmConfigTemplate jsonPath: .metadata.creationTimestamp diff --git a/bootstrap/kubeadm/main.go b/bootstrap/kubeadm/main.go index 5ae2aeff4aff..649d87529cfe 100644 --- a/bootstrap/kubeadm/main.go +++ b/bootstrap/kubeadm/main.go @@ -51,6 +51,7 @@ import ( "sigs.k8s.io/cluster-api/controllers/remote" expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" "sigs.k8s.io/cluster-api/feature" + bootstrapv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3" "sigs.k8s.io/cluster-api/util/flags" "sigs.k8s.io/cluster-api/version" ) @@ -89,6 +90,7 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) _ = expv1.AddToScheme(scheme) + _ = bootstrapv1alpha3.AddToScheme(scheme) _ = bootstrapv1alpha4.AddToScheme(scheme) _ = bootstrapv1.AddToScheme(scheme) } diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring.go b/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring.go new file mode 100644 index 000000000000..efd815445f10 --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring.go @@ -0,0 +1,89 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + "fmt" + "strings" + + "github.com/pkg/errors" + bootstrapapi "k8s.io/cluster-bootstrap/token/api" + bootstraputil "k8s.io/cluster-bootstrap/token/util" +) + +// BootstrapTokenString is a token of the format abcdef.abcdef0123456789 that is used +// for both validation of the practically of the API server from a joining node's point +// of view and as an authentication method for the node in the bootstrap phase of +// "kubeadm join". This token is and should be short-lived. +// +// +kubebuilder:validation:Type=string +type BootstrapTokenString struct { + ID string `json:"-"` + Secret string `json:"-"` +} + +// MarshalJSON implements the json.Marshaler interface. +func (bts BootstrapTokenString) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf("%q", bts.String())), nil +} + +// UnmarshalJSON implements the json.Unmarshaller interface. +func (bts *BootstrapTokenString) UnmarshalJSON(b []byte) error { + // If the token is represented as "", just return quickly without an error + if len(b) == 0 { + return nil + } + + // Remove unnecessary " characters coming from the JSON parser + token := strings.ReplaceAll(string(b), `"`, ``) + // Convert the string Token to a BootstrapTokenString object + newbts, err := NewBootstrapTokenString(token) + if err != nil { + return err + } + bts.ID = newbts.ID + bts.Secret = newbts.Secret + return nil +} + +// String returns the string representation of the BootstrapTokenString. +func (bts BootstrapTokenString) String() string { + if bts.ID != "" && bts.Secret != "" { + return bootstraputil.TokenFromIDAndSecret(bts.ID, bts.Secret) + } + return "" +} + +// NewBootstrapTokenString converts the given Bootstrap Token as a string +// to the BootstrapTokenString object used for serialization/deserialization +// and internal usage. It also automatically validates that the given token +// is of the right format. +func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) { + substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token) + // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works) + if len(substrs) != 3 { + return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern) + } + + return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil +} + +// NewBootstrapTokenStringFromIDAndSecret is a wrapper around NewBootstrapTokenString +// that allows the caller to specify the ID and Secret separately. +func NewBootstrapTokenStringFromIDAndSecret(id, secret string) (*BootstrapTokenString, error) { + return NewBootstrapTokenString(bootstraputil.TokenFromIDAndSecret(id, secret)) +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring_test.go b/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring_test.go new file mode 100644 index 000000000000..821d2a6295b6 --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/bootstraptokenstring_test.go @@ -0,0 +1,223 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + "encoding/json" + "testing" + + "github.com/google/go-cmp/cmp" + . "github.com/onsi/gomega" + "github.com/pkg/errors" +) + +func TestMarshalJSON(t *testing.T) { + var tests = []struct { + bts BootstrapTokenString + expected string + }{ + {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, `"abcdef.abcdef0123456789"`}, + {BootstrapTokenString{ID: "foo", Secret: "bar"}, `"foo.bar"`}, + {BootstrapTokenString{ID: "h", Secret: "b"}, `"h.b"`}, + } + for _, rt := range tests { + t.Run(rt.bts.ID, func(t *testing.T) { + g := NewWithT(t) + + b, err := json.Marshal(rt.bts) + g.Expect(err).ToNot(HaveOccurred()) + g.Expect(b).To(BeEquivalentTo(rt.expected)) + }) + } +} + +func TestUnmarshalJSON(t *testing.T) { + var tests = []struct { + input string + bts *BootstrapTokenString + expectedError bool + }{ + {`"f.s"`, &BootstrapTokenString{}, true}, + {`"abcdef."`, &BootstrapTokenString{}, true}, + {`"abcdef:abcdef0123456789"`, &BootstrapTokenString{}, true}, + {`abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, + {`"abcdef.abcdef0123456789`, &BootstrapTokenString{}, true}, + {`"abcdef.ABCDEF0123456789"`, &BootstrapTokenString{}, true}, + {`"abcdef.abcdef0123456789"`, &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, false}, + {`"123456.aabbccddeeffgghh"`, &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}, false}, + } + for _, rt := range tests { + t.Run(rt.input, func(t *testing.T) { + g := NewWithT(t) + + newbts := &BootstrapTokenString{} + err := json.Unmarshal([]byte(rt.input), newbts) + if rt.expectedError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).ToNot(HaveOccurred()) + } + g.Expect(newbts).To(Equal(rt.bts)) + }) + } +} + +func TestJSONRoundtrip(t *testing.T) { + var tests = []struct { + input string + bts *BootstrapTokenString + }{ + {`"abcdef.abcdef0123456789"`, nil}, + {"", &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, + } + for _, rt := range tests { + t.Run(rt.input, func(t *testing.T) { + g := NewWithT(t) + + g.Expect(roundtrip(rt.input, rt.bts)).To(Succeed()) + }) + } +} + +func roundtrip(input string, bts *BootstrapTokenString) error { + var b []byte + var err error + newbts := &BootstrapTokenString{} + // If string input was specified, roundtrip like this: string -> (unmarshal) -> object -> (marshal) -> string + if input != "" { + if err := json.Unmarshal([]byte(input), newbts); err != nil { + return errors.Wrap(err, "expected no unmarshal error, got error") + } + if b, err = json.Marshal(newbts); err != nil { + return errors.Wrap(err, "expected no marshal error, got error") + } + if input != string(b) { + return errors.Errorf( + "expected token: %s\n\t actual: %s", + input, + string(b), + ) + } + } else { // Otherwise, roundtrip like this: object -> (marshal) -> string -> (unmarshal) -> object + if b, err = json.Marshal(bts); err != nil { + return errors.Wrap(err, "expected no marshal error, got error") + } + if err := json.Unmarshal(b, newbts); err != nil { + return errors.Wrap(err, "expected no unmarshal error, got error") + } + if diff := cmp.Diff(bts, newbts); diff != "" { + return errors.Errorf( + "expected object: %v\n\t actual: %v\n\t got diff: %v", + bts, + newbts, + diff, + ) + } + } + return nil +} + +func TestTokenFromIDAndSecret(t *testing.T) { + var tests = []struct { + bts BootstrapTokenString + expected string + }{ + {BootstrapTokenString{ID: "foo", Secret: "bar"}, "foo.bar"}, + {BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}, "abcdef.abcdef0123456789"}, + {BootstrapTokenString{ID: "h", Secret: "b"}, "h.b"}, + } + for _, rt := range tests { + t.Run(rt.bts.ID, func(t *testing.T) { + g := NewWithT(t) + + g.Expect(rt.bts.String()).To(Equal(rt.expected)) + }) + } +} + +func TestNewBootstrapTokenString(t *testing.T) { + var tests = []struct { + token string + expectedError bool + bts *BootstrapTokenString + }{ + {token: "", expectedError: true, bts: nil}, + {token: ".", expectedError: true, bts: nil}, + {token: "1234567890123456789012", expectedError: true, bts: nil}, // invalid parcel size + {token: "12345.1234567890123456", expectedError: true, bts: nil}, // invalid parcel size + {token: ".1234567890123456", expectedError: true, bts: nil}, // invalid parcel size + {token: "123456.", expectedError: true, bts: nil}, // invalid parcel size + {token: "123456:1234567890.123456", expectedError: true, bts: nil}, // invalid separation + {token: "abcdef:1234567890123456", expectedError: true, bts: nil}, // invalid separation + {token: "Abcdef.1234567890123456", expectedError: true, bts: nil}, // invalid token id + {token: "123456.AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret + {token: "123456.AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character + {token: "abc*ef.1234567890123456", expectedError: true, bts: nil}, // invalid character + {token: "abcdef.1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, + {token: "123456.aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, + {token: "abcdef.abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, + {token: "123456.1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, + } + for _, rt := range tests { + t.Run(rt.token, func(t *testing.T) { + g := NewWithT(t) + + actual, err := NewBootstrapTokenString(rt.token) + if rt.expectedError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).ToNot(HaveOccurred()) + } + g.Expect(actual).To(Equal(rt.bts)) + }) + } +} + +func TestNewBootstrapTokenStringFromIDAndSecret(t *testing.T) { + var tests = []struct { + id, secret string + expectedError bool + bts *BootstrapTokenString + }{ + {id: "", secret: "", expectedError: true, bts: nil}, + {id: "1234567890123456789012", secret: "", expectedError: true, bts: nil}, // invalid parcel size + {id: "12345", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size + {id: "", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid parcel size + {id: "123456", secret: "", expectedError: true, bts: nil}, // invalid parcel size + {id: "Abcdef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid token id + {id: "123456", secret: "AABBCCDDEEFFGGHH", expectedError: true, bts: nil}, // invalid token secret + {id: "123456", secret: "AABBCCD-EEFFGGHH", expectedError: true, bts: nil}, // invalid character + {id: "abc*ef", secret: "1234567890123456", expectedError: true, bts: nil}, // invalid character + {id: "abcdef", secret: "1234567890123456", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "1234567890123456"}}, + {id: "123456", secret: "aabbccddeeffgghh", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "aabbccddeeffgghh"}}, + {id: "abcdef", secret: "abcdef0123456789", expectedError: false, bts: &BootstrapTokenString{ID: "abcdef", Secret: "abcdef0123456789"}}, + {id: "123456", secret: "1234560123456789", expectedError: false, bts: &BootstrapTokenString{ID: "123456", Secret: "1234560123456789"}}, + } + for _, rt := range tests { + t.Run(rt.id, func(t *testing.T) { + g := NewWithT(t) + + actual, err := NewBootstrapTokenStringFromIDAndSecret(rt.id, rt.secret) + if rt.expectedError { + g.Expect(err).To(HaveOccurred()) + } else { + g.Expect(err).ToNot(HaveOccurred()) + } + g.Expect(actual).To(Equal(rt.bts)) + }) + } +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/conversion.go b/bootstrap/kubeadm/types/upstreamv1beta1/conversion.go new file mode 100644 index 000000000000..e893686d52e1 --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/conversion.go @@ -0,0 +1,97 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + apimachineryconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" +) + +// ConvertTo converts this ClusterConfiguration to the Hub version (v1alpha4). +func (src *ClusterConfiguration) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.ClusterConfiguration) + return Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(src, dst, nil) +} + +// ConvertFrom converts from the ClusterConfiguration Hub version (v1alpha4) to this version. +func (dst *ClusterConfiguration) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.ClusterConfiguration) + return Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(src, dst, nil) +} + +// ConvertTo converts this ClusterStatus to the Hub version (v1alpha4). +func (src *ClusterStatus) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.ClusterStatus) + return Convert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus(src, dst, nil) +} + +// ConvertFrom converts from the ClusterStatus Hub version (v1alpha4) to this version. +func (dst *ClusterStatus) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.ClusterStatus) + return Convert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus(src, dst, nil) +} + +// ConvertTo converts this InitConfiguration to the Hub version (v1alpha4). +func (src *InitConfiguration) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.InitConfiguration) + return Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(src, dst, nil) +} + +// ConvertFrom converts from the InitConfiguration Hub version (v1alpha4) to this version. +func (dst *InitConfiguration) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.InitConfiguration) + return Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(src, dst, nil) +} + +// ConvertTo converts this JoinConfiguration to the Hub version (v1alpha4). +func (src *JoinConfiguration) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.JoinConfiguration) + return Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(src, dst, nil) +} + +// ConvertFrom converts from the JoinConfiguration Hub version (v1alpha4) to this version. +func (dst *JoinConfiguration) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.JoinConfiguration) + return Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(src, dst, nil) +} + +func Convert_upstreamv1beta1_DNS_To_v1beta1_DNS(in *DNS, out *bootstrapv1.DNS, s apimachineryconversion.Scope) error { + // DNS.Type was removed in v1alpha4 because only CoreDNS is supported, dropping this info. + return autoConvert_upstreamv1beta1_DNS_To_v1beta1_DNS(in, out, s) +} + +func Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in *ClusterConfiguration, out *bootstrapv1.ClusterConfiguration, s apimachineryconversion.Scope) error { + // ClusterConfiguration.UseHyperKubeImage was removed in kubeadm v1alpha4 API + return autoConvert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in, out, s) +} + +func Convert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(in *bootstrapv1.NodeRegistrationOptions, out *NodeRegistrationOptions, s apimachineryconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return autoConvert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(in, out, s) +} + +func Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(in *bootstrapv1.InitConfiguration, out *InitConfiguration, s apimachineryconversion.Scope) error { + // InitConfiguration.Patches does not exist in kubeadm v1beta1 API + return autoConvert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(in, out, s) +} + +func Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(in *bootstrapv1.JoinConfiguration, out *JoinConfiguration, s apimachineryconversion.Scope) error { + // JoinConfiguration.Patches does not exist in kubeadm v1beta1 API + return autoConvert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(in, out, s) +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/conversion_test.go b/bootstrap/kubeadm/types/upstreamv1beta1/conversion_test.go new file mode 100644 index 000000000000..13d1f18319ac --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/conversion_test.go @@ -0,0 +1,120 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + "testing" + + fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for ClusterConfiguration", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.ClusterConfiguration{}, + Spoke: &ClusterConfiguration{}, + // NOTE: Kubeadm types does not have ObjectMeta, so we are required to skip data annotation cleanup in the spoke-hub-spoke round trip test. + SkipSpokeAnnotationCleanup: true, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) + t.Run("for ClusterStatus", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.ClusterStatus{}, + Spoke: &ClusterStatus{}, + // NOTE: Kubeadm types does not have ObjectMeta, so we are required to skip data annotation cleanup in the spoke-hub-spoke round trip test. + SkipSpokeAnnotationCleanup: true, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) + t.Run("for InitConfiguration", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.InitConfiguration{}, + Spoke: &InitConfiguration{}, + // NOTE: Kubeadm types does not have ObjectMeta, so we are required to skip data annotation cleanup in the spoke-hub-spoke round trip test. + SkipSpokeAnnotationCleanup: true, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) + t.Run("for JoinConfiguration", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.JoinConfiguration{}, + Spoke: &JoinConfiguration{}, + // NOTE: Kubeadm types does not have ObjectMeta, so we are required to skip data annotation cleanup in the spoke-hub-spoke round trip test. + SkipSpokeAnnotationCleanup: true, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) +} + +func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + dnsFuzzer, + clusterConfigurationFuzzer, + kubeadmNodeRegistrationOptionsFuzzer, + kubeadmInitConfigurationFuzzer, + kubeadmJoinConfigurationFuzzer, + } +} + +func dnsFuzzer(obj *DNS, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // DNS.Type does not exists in v1alpha4, so setting it to empty string in order to avoid v1beta1 --> v1alpha4 --> v1beta1 round trip errors. + obj.Type = "" +} + +func clusterConfigurationFuzzer(obj *ClusterConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // ClusterConfiguration.UseHyperKubeImage has been removed in v1alpha4, so setting it to false in order to avoid v1beta1 --> v1alpha4 --> v1beta1 round trip errors. + obj.UseHyperKubeImage = false +} + +func kubeadmNodeRegistrationOptionsFuzzer(obj *bootstrapv1.NodeRegistrationOptions, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1alpha4 --> v1beta1 -> v1alpha4 round trip errors. + obj.IgnorePreflightErrors = nil + + // NodeRegistrationOptions.ImagePullPolicy does not exist in + // kubeadm v1beta1 API, so setting it to empty in order to + // avoid round trip errors. + obj.ImagePullPolicy = "" +} + +func kubeadmInitConfigurationFuzzer(obj *bootstrapv1.InitConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // InitConfiguration.Patches does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1beta1 --> upstream v1beta1 -> v1beta1 round trip errors. + obj.Patches = nil + + // InitConfiguration.SkipPhases does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1beta1 --> upstream v1beta1 -> v1beta1 round trip errors. + obj.SkipPhases = nil +} + +func kubeadmJoinConfigurationFuzzer(obj *bootstrapv1.JoinConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // JoinConfiguration.Patches does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1beta1 --> upstream v1beta1 -> v1beta1 round trip errors. + obj.Patches = nil + + // JoinConfiguration.SkipPhases does not exist in kubeadm v1beta1 API, so setting it to nil in order to avoid + // v1beta1 --> upstream v1beta1 -> v1beta1 round trip errors. + obj.SkipPhases = nil +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/doc.go b/bootstrap/kubeadm/types/upstreamv1beta1/doc.go new file mode 100644 index 000000000000..97d1211d0e5e --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package upstreamv1beta1 contains a mirror of kubeadm API v1beta1 API, required because it is not possible to import k/K. +// +// IMPORTANT: Do not change these files! +// IMPORTANT: only for KubeadmConfig serialization/deserialization, and should not be used for other purposes. +// +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1 +// +k8s:deepcopy-gen=package +package upstreamv1beta1 // import "sigs.k8s.io/cluster-api/bootstrap/kubeadm/kubeadm/v1beta1" diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/groupversion_info.go b/bootstrap/kubeadm/types/upstreamv1beta1/groupversion_info.go new file mode 100644 index 000000000000..8cb7be6e0fb8 --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/groupversion_info.go @@ -0,0 +1,35 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "kubeadm.k8s.io", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/types.go b/bootstrap/kubeadm/types/upstreamv1beta1/types.go new file mode 100644 index 000000000000..3f90b4611fcc --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/types.go @@ -0,0 +1,426 @@ +/* +Copyright 2018 The Kubernetes Authors. + +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. +*/ + +package upstreamv1beta1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// InitConfiguration contains a list of elements that is specific "kubeadm init"-only runtime +// information. +type InitConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create. + // This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature + // +optional + BootstrapTokens []BootstrapToken `json:"bootstrapTokens,omitempty"` + + // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster. + // When used in the context of control plane nodes, NodeRegistration should remain consistent + // across both InitConfiguration and JoinConfiguration + // +optional + NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` + + // LocalAPIEndpoint represents the endpoint of the API server instance that's deployed on this control plane node + // In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint in the sense that ControlPlaneEndpoint + // is the global endpoint for the cluster, which then loadbalances the requests to each individual API server. This + // configuration object lets you customize what IP/DNS name and port the local API server advertises it's accessible + // on. By default, kubeadm tries to auto-detect the IP of the default interface and use that, but in case that process + // fails you may set the desired value here. + // +optional + LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster. +type ClusterConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // Etcd holds configuration for etcd. + // NB: This value defaults to a Local (stacked) etcd + // +optional + Etcd Etcd `json:"etcd,omitempty"` + + // Networking holds configuration for the networking topology of the cluster. + // NB: This value defaults to the Cluster object spec.clusterNetwork. + // +optional + Networking Networking `json:"networking,omitempty"` + + // KubernetesVersion is the target version of the control plane. + // NB: This value defaults to the Machine object spec.version + // +optional + KubernetesVersion string `json:"kubernetesVersion,omitempty"` + + // ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it + // can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port. + // In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort + // are used; in case the ControlPlaneEndpoint is specified but without a TCP port, + // the BindPort is used. + // Possible usages are: + // e.g. In a cluster with more than one control plane instances, this field should be + // assigned the address of the external load balancer in front of the + // control plane instances. + // e.g. in environments with enforced node recycling, the ControlPlaneEndpoint + // could be used for assigning a stable DNS to the control plane. + // NB: This value defaults to the first value in the Cluster object status.apiEndpoints array. + // +optional + ControlPlaneEndpoint string `json:"controlPlaneEndpoint,omitempty"` + + // APIServer contains extra settings for the API server control plane component + // +optional + APIServer APIServer `json:"apiServer,omitempty"` + + // ControllerManager contains extra settings for the controller manager control plane component + // +optional + ControllerManager ControlPlaneComponent `json:"controllerManager,omitempty"` + + // Scheduler contains extra settings for the scheduler control plane component + // +optional + Scheduler ControlPlaneComponent `json:"scheduler,omitempty"` + + // DNS defines the options for the DNS add-on installed in the cluster. + // +optional + DNS DNS `json:"dns,omitempty"` + + // CertificatesDir specifies where to store or look for all required certificates. + // NB: if not provided, this will default to `/etc/kubernetes/pki` + // +optional + CertificatesDir string `json:"certificatesDir,omitempty"` + + // ImageRepository sets the container registry to pull images from. + // If empty, `k8s.gcr.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/` or `ci-cross/`) + // `gcr.io/k8s-staging-ci-images` will be used as a default for control plane components and for kube-proxy, while `k8s.gcr.io` + // will be used for all the other images. + // +optional + ImageRepository string `json:"imageRepository,omitempty"` + + // UseHyperKubeImage controls if hyperkube should be used for Kubernetes components instead of their respective separate images + // +optional + UseHyperKubeImage bool `json:"useHyperKubeImage,omitempty"` + + // FeatureGates enabled by the user. + // +optional + FeatureGates map[string]bool `json:"featureGates,omitempty"` + + // The cluster name + // +optional + ClusterName string `json:"clusterName,omitempty"` +} + +// ControlPlaneComponent holds settings common to control plane component of the cluster. +type ControlPlaneComponent struct { + // ExtraArgs is an extra set of flags to pass to the control plane component. + // TODO: This is temporary and ideally we would like to switch all components to + // use ComponentConfig + ConfigMaps. + ExtraArgs map[string]string `json:"extraArgs,omitempty"` + + // ExtraVolumes is an extra set of host volumes, mounted to the control plane component. + ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"` +} + +// APIServer holds settings necessary for API server deployments in the cluster. +type APIServer struct { + ControlPlaneComponent `json:",inline"` + + // CertSANs sets extra Subject Alternative Names for the API Server signing cert. + CertSANs []string `json:"certSANs,omitempty"` + + // TimeoutForControlPlane controls the timeout that we use for API server to appear + TimeoutForControlPlane *metav1.Duration `json:"timeoutForControlPlane,omitempty"` +} + +// DNSAddOnType defines string identifying DNS add-on types. +type DNSAddOnType string + +const ( + // CoreDNS add-on type. + CoreDNS DNSAddOnType = "CoreDNS" + + // KubeDNS add-on type. + KubeDNS DNSAddOnType = "kube-dns" +) + +// DNS defines the DNS addon that should be used in the cluster. +type DNS struct { + // Type defines the DNS add-on to be used + // +optional + Type DNSAddOnType `json:"type,omitempty"` + + // ImageMeta allows to customize the image used for the DNS component + ImageMeta `json:",inline"` +} + +// ImageMeta allows to customize the image used for components that are not +// originated from the Kubernetes/Kubernetes release process. +type ImageMeta struct { + // ImageRepository sets the container registry to pull images from. + // if not set, the ImageRepository defined in ClusterConfiguration will be used instead. + ImageRepository string `json:"imageRepository,omitempty"` + + // ImageTag allows to specify a tag for the image. + // In case this value is set, kubeadm does not change automatically the version of the above components during upgrades. + ImageTag string `json:"imageTag,omitempty"` + + //TODO: evaluate if we need also a ImageName based on user feedbacks +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config +// ConfigMap in the cluster, and then updated by kubeadm when additional control plane instance joins or leaves the cluster. +type ClusterStatus struct { + metav1.TypeMeta `json:",inline"` + + // APIEndpoints currently available in the cluster, one for each control plane/api server instance. + // The key of the map is the IP of the host's default interface + APIEndpoints map[string]APIEndpoint `json:"apiEndpoints"` +} + +// APIEndpoint struct contains elements of API server instance deployed on a node. +type APIEndpoint struct { + // AdvertiseAddress sets the IP address for the API server to advertise. + AdvertiseAddress string `json:"advertiseAddress"` + + // BindPort sets the secure port for the API Server to bind to. + // Defaults to 6443. + BindPort int32 `json:"bindPort"` +} + +// NodeRegistrationOptions holds fields that relate to registering a new control-plane or node to the cluster, either via "kubeadm init" or "kubeadm join". +type NodeRegistrationOptions struct { + + // Name is the `.Metadata.Name` field of the Node API object that will be created in this `kubeadm init` or `kubeadm join` operation. + // This field is also used in the CommonName field of the kubelet's client certificate to the API server. + // Defaults to the hostname of the node if not provided. + // +optional + Name string `json:"name,omitempty"` + + // CRISocket is used to retrieve container runtime info. This information will be annotated to the Node API object, for later re-use + // +optional + CRISocket string `json:"criSocket,omitempty"` + + // Taints specifies the taints the Node API object should be registered with. If this field is unset, i.e. nil, in the `kubeadm init` process + // it will be defaulted to []v1.Taint{'node-role.kubernetes.io/master=""'}. If you don't want to taint your control-plane node, set this field to an + // empty slice, i.e. `taints: {}` in the YAML file. This field is solely used for Node registration. + // +optional + Taints []corev1.Taint `json:"taints,omitempty"` + + // KubeletExtraArgs passes through extra arguments to the kubelet. The arguments here are passed to the kubelet command line via the environment file + // kubeadm writes at runtime for the kubelet to source. This overrides the generic base-level configuration in the kubelet-config-1.X ConfigMap + // Flags have higher priority when parsing. These values are local and specific to the node kubeadm is executing on. + // +optional + KubeletExtraArgs map[string]string `json:"kubeletExtraArgs,omitempty"` +} + +// Networking contains elements describing cluster's networking configuration. +type Networking struct { + // ServiceSubnet is the subnet used by k8s services. + // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.pods.cidrBlocks, or + // to "10.96.0.0/12" if that's unset. + // +optional + ServiceSubnet string `json:"serviceSubnet,omitempty"` + // PodSubnet is the subnet used by pods. + // If unset, the API server will not allocate CIDR ranges for every node. + // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.services.cidrBlocks if that is set + // +optional + PodSubnet string `json:"podSubnet,omitempty"` + // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local". + // +optional + DNSDomain string `json:"dnsDomain,omitempty"` +} + +// BootstrapToken describes one bootstrap token, stored as a Secret in the cluster. +type BootstrapToken struct { + // Token is used for establishing bidirectional trust between nodes and control-planes. + // Used for joining nodes in the cluster. + Token *BootstrapTokenString `json:"token"` + // Description sets a human-friendly message why this token exists and what it's used + // for, so other administrators can know its purpose. + Description string `json:"description,omitempty"` + // TTL defines the time to live for this token. Defaults to 24h. + // Expires and TTL are mutually exclusive. + TTL *metav1.Duration `json:"ttl,omitempty"` + // Expires specifies the timestamp when this token expires. Defaults to being set + // dynamically at runtime based on the TTL. Expires and TTL are mutually exclusive. + Expires *metav1.Time `json:"expires,omitempty"` + // Usages describes the ways in which this token can be used. Can by default be used + // for establishing bidirectional trust, but that can be changed here. + Usages []string `json:"usages,omitempty"` + // Groups specifies the extra groups that this token will authenticate as when/if + // used for authentication + Groups []string `json:"groups,omitempty"` +} + +// Etcd contains elements describing Etcd configuration. +type Etcd struct { + + // Local provides configuration knobs for configuring the local etcd instance + // Local and External are mutually exclusive + Local *LocalEtcd `json:"local,omitempty"` + + // External describes how to connect to an external etcd cluster + // Local and External are mutually exclusive + External *ExternalEtcd `json:"external,omitempty"` +} + +// LocalEtcd describes that kubeadm should run an etcd cluster locally. +type LocalEtcd struct { + // ImageMeta allows to customize the container used for etcd + ImageMeta `json:",inline"` + + // DataDir is the directory etcd will place its data. + // Defaults to "/var/lib/etcd". + // +optional + DataDir string `json:"dataDir,omitempty"` + + // ExtraArgs are extra arguments provided to the etcd binary + // when run inside a static pod. + ExtraArgs map[string]string `json:"extraArgs,omitempty"` + + // ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert. + ServerCertSANs []string `json:"serverCertSANs,omitempty"` + // PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert. + PeerCertSANs []string `json:"peerCertSANs,omitempty"` +} + +// ExternalEtcd describes an external etcd cluster. +// Kubeadm has no knowledge of where certificate files live and they must be supplied. +type ExternalEtcd struct { + // Endpoints of etcd members. Required for ExternalEtcd. + Endpoints []string `json:"endpoints"` + + // CAFile is an SSL Certificate Authority file used to secure etcd communication. + // Required if using a TLS connection. + CAFile string `json:"caFile"` + + // CertFile is an SSL certification file used to secure etcd communication. + // Required if using a TLS connection. + CertFile string `json:"certFile"` + + // KeyFile is an SSL key file used to secure etcd communication. + // Required if using a TLS connection. + KeyFile string `json:"keyFile"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// JoinConfiguration contains elements describing a particular node. +type JoinConfiguration struct { + metav1.TypeMeta `json:",inline"` + + // NodeRegistration holds fields that relate to registering the new control-plane node to the cluster. + // When used in the context of control plane nodes, NodeRegistration should remain consistent + // across both InitConfiguration and JoinConfiguration + // +optional + NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"` + + // CACertPath is the path to the SSL certificate authority used to + // secure comunications between node and control-plane. + // Defaults to "/etc/kubernetes/pki/ca.crt". + // +optional + // TODO: revisit when there is defaulting from k/k + CACertPath string `json:"caCertPath,omitempty"` + + // Discovery specifies the options for the kubelet to use during the TLS Bootstrap process + // +optional + // TODO: revisit when there is defaulting from k/k + Discovery Discovery `json:"discovery,omitempty"` + + // ControlPlane defines the additional control plane instance to be deployed on the joining node. + // If nil, no additional control plane instance will be deployed. + // +optional + ControlPlane *JoinControlPlane `json:"controlPlane,omitempty"` +} + +// JoinControlPlane contains elements describing an additional control plane instance to be deployed on the joining node. +type JoinControlPlane struct { + // LocalAPIEndpoint represents the endpoint of the API server instance to be deployed on this node. + LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"` +} + +// Discovery specifies the options for the kubelet to use during the TLS Bootstrap process. +type Discovery struct { + // BootstrapToken is used to set the options for bootstrap token based discovery + // BootstrapToken and File are mutually exclusive + BootstrapToken *BootstrapTokenDiscovery `json:"bootstrapToken,omitempty"` + + // File is used to specify a file or URL to a kubeconfig file from which to load cluster information + // BootstrapToken and File are mutually exclusive + File *FileDiscovery `json:"file,omitempty"` + + // TLSBootstrapToken is a token used for TLS bootstrapping. + // If .BootstrapToken is set, this field is defaulted to .BootstrapToken.Token, but can be overridden. + // If .File is set, this field **must be set** in case the KubeConfigFile does not contain any other authentication information + // +optional + // TODO: revisit when there is defaulting from k/k + TLSBootstrapToken string `json:"tlsBootstrapToken,omitempty"` + + // Timeout modifies the discovery timeout + Timeout *metav1.Duration `json:"timeout,omitempty"` +} + +// BootstrapTokenDiscovery is used to set the options for bootstrap token based discovery. +type BootstrapTokenDiscovery struct { + // Token is a token used to validate cluster information + // fetched from the control-plane. + Token string `json:"token"` + + // APIServerEndpoint is an IP or domain name to the API server from which info will be fetched. + APIServerEndpoint string `json:"apiServerEndpoint,omitempty"` + + // CACertHashes specifies a set of public key pins to verify + // when token-based discovery is used. The root CA found during discovery + // must match one of these values. Specifying an empty set disables root CA + // pinning, which can be unsafe. Each hash is specified as ":", + // where the only currently supported type is "sha256". This is a hex-encoded + // SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded + // ASN.1. These hashes can be calculated using, for example, OpenSSL: + // openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex + CACertHashes []string `json:"caCertHashes,omitempty"` + + // UnsafeSkipCAVerification allows token-based discovery + // without CA verification via CACertHashes. This can weaken + // the security of kubeadm since other nodes can impersonate the control-plane. + UnsafeSkipCAVerification bool `json:"unsafeSkipCAVerification"` +} + +// FileDiscovery is used to specify a file or URL to a kubeconfig file from which to load cluster information. +type FileDiscovery struct { + // KubeConfigPath is used to specify the actual file path or URL to the kubeconfig file from which to load cluster information + KubeConfigPath string `json:"kubeConfigPath"` +} + +// HostPathMount contains elements describing volumes that are mounted from the +// host. +type HostPathMount struct { + // Name of the volume inside the pod template. + Name string `json:"name"` + // HostPath is the path in the host that will be mounted inside + // the pod. + HostPath string `json:"hostPath"` + // MountPath is the path inside the pod where hostPath will be mounted. + MountPath string `json:"mountPath"` + // ReadOnly controls write access to the volume + ReadOnly bool `json:"readOnly,omitempty"` + // PathType is the type of the HostPath. + PathType corev1.HostPathType `json:"pathType,omitempty"` +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go new file mode 100644 index 000000000000..0497d927b800 --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.conversion.go @@ -0,0 +1,811 @@ +//go:build !ignore_autogenerated_kubeadm_types +// +build !ignore_autogenerated_kubeadm_types + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package upstreamv1beta1 + +import ( + unsafe "unsafe" + + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + v1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*APIEndpoint)(nil), (*v1beta1.APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(a.(*APIEndpoint), b.(*v1beta1.APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.APIEndpoint)(nil), (*APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(a.(*v1beta1.APIEndpoint), b.(*APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*APIServer)(nil), (*v1beta1.APIServer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_APIServer_To_v1beta1_APIServer(a.(*APIServer), b.(*v1beta1.APIServer), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.APIServer)(nil), (*APIServer)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIServer_To_upstreamv1beta1_APIServer(a.(*v1beta1.APIServer), b.(*APIServer), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BootstrapToken)(nil), (*v1beta1.BootstrapToken)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_BootstrapToken_To_v1beta1_BootstrapToken(a.(*BootstrapToken), b.(*v1beta1.BootstrapToken), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BootstrapToken)(nil), (*BootstrapToken)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BootstrapToken_To_upstreamv1beta1_BootstrapToken(a.(*v1beta1.BootstrapToken), b.(*BootstrapToken), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BootstrapTokenDiscovery)(nil), (*v1beta1.BootstrapTokenDiscovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery(a.(*BootstrapTokenDiscovery), b.(*v1beta1.BootstrapTokenDiscovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BootstrapTokenDiscovery)(nil), (*BootstrapTokenDiscovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BootstrapTokenDiscovery_To_upstreamv1beta1_BootstrapTokenDiscovery(a.(*v1beta1.BootstrapTokenDiscovery), b.(*BootstrapTokenDiscovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BootstrapTokenString)(nil), (*v1beta1.BootstrapTokenString)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_BootstrapTokenString_To_v1beta1_BootstrapTokenString(a.(*BootstrapTokenString), b.(*v1beta1.BootstrapTokenString), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.BootstrapTokenString)(nil), (*BootstrapTokenString)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_BootstrapTokenString_To_upstreamv1beta1_BootstrapTokenString(a.(*v1beta1.BootstrapTokenString), b.(*BootstrapTokenString), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterConfiguration)(nil), (*ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(a.(*v1beta1.ClusterConfiguration), b.(*ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterStatus)(nil), (*v1beta1.ClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus(a.(*ClusterStatus), b.(*v1beta1.ClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterStatus)(nil), (*ClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus(a.(*v1beta1.ClusterStatus), b.(*ClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ControlPlaneComponent)(nil), (*v1beta1.ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(a.(*ControlPlaneComponent), b.(*v1beta1.ControlPlaneComponent), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ControlPlaneComponent)(nil), (*ControlPlaneComponent)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(a.(*v1beta1.ControlPlaneComponent), b.(*ControlPlaneComponent), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DNS)(nil), (*DNS)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DNS_To_upstreamv1beta1_DNS(a.(*v1beta1.DNS), b.(*DNS), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Discovery)(nil), (*v1beta1.Discovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_Discovery_To_v1beta1_Discovery(a.(*Discovery), b.(*v1beta1.Discovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Discovery)(nil), (*Discovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Discovery_To_upstreamv1beta1_Discovery(a.(*v1beta1.Discovery), b.(*Discovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Etcd)(nil), (*v1beta1.Etcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_Etcd_To_v1beta1_Etcd(a.(*Etcd), b.(*v1beta1.Etcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Etcd)(nil), (*Etcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Etcd_To_upstreamv1beta1_Etcd(a.(*v1beta1.Etcd), b.(*Etcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ExternalEtcd)(nil), (*v1beta1.ExternalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ExternalEtcd_To_v1beta1_ExternalEtcd(a.(*ExternalEtcd), b.(*v1beta1.ExternalEtcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ExternalEtcd)(nil), (*ExternalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ExternalEtcd_To_upstreamv1beta1_ExternalEtcd(a.(*v1beta1.ExternalEtcd), b.(*ExternalEtcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*FileDiscovery)(nil), (*v1beta1.FileDiscovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_FileDiscovery_To_v1beta1_FileDiscovery(a.(*FileDiscovery), b.(*v1beta1.FileDiscovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.FileDiscovery)(nil), (*FileDiscovery)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_FileDiscovery_To_upstreamv1beta1_FileDiscovery(a.(*v1beta1.FileDiscovery), b.(*FileDiscovery), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*HostPathMount)(nil), (*v1beta1.HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_HostPathMount_To_v1beta1_HostPathMount(a.(*HostPathMount), b.(*v1beta1.HostPathMount), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.HostPathMount)(nil), (*HostPathMount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_HostPathMount_To_upstreamv1beta1_HostPathMount(a.(*v1beta1.HostPathMount), b.(*HostPathMount), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ImageMeta)(nil), (*v1beta1.ImageMeta)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(a.(*ImageMeta), b.(*v1beta1.ImageMeta), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ImageMeta)(nil), (*ImageMeta)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(a.(*v1beta1.ImageMeta), b.(*ImageMeta), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*InitConfiguration)(nil), (*v1beta1.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(a.(*InitConfiguration), b.(*v1beta1.InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*JoinConfiguration)(nil), (*v1beta1.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(a.(*JoinConfiguration), b.(*v1beta1.JoinConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*JoinControlPlane)(nil), (*v1beta1.JoinControlPlane)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_JoinControlPlane_To_v1beta1_JoinControlPlane(a.(*JoinControlPlane), b.(*v1beta1.JoinControlPlane), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.JoinControlPlane)(nil), (*JoinControlPlane)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_JoinControlPlane_To_upstreamv1beta1_JoinControlPlane(a.(*v1beta1.JoinControlPlane), b.(*JoinControlPlane), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*LocalEtcd)(nil), (*v1beta1.LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_LocalEtcd_To_v1beta1_LocalEtcd(a.(*LocalEtcd), b.(*v1beta1.LocalEtcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.LocalEtcd)(nil), (*LocalEtcd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_LocalEtcd_To_upstreamv1beta1_LocalEtcd(a.(*v1beta1.LocalEtcd), b.(*LocalEtcd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Networking)(nil), (*v1beta1.Networking)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_Networking_To_v1beta1_Networking(a.(*Networking), b.(*v1beta1.Networking), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Networking)(nil), (*Networking)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Networking_To_upstreamv1beta1_Networking(a.(*v1beta1.Networking), b.(*Networking), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*NodeRegistrationOptions)(nil), (*v1beta1.NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(a.(*NodeRegistrationOptions), b.(*v1beta1.NodeRegistrationOptions), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ClusterConfiguration)(nil), (*v1beta1.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(a.(*ClusterConfiguration), b.(*v1beta1.ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*DNS)(nil), (*v1beta1.DNS)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_DNS_To_v1beta1_DNS(a.(*DNS), b.(*v1beta1.DNS), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.InitConfiguration)(nil), (*InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(a.(*v1beta1.InitConfiguration), b.(*InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.JoinConfiguration)(nil), (*JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(a.(*v1beta1.JoinConfiguration), b.(*JoinConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.NodeRegistrationOptions)(nil), (*NodeRegistrationOptions)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(a.(*v1beta1.NodeRegistrationOptions), b.(*NodeRegistrationOptions), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + out.AdvertiseAddress = in.AdvertiseAddress + out.BindPort = in.BindPort + return nil +} + +// Convert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint is an autogenerated conversion function. +func Convert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(in, out, s) +} + +func autoConvert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + out.AdvertiseAddress = in.AdvertiseAddress + out.BindPort = in.BindPort + return nil +} + +// Convert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint is an autogenerated conversion function. +func Convert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + return autoConvert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(in, out, s) +} + +func autoConvert_upstreamv1beta1_APIServer_To_v1beta1_APIServer(in *APIServer, out *v1beta1.APIServer, s conversion.Scope) error { + if err := Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.ControlPlaneComponent, &out.ControlPlaneComponent, s); err != nil { + return err + } + out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs)) + out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane)) + return nil +} + +// Convert_upstreamv1beta1_APIServer_To_v1beta1_APIServer is an autogenerated conversion function. +func Convert_upstreamv1beta1_APIServer_To_v1beta1_APIServer(in *APIServer, out *v1beta1.APIServer, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_APIServer_To_v1beta1_APIServer(in, out, s) +} + +func autoConvert_v1beta1_APIServer_To_upstreamv1beta1_APIServer(in *v1beta1.APIServer, out *APIServer, s conversion.Scope) error { + if err := Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(&in.ControlPlaneComponent, &out.ControlPlaneComponent, s); err != nil { + return err + } + out.CertSANs = *(*[]string)(unsafe.Pointer(&in.CertSANs)) + out.TimeoutForControlPlane = (*v1.Duration)(unsafe.Pointer(in.TimeoutForControlPlane)) + return nil +} + +// Convert_v1beta1_APIServer_To_upstreamv1beta1_APIServer is an autogenerated conversion function. +func Convert_v1beta1_APIServer_To_upstreamv1beta1_APIServer(in *v1beta1.APIServer, out *APIServer, s conversion.Scope) error { + return autoConvert_v1beta1_APIServer_To_upstreamv1beta1_APIServer(in, out, s) +} + +func autoConvert_upstreamv1beta1_BootstrapToken_To_v1beta1_BootstrapToken(in *BootstrapToken, out *v1beta1.BootstrapToken, s conversion.Scope) error { + out.Token = (*v1beta1.BootstrapTokenString)(unsafe.Pointer(in.Token)) + out.Description = in.Description + out.TTL = (*v1.Duration)(unsafe.Pointer(in.TTL)) + out.Expires = (*v1.Time)(unsafe.Pointer(in.Expires)) + out.Usages = *(*[]string)(unsafe.Pointer(&in.Usages)) + out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups)) + return nil +} + +// Convert_upstreamv1beta1_BootstrapToken_To_v1beta1_BootstrapToken is an autogenerated conversion function. +func Convert_upstreamv1beta1_BootstrapToken_To_v1beta1_BootstrapToken(in *BootstrapToken, out *v1beta1.BootstrapToken, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_BootstrapToken_To_v1beta1_BootstrapToken(in, out, s) +} + +func autoConvert_v1beta1_BootstrapToken_To_upstreamv1beta1_BootstrapToken(in *v1beta1.BootstrapToken, out *BootstrapToken, s conversion.Scope) error { + out.Token = (*BootstrapTokenString)(unsafe.Pointer(in.Token)) + out.Description = in.Description + out.TTL = (*v1.Duration)(unsafe.Pointer(in.TTL)) + out.Expires = (*v1.Time)(unsafe.Pointer(in.Expires)) + out.Usages = *(*[]string)(unsafe.Pointer(&in.Usages)) + out.Groups = *(*[]string)(unsafe.Pointer(&in.Groups)) + return nil +} + +// Convert_v1beta1_BootstrapToken_To_upstreamv1beta1_BootstrapToken is an autogenerated conversion function. +func Convert_v1beta1_BootstrapToken_To_upstreamv1beta1_BootstrapToken(in *v1beta1.BootstrapToken, out *BootstrapToken, s conversion.Scope) error { + return autoConvert_v1beta1_BootstrapToken_To_upstreamv1beta1_BootstrapToken(in, out, s) +} + +func autoConvert_upstreamv1beta1_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery(in *BootstrapTokenDiscovery, out *v1beta1.BootstrapTokenDiscovery, s conversion.Scope) error { + out.Token = in.Token + out.APIServerEndpoint = in.APIServerEndpoint + out.CACertHashes = *(*[]string)(unsafe.Pointer(&in.CACertHashes)) + out.UnsafeSkipCAVerification = in.UnsafeSkipCAVerification + return nil +} + +// Convert_upstreamv1beta1_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery is an autogenerated conversion function. +func Convert_upstreamv1beta1_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery(in *BootstrapTokenDiscovery, out *v1beta1.BootstrapTokenDiscovery, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_BootstrapTokenDiscovery_To_v1beta1_BootstrapTokenDiscovery(in, out, s) +} + +func autoConvert_v1beta1_BootstrapTokenDiscovery_To_upstreamv1beta1_BootstrapTokenDiscovery(in *v1beta1.BootstrapTokenDiscovery, out *BootstrapTokenDiscovery, s conversion.Scope) error { + out.Token = in.Token + out.APIServerEndpoint = in.APIServerEndpoint + out.CACertHashes = *(*[]string)(unsafe.Pointer(&in.CACertHashes)) + out.UnsafeSkipCAVerification = in.UnsafeSkipCAVerification + return nil +} + +// Convert_v1beta1_BootstrapTokenDiscovery_To_upstreamv1beta1_BootstrapTokenDiscovery is an autogenerated conversion function. +func Convert_v1beta1_BootstrapTokenDiscovery_To_upstreamv1beta1_BootstrapTokenDiscovery(in *v1beta1.BootstrapTokenDiscovery, out *BootstrapTokenDiscovery, s conversion.Scope) error { + return autoConvert_v1beta1_BootstrapTokenDiscovery_To_upstreamv1beta1_BootstrapTokenDiscovery(in, out, s) +} + +func autoConvert_upstreamv1beta1_BootstrapTokenString_To_v1beta1_BootstrapTokenString(in *BootstrapTokenString, out *v1beta1.BootstrapTokenString, s conversion.Scope) error { + out.ID = in.ID + out.Secret = in.Secret + return nil +} + +// Convert_upstreamv1beta1_BootstrapTokenString_To_v1beta1_BootstrapTokenString is an autogenerated conversion function. +func Convert_upstreamv1beta1_BootstrapTokenString_To_v1beta1_BootstrapTokenString(in *BootstrapTokenString, out *v1beta1.BootstrapTokenString, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_BootstrapTokenString_To_v1beta1_BootstrapTokenString(in, out, s) +} + +func autoConvert_v1beta1_BootstrapTokenString_To_upstreamv1beta1_BootstrapTokenString(in *v1beta1.BootstrapTokenString, out *BootstrapTokenString, s conversion.Scope) error { + out.ID = in.ID + out.Secret = in.Secret + return nil +} + +// Convert_v1beta1_BootstrapTokenString_To_upstreamv1beta1_BootstrapTokenString is an autogenerated conversion function. +func Convert_v1beta1_BootstrapTokenString_To_upstreamv1beta1_BootstrapTokenString(in *v1beta1.BootstrapTokenString, out *BootstrapTokenString, s conversion.Scope) error { + return autoConvert_v1beta1_BootstrapTokenString_To_upstreamv1beta1_BootstrapTokenString(in, out, s) +} + +func autoConvert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in *ClusterConfiguration, out *v1beta1.ClusterConfiguration, s conversion.Scope) error { + if err := Convert_upstreamv1beta1_Etcd_To_v1beta1_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_upstreamv1beta1_Networking_To_v1beta1_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint + if err := Convert_upstreamv1beta1_APIServer_To_v1beta1_APIServer(&in.APIServer, &out.APIServer, s); err != nil { + return err + } + if err := Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.ControllerManager, &out.ControllerManager, s); err != nil { + return err + } + if err := Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(&in.Scheduler, &out.Scheduler, s); err != nil { + return err + } + if err := Convert_upstreamv1beta1_DNS_To_v1beta1_DNS(&in.DNS, &out.DNS, s); err != nil { + return err + } + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + // WARNING: in.UseHyperKubeImage requires manual conversion: does not exist in peer-type + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +func autoConvert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(in *v1beta1.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { + if err := Convert_v1beta1_Etcd_To_upstreamv1beta1_Etcd(&in.Etcd, &out.Etcd, s); err != nil { + return err + } + if err := Convert_v1beta1_Networking_To_upstreamv1beta1_Networking(&in.Networking, &out.Networking, s); err != nil { + return err + } + out.KubernetesVersion = in.KubernetesVersion + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint + if err := Convert_v1beta1_APIServer_To_upstreamv1beta1_APIServer(&in.APIServer, &out.APIServer, s); err != nil { + return err + } + if err := Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(&in.ControllerManager, &out.ControllerManager, s); err != nil { + return err + } + if err := Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(&in.Scheduler, &out.Scheduler, s); err != nil { + return err + } + if err := Convert_v1beta1_DNS_To_upstreamv1beta1_DNS(&in.DNS, &out.DNS, s); err != nil { + return err + } + out.CertificatesDir = in.CertificatesDir + out.ImageRepository = in.ImageRepository + out.FeatureGates = *(*map[string]bool)(unsafe.Pointer(&in.FeatureGates)) + out.ClusterName = in.ClusterName + return nil +} + +// Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration is an autogenerated conversion function. +func Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(in *v1beta1.ClusterConfiguration, out *ClusterConfiguration, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(in, out, s) +} + +func autoConvert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus(in *ClusterStatus, out *v1beta1.ClusterStatus, s conversion.Scope) error { + out.APIEndpoints = *(*map[string]v1beta1.APIEndpoint)(unsafe.Pointer(&in.APIEndpoints)) + return nil +} + +// Convert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus is an autogenerated conversion function. +func Convert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus(in *ClusterStatus, out *v1beta1.ClusterStatus, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_ClusterStatus_To_v1beta1_ClusterStatus(in, out, s) +} + +func autoConvert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus(in *v1beta1.ClusterStatus, out *ClusterStatus, s conversion.Scope) error { + out.APIEndpoints = *(*map[string]APIEndpoint)(unsafe.Pointer(&in.APIEndpoints)) + return nil +} + +// Convert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus is an autogenerated conversion function. +func Convert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus(in *v1beta1.ClusterStatus, out *ClusterStatus, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterStatus_To_upstreamv1beta1_ClusterStatus(in, out, s) +} + +func autoConvert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in *ControlPlaneComponent, out *v1beta1.ControlPlaneComponent, s conversion.Scope) error { + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ExtraVolumes = *(*[]v1beta1.HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) + return nil +} + +// Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent is an autogenerated conversion function. +func Convert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in *ControlPlaneComponent, out *v1beta1.ControlPlaneComponent, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_ControlPlaneComponent_To_v1beta1_ControlPlaneComponent(in, out, s) +} + +func autoConvert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(in *v1beta1.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ExtraVolumes = *(*[]HostPathMount)(unsafe.Pointer(&in.ExtraVolumes)) + return nil +} + +// Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent is an autogenerated conversion function. +func Convert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(in *v1beta1.ControlPlaneComponent, out *ControlPlaneComponent, s conversion.Scope) error { + return autoConvert_v1beta1_ControlPlaneComponent_To_upstreamv1beta1_ControlPlaneComponent(in, out, s) +} + +func autoConvert_upstreamv1beta1_DNS_To_v1beta1_DNS(in *DNS, out *v1beta1.DNS, s conversion.Scope) error { + // WARNING: in.Type requires manual conversion: does not exist in peer-type + if err := Convert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_DNS_To_upstreamv1beta1_DNS(in *v1beta1.DNS, out *DNS, s conversion.Scope) error { + if err := Convert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DNS_To_upstreamv1beta1_DNS is an autogenerated conversion function. +func Convert_v1beta1_DNS_To_upstreamv1beta1_DNS(in *v1beta1.DNS, out *DNS, s conversion.Scope) error { + return autoConvert_v1beta1_DNS_To_upstreamv1beta1_DNS(in, out, s) +} + +func autoConvert_upstreamv1beta1_Discovery_To_v1beta1_Discovery(in *Discovery, out *v1beta1.Discovery, s conversion.Scope) error { + out.BootstrapToken = (*v1beta1.BootstrapTokenDiscovery)(unsafe.Pointer(in.BootstrapToken)) + out.File = (*v1beta1.FileDiscovery)(unsafe.Pointer(in.File)) + out.TLSBootstrapToken = in.TLSBootstrapToken + out.Timeout = (*v1.Duration)(unsafe.Pointer(in.Timeout)) + return nil +} + +// Convert_upstreamv1beta1_Discovery_To_v1beta1_Discovery is an autogenerated conversion function. +func Convert_upstreamv1beta1_Discovery_To_v1beta1_Discovery(in *Discovery, out *v1beta1.Discovery, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_Discovery_To_v1beta1_Discovery(in, out, s) +} + +func autoConvert_v1beta1_Discovery_To_upstreamv1beta1_Discovery(in *v1beta1.Discovery, out *Discovery, s conversion.Scope) error { + out.BootstrapToken = (*BootstrapTokenDiscovery)(unsafe.Pointer(in.BootstrapToken)) + out.File = (*FileDiscovery)(unsafe.Pointer(in.File)) + out.TLSBootstrapToken = in.TLSBootstrapToken + out.Timeout = (*v1.Duration)(unsafe.Pointer(in.Timeout)) + return nil +} + +// Convert_v1beta1_Discovery_To_upstreamv1beta1_Discovery is an autogenerated conversion function. +func Convert_v1beta1_Discovery_To_upstreamv1beta1_Discovery(in *v1beta1.Discovery, out *Discovery, s conversion.Scope) error { + return autoConvert_v1beta1_Discovery_To_upstreamv1beta1_Discovery(in, out, s) +} + +func autoConvert_upstreamv1beta1_Etcd_To_v1beta1_Etcd(in *Etcd, out *v1beta1.Etcd, s conversion.Scope) error { + out.Local = (*v1beta1.LocalEtcd)(unsafe.Pointer(in.Local)) + out.External = (*v1beta1.ExternalEtcd)(unsafe.Pointer(in.External)) + return nil +} + +// Convert_upstreamv1beta1_Etcd_To_v1beta1_Etcd is an autogenerated conversion function. +func Convert_upstreamv1beta1_Etcd_To_v1beta1_Etcd(in *Etcd, out *v1beta1.Etcd, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_Etcd_To_v1beta1_Etcd(in, out, s) +} + +func autoConvert_v1beta1_Etcd_To_upstreamv1beta1_Etcd(in *v1beta1.Etcd, out *Etcd, s conversion.Scope) error { + out.Local = (*LocalEtcd)(unsafe.Pointer(in.Local)) + out.External = (*ExternalEtcd)(unsafe.Pointer(in.External)) + return nil +} + +// Convert_v1beta1_Etcd_To_upstreamv1beta1_Etcd is an autogenerated conversion function. +func Convert_v1beta1_Etcd_To_upstreamv1beta1_Etcd(in *v1beta1.Etcd, out *Etcd, s conversion.Scope) error { + return autoConvert_v1beta1_Etcd_To_upstreamv1beta1_Etcd(in, out, s) +} + +func autoConvert_upstreamv1beta1_ExternalEtcd_To_v1beta1_ExternalEtcd(in *ExternalEtcd, out *v1beta1.ExternalEtcd, s conversion.Scope) error { + out.Endpoints = *(*[]string)(unsafe.Pointer(&in.Endpoints)) + out.CAFile = in.CAFile + out.CertFile = in.CertFile + out.KeyFile = in.KeyFile + return nil +} + +// Convert_upstreamv1beta1_ExternalEtcd_To_v1beta1_ExternalEtcd is an autogenerated conversion function. +func Convert_upstreamv1beta1_ExternalEtcd_To_v1beta1_ExternalEtcd(in *ExternalEtcd, out *v1beta1.ExternalEtcd, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_ExternalEtcd_To_v1beta1_ExternalEtcd(in, out, s) +} + +func autoConvert_v1beta1_ExternalEtcd_To_upstreamv1beta1_ExternalEtcd(in *v1beta1.ExternalEtcd, out *ExternalEtcd, s conversion.Scope) error { + out.Endpoints = *(*[]string)(unsafe.Pointer(&in.Endpoints)) + out.CAFile = in.CAFile + out.CertFile = in.CertFile + out.KeyFile = in.KeyFile + return nil +} + +// Convert_v1beta1_ExternalEtcd_To_upstreamv1beta1_ExternalEtcd is an autogenerated conversion function. +func Convert_v1beta1_ExternalEtcd_To_upstreamv1beta1_ExternalEtcd(in *v1beta1.ExternalEtcd, out *ExternalEtcd, s conversion.Scope) error { + return autoConvert_v1beta1_ExternalEtcd_To_upstreamv1beta1_ExternalEtcd(in, out, s) +} + +func autoConvert_upstreamv1beta1_FileDiscovery_To_v1beta1_FileDiscovery(in *FileDiscovery, out *v1beta1.FileDiscovery, s conversion.Scope) error { + out.KubeConfigPath = in.KubeConfigPath + return nil +} + +// Convert_upstreamv1beta1_FileDiscovery_To_v1beta1_FileDiscovery is an autogenerated conversion function. +func Convert_upstreamv1beta1_FileDiscovery_To_v1beta1_FileDiscovery(in *FileDiscovery, out *v1beta1.FileDiscovery, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_FileDiscovery_To_v1beta1_FileDiscovery(in, out, s) +} + +func autoConvert_v1beta1_FileDiscovery_To_upstreamv1beta1_FileDiscovery(in *v1beta1.FileDiscovery, out *FileDiscovery, s conversion.Scope) error { + out.KubeConfigPath = in.KubeConfigPath + return nil +} + +// Convert_v1beta1_FileDiscovery_To_upstreamv1beta1_FileDiscovery is an autogenerated conversion function. +func Convert_v1beta1_FileDiscovery_To_upstreamv1beta1_FileDiscovery(in *v1beta1.FileDiscovery, out *FileDiscovery, s conversion.Scope) error { + return autoConvert_v1beta1_FileDiscovery_To_upstreamv1beta1_FileDiscovery(in, out, s) +} + +func autoConvert_upstreamv1beta1_HostPathMount_To_v1beta1_HostPathMount(in *HostPathMount, out *v1beta1.HostPathMount, s conversion.Scope) error { + out.Name = in.Name + out.HostPath = in.HostPath + out.MountPath = in.MountPath + out.ReadOnly = in.ReadOnly + out.PathType = corev1.HostPathType(in.PathType) + return nil +} + +// Convert_upstreamv1beta1_HostPathMount_To_v1beta1_HostPathMount is an autogenerated conversion function. +func Convert_upstreamv1beta1_HostPathMount_To_v1beta1_HostPathMount(in *HostPathMount, out *v1beta1.HostPathMount, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_HostPathMount_To_v1beta1_HostPathMount(in, out, s) +} + +func autoConvert_v1beta1_HostPathMount_To_upstreamv1beta1_HostPathMount(in *v1beta1.HostPathMount, out *HostPathMount, s conversion.Scope) error { + out.Name = in.Name + out.HostPath = in.HostPath + out.MountPath = in.MountPath + out.ReadOnly = in.ReadOnly + out.PathType = corev1.HostPathType(in.PathType) + return nil +} + +// Convert_v1beta1_HostPathMount_To_upstreamv1beta1_HostPathMount is an autogenerated conversion function. +func Convert_v1beta1_HostPathMount_To_upstreamv1beta1_HostPathMount(in *v1beta1.HostPathMount, out *HostPathMount, s conversion.Scope) error { + return autoConvert_v1beta1_HostPathMount_To_upstreamv1beta1_HostPathMount(in, out, s) +} + +func autoConvert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(in *ImageMeta, out *v1beta1.ImageMeta, s conversion.Scope) error { + out.ImageRepository = in.ImageRepository + out.ImageTag = in.ImageTag + return nil +} + +// Convert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta is an autogenerated conversion function. +func Convert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(in *ImageMeta, out *v1beta1.ImageMeta, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(in, out, s) +} + +func autoConvert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(in *v1beta1.ImageMeta, out *ImageMeta, s conversion.Scope) error { + out.ImageRepository = in.ImageRepository + out.ImageTag = in.ImageTag + return nil +} + +// Convert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta is an autogenerated conversion function. +func Convert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(in *v1beta1.ImageMeta, out *ImageMeta, s conversion.Scope) error { + return autoConvert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(in, out, s) +} + +func autoConvert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(in *InitConfiguration, out *v1beta1.InitConfiguration, s conversion.Scope) error { + out.BootstrapTokens = *(*[]v1beta1.BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + if err := Convert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { + return err + } + if err := Convert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(&in.LocalAPIEndpoint, &out.LocalAPIEndpoint, s); err != nil { + return err + } + return nil +} + +// Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration is an autogenerated conversion function. +func Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(in *InitConfiguration, out *v1beta1.InitConfiguration, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(in, out, s) +} + +func autoConvert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(in *v1beta1.InitConfiguration, out *InitConfiguration, s conversion.Scope) error { + out.BootstrapTokens = *(*[]BootstrapToken)(unsafe.Pointer(&in.BootstrapTokens)) + if err := Convert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { + return err + } + if err := Convert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(&in.LocalAPIEndpoint, &out.LocalAPIEndpoint, s); err != nil { + return err + } + // WARNING: in.SkipPhases requires manual conversion: does not exist in peer-type + // WARNING: in.Patches requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(in *JoinConfiguration, out *v1beta1.JoinConfiguration, s conversion.Scope) error { + if err := Convert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { + return err + } + out.CACertPath = in.CACertPath + if err := Convert_upstreamv1beta1_Discovery_To_v1beta1_Discovery(&in.Discovery, &out.Discovery, s); err != nil { + return err + } + out.ControlPlane = (*v1beta1.JoinControlPlane)(unsafe.Pointer(in.ControlPlane)) + return nil +} + +// Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration is an autogenerated conversion function. +func Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(in *JoinConfiguration, out *v1beta1.JoinConfiguration, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(in, out, s) +} + +func autoConvert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(in *v1beta1.JoinConfiguration, out *JoinConfiguration, s conversion.Scope) error { + if err := Convert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(&in.NodeRegistration, &out.NodeRegistration, s); err != nil { + return err + } + out.CACertPath = in.CACertPath + if err := Convert_v1beta1_Discovery_To_upstreamv1beta1_Discovery(&in.Discovery, &out.Discovery, s); err != nil { + return err + } + out.ControlPlane = (*JoinControlPlane)(unsafe.Pointer(in.ControlPlane)) + // WARNING: in.SkipPhases requires manual conversion: does not exist in peer-type + // WARNING: in.Patches requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_upstreamv1beta1_JoinControlPlane_To_v1beta1_JoinControlPlane(in *JoinControlPlane, out *v1beta1.JoinControlPlane, s conversion.Scope) error { + if err := Convert_upstreamv1beta1_APIEndpoint_To_v1beta1_APIEndpoint(&in.LocalAPIEndpoint, &out.LocalAPIEndpoint, s); err != nil { + return err + } + return nil +} + +// Convert_upstreamv1beta1_JoinControlPlane_To_v1beta1_JoinControlPlane is an autogenerated conversion function. +func Convert_upstreamv1beta1_JoinControlPlane_To_v1beta1_JoinControlPlane(in *JoinControlPlane, out *v1beta1.JoinControlPlane, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_JoinControlPlane_To_v1beta1_JoinControlPlane(in, out, s) +} + +func autoConvert_v1beta1_JoinControlPlane_To_upstreamv1beta1_JoinControlPlane(in *v1beta1.JoinControlPlane, out *JoinControlPlane, s conversion.Scope) error { + if err := Convert_v1beta1_APIEndpoint_To_upstreamv1beta1_APIEndpoint(&in.LocalAPIEndpoint, &out.LocalAPIEndpoint, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_JoinControlPlane_To_upstreamv1beta1_JoinControlPlane is an autogenerated conversion function. +func Convert_v1beta1_JoinControlPlane_To_upstreamv1beta1_JoinControlPlane(in *v1beta1.JoinControlPlane, out *JoinControlPlane, s conversion.Scope) error { + return autoConvert_v1beta1_JoinControlPlane_To_upstreamv1beta1_JoinControlPlane(in, out, s) +} + +func autoConvert_upstreamv1beta1_LocalEtcd_To_v1beta1_LocalEtcd(in *LocalEtcd, out *v1beta1.LocalEtcd, s conversion.Scope) error { + if err := Convert_upstreamv1beta1_ImageMeta_To_v1beta1_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { + return err + } + out.DataDir = in.DataDir + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) + out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) + return nil +} + +// Convert_upstreamv1beta1_LocalEtcd_To_v1beta1_LocalEtcd is an autogenerated conversion function. +func Convert_upstreamv1beta1_LocalEtcd_To_v1beta1_LocalEtcd(in *LocalEtcd, out *v1beta1.LocalEtcd, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_LocalEtcd_To_v1beta1_LocalEtcd(in, out, s) +} + +func autoConvert_v1beta1_LocalEtcd_To_upstreamv1beta1_LocalEtcd(in *v1beta1.LocalEtcd, out *LocalEtcd, s conversion.Scope) error { + if err := Convert_v1beta1_ImageMeta_To_upstreamv1beta1_ImageMeta(&in.ImageMeta, &out.ImageMeta, s); err != nil { + return err + } + out.DataDir = in.DataDir + out.ExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.ExtraArgs)) + out.ServerCertSANs = *(*[]string)(unsafe.Pointer(&in.ServerCertSANs)) + out.PeerCertSANs = *(*[]string)(unsafe.Pointer(&in.PeerCertSANs)) + return nil +} + +// Convert_v1beta1_LocalEtcd_To_upstreamv1beta1_LocalEtcd is an autogenerated conversion function. +func Convert_v1beta1_LocalEtcd_To_upstreamv1beta1_LocalEtcd(in *v1beta1.LocalEtcd, out *LocalEtcd, s conversion.Scope) error { + return autoConvert_v1beta1_LocalEtcd_To_upstreamv1beta1_LocalEtcd(in, out, s) +} + +func autoConvert_upstreamv1beta1_Networking_To_v1beta1_Networking(in *Networking, out *v1beta1.Networking, s conversion.Scope) error { + out.ServiceSubnet = in.ServiceSubnet + out.PodSubnet = in.PodSubnet + out.DNSDomain = in.DNSDomain + return nil +} + +// Convert_upstreamv1beta1_Networking_To_v1beta1_Networking is an autogenerated conversion function. +func Convert_upstreamv1beta1_Networking_To_v1beta1_Networking(in *Networking, out *v1beta1.Networking, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_Networking_To_v1beta1_Networking(in, out, s) +} + +func autoConvert_v1beta1_Networking_To_upstreamv1beta1_Networking(in *v1beta1.Networking, out *Networking, s conversion.Scope) error { + out.ServiceSubnet = in.ServiceSubnet + out.PodSubnet = in.PodSubnet + out.DNSDomain = in.DNSDomain + return nil +} + +// Convert_v1beta1_Networking_To_upstreamv1beta1_Networking is an autogenerated conversion function. +func Convert_v1beta1_Networking_To_upstreamv1beta1_Networking(in *v1beta1.Networking, out *Networking, s conversion.Scope) error { + return autoConvert_v1beta1_Networking_To_upstreamv1beta1_Networking(in, out, s) +} + +func autoConvert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in *NodeRegistrationOptions, out *v1beta1.NodeRegistrationOptions, s conversion.Scope) error { + out.Name = in.Name + out.CRISocket = in.CRISocket + out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) + out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) + return nil +} + +// Convert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions is an autogenerated conversion function. +func Convert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in *NodeRegistrationOptions, out *v1beta1.NodeRegistrationOptions, s conversion.Scope) error { + return autoConvert_upstreamv1beta1_NodeRegistrationOptions_To_v1beta1_NodeRegistrationOptions(in, out, s) +} + +func autoConvert_v1beta1_NodeRegistrationOptions_To_upstreamv1beta1_NodeRegistrationOptions(in *v1beta1.NodeRegistrationOptions, out *NodeRegistrationOptions, s conversion.Scope) error { + out.Name = in.Name + out.CRISocket = in.CRISocket + out.Taints = *(*[]corev1.Taint)(unsafe.Pointer(&in.Taints)) + out.KubeletExtraArgs = *(*map[string]string)(unsafe.Pointer(&in.KubeletExtraArgs)) + // WARNING: in.IgnorePreflightErrors requires manual conversion: does not exist in peer-type + // WARNING: in.ImagePullPolicy requires manual conversion: does not exist in peer-type + return nil +} diff --git a/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.deepcopy.go b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000000..aeaaa3afff3d --- /dev/null +++ b/bootstrap/kubeadm/types/upstreamv1beta1/zz_generated.deepcopy.go @@ -0,0 +1,530 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package upstreamv1beta1 + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIEndpoint) DeepCopyInto(out *APIEndpoint) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIEndpoint. +func (in *APIEndpoint) DeepCopy() *APIEndpoint { + if in == nil { + return nil + } + out := new(APIEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIServer) DeepCopyInto(out *APIServer) { + *out = *in + in.ControlPlaneComponent.DeepCopyInto(&out.ControlPlaneComponent) + if in.CertSANs != nil { + in, out := &in.CertSANs, &out.CertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.TimeoutForControlPlane != nil { + in, out := &in.TimeoutForControlPlane, &out.TimeoutForControlPlane + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServer. +func (in *APIServer) DeepCopy() *APIServer { + if in == nil { + return nil + } + out := new(APIServer) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BootstrapToken) DeepCopyInto(out *BootstrapToken) { + *out = *in + if in.Token != nil { + in, out := &in.Token, &out.Token + *out = new(BootstrapTokenString) + **out = **in + } + if in.TTL != nil { + in, out := &in.TTL, &out.TTL + *out = new(v1.Duration) + **out = **in + } + if in.Expires != nil { + in, out := &in.Expires, &out.Expires + *out = (*in).DeepCopy() + } + if in.Usages != nil { + in, out := &in.Usages, &out.Usages + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Groups != nil { + in, out := &in.Groups, &out.Groups + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapToken. +func (in *BootstrapToken) DeepCopy() *BootstrapToken { + if in == nil { + return nil + } + out := new(BootstrapToken) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BootstrapTokenDiscovery) DeepCopyInto(out *BootstrapTokenDiscovery) { + *out = *in + if in.CACertHashes != nil { + in, out := &in.CACertHashes, &out.CACertHashes + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapTokenDiscovery. +func (in *BootstrapTokenDiscovery) DeepCopy() *BootstrapTokenDiscovery { + if in == nil { + return nil + } + out := new(BootstrapTokenDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BootstrapTokenString) DeepCopyInto(out *BootstrapTokenString) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapTokenString. +func (in *BootstrapTokenString) DeepCopy() *BootstrapTokenString { + if in == nil { + return nil + } + out := new(BootstrapTokenString) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterConfiguration) DeepCopyInto(out *ClusterConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.Etcd.DeepCopyInto(&out.Etcd) + out.Networking = in.Networking + in.APIServer.DeepCopyInto(&out.APIServer) + in.ControllerManager.DeepCopyInto(&out.ControllerManager) + in.Scheduler.DeepCopyInto(&out.Scheduler) + out.DNS = in.DNS + if in.FeatureGates != nil { + in, out := &in.FeatureGates, &out.FeatureGates + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterConfiguration. +func (in *ClusterConfiguration) DeepCopy() *ClusterConfiguration { + if in == nil { + return nil + } + out := new(ClusterConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.APIEndpoints != nil { + in, out := &in.APIEndpoints, &out.APIEndpoints + *out = make(map[string]APIEndpoint, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterStatus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneComponent) DeepCopyInto(out *ControlPlaneComponent) { + *out = *in + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ExtraVolumes != nil { + in, out := &in.ExtraVolumes, &out.ExtraVolumes + *out = make([]HostPathMount, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneComponent. +func (in *ControlPlaneComponent) DeepCopy() *ControlPlaneComponent { + if in == nil { + return nil + } + out := new(ControlPlaneComponent) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DNS) DeepCopyInto(out *DNS) { + *out = *in + out.ImageMeta = in.ImageMeta +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNS. +func (in *DNS) DeepCopy() *DNS { + if in == nil { + return nil + } + out := new(DNS) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Discovery) DeepCopyInto(out *Discovery) { + *out = *in + if in.BootstrapToken != nil { + in, out := &in.BootstrapToken, &out.BootstrapToken + *out = new(BootstrapTokenDiscovery) + (*in).DeepCopyInto(*out) + } + if in.File != nil { + in, out := &in.File, &out.File + *out = new(FileDiscovery) + **out = **in + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Discovery. +func (in *Discovery) DeepCopy() *Discovery { + if in == nil { + return nil + } + out := new(Discovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Etcd) DeepCopyInto(out *Etcd) { + *out = *in + if in.Local != nil { + in, out := &in.Local, &out.Local + *out = new(LocalEtcd) + (*in).DeepCopyInto(*out) + } + if in.External != nil { + in, out := &in.External, &out.External + *out = new(ExternalEtcd) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Etcd. +func (in *Etcd) DeepCopy() *Etcd { + if in == nil { + return nil + } + out := new(Etcd) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ExternalEtcd) DeepCopyInto(out *ExternalEtcd) { + *out = *in + if in.Endpoints != nil { + in, out := &in.Endpoints, &out.Endpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalEtcd. +func (in *ExternalEtcd) DeepCopy() *ExternalEtcd { + if in == nil { + return nil + } + out := new(ExternalEtcd) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FileDiscovery) DeepCopyInto(out *FileDiscovery) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FileDiscovery. +func (in *FileDiscovery) DeepCopy() *FileDiscovery { + if in == nil { + return nil + } + out := new(FileDiscovery) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostPathMount) DeepCopyInto(out *HostPathMount) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPathMount. +func (in *HostPathMount) DeepCopy() *HostPathMount { + if in == nil { + return nil + } + out := new(HostPathMount) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageMeta) DeepCopyInto(out *ImageMeta) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageMeta. +func (in *ImageMeta) DeepCopy() *ImageMeta { + if in == nil { + return nil + } + out := new(ImageMeta) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InitConfiguration) DeepCopyInto(out *InitConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + if in.BootstrapTokens != nil { + in, out := &in.BootstrapTokens, &out.BootstrapTokens + *out = make([]BootstrapToken, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.NodeRegistration.DeepCopyInto(&out.NodeRegistration) + out.LocalAPIEndpoint = in.LocalAPIEndpoint +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InitConfiguration. +func (in *InitConfiguration) DeepCopy() *InitConfiguration { + if in == nil { + return nil + } + out := new(InitConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *InitConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JoinConfiguration) DeepCopyInto(out *JoinConfiguration) { + *out = *in + out.TypeMeta = in.TypeMeta + in.NodeRegistration.DeepCopyInto(&out.NodeRegistration) + in.Discovery.DeepCopyInto(&out.Discovery) + if in.ControlPlane != nil { + in, out := &in.ControlPlane, &out.ControlPlane + *out = new(JoinControlPlane) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinConfiguration. +func (in *JoinConfiguration) DeepCopy() *JoinConfiguration { + if in == nil { + return nil + } + out := new(JoinConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *JoinConfiguration) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *JoinControlPlane) DeepCopyInto(out *JoinControlPlane) { + *out = *in + out.LocalAPIEndpoint = in.LocalAPIEndpoint +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JoinControlPlane. +func (in *JoinControlPlane) DeepCopy() *JoinControlPlane { + if in == nil { + return nil + } + out := new(JoinControlPlane) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LocalEtcd) DeepCopyInto(out *LocalEtcd) { + *out = *in + out.ImageMeta = in.ImageMeta + if in.ExtraArgs != nil { + in, out := &in.ExtraArgs, &out.ExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ServerCertSANs != nil { + in, out := &in.ServerCertSANs, &out.ServerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PeerCertSANs != nil { + in, out := &in.PeerCertSANs, &out.PeerCertSANs + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalEtcd. +func (in *LocalEtcd) DeepCopy() *LocalEtcd { + if in == nil { + return nil + } + out := new(LocalEtcd) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Networking) DeepCopyInto(out *Networking) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking. +func (in *Networking) DeepCopy() *Networking { + if in == nil { + return nil + } + out := new(Networking) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NodeRegistrationOptions) DeepCopyInto(out *NodeRegistrationOptions) { + *out = *in + if in.Taints != nil { + in, out := &in.Taints, &out.Taints + *out = make([]corev1.Taint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.KubeletExtraArgs != nil { + in, out := &in.KubeletExtraArgs, &out.KubeletExtraArgs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeRegistrationOptions. +func (in *NodeRegistrationOptions) DeepCopy() *NodeRegistrationOptions { + if in == nil { + return nil + } + out := new(NodeRegistrationOptions) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesetbindings.yaml b/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesetbindings.yaml index 10eb4a32243d..58e1e86bc00f 100644 --- a/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesetbindings.yaml +++ b/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesetbindings.yaml @@ -16,6 +16,91 @@ spec: singular: clusterresourcesetbinding scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "ClusterResourceSetBinding lists all matching ClusterResourceSets + with the cluster it belongs to. \n Deprecated: This type will be removed + in one of the next releases." + 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: ClusterResourceSetBindingSpec defines the desired state of + ClusterResourceSetBinding. + properties: + bindings: + description: Bindings is a list of ClusterResourceSets and their resources. + items: + description: ResourceSetBinding keeps info on all of the resources + in a ClusterResourceSet. + properties: + clusterResourceSetName: + description: ClusterResourceSetName is the name of the ClusterResourceSet + that is applied to the owner cluster of the binding. + type: string + resources: + description: Resources is a list of resources that the ClusterResourceSet + has. + items: + description: ResourceBinding shows the status of a resource + that belongs to a ClusterResourceSet matched by the owner + cluster of the ClusterResourceSetBinding object. + properties: + applied: + description: Applied is to track if a resource is applied + to the cluster or not. + type: boolean + hash: + description: Hash is the hash of a resource's data. This + can be used to decide if a resource is changed. For + "ApplyOnce" ClusterResourceSet.spec.strategy, this is + no-op as that strategy does not act on change. + type: string + kind: + description: 'Kind of the resource. Supported kinds are: + Secrets and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + lastAppliedTime: + description: LastAppliedTime identifies when this resource + was last applied to the cluster. + format: date-time + type: string + name: + description: Name of the resource that is in the same + namespace with ClusterResourceSet object. + minLength: 1 + type: string + required: + - applied + - kind + - name + type: object + type: array + required: + - clusterResourceSetName + type: object + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of ClusterResourceSetBinding jsonPath: .metadata.creationTimestamp diff --git a/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesets.yaml b/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesets.yaml index e9a769f26b79..2b6e10f82f44 100644 --- a/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesets.yaml +++ b/config/crd/bases/addons.cluster.x-k8s.io_clusterresourcesets.yaml @@ -16,6 +16,165 @@ spec: singular: clusterresourceset scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "ClusterResourceSet is the Schema for the clusterresourcesets + API. \n Deprecated: This type will be removed in one of the next releases." + 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: ClusterResourceSetSpec defines the desired state of ClusterResourceSet. + properties: + clusterSelector: + description: Label selector for Clusters. The Clusters that are selected + by this will be the ones affected by this ClusterResourceSet. It + must match the Cluster labels. This field is immutable. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + resources: + description: Resources is a list of Secrets/ConfigMaps where each + contains 1 or more resources to be applied to remote clusters. + items: + description: ResourceRef specifies a resource. + properties: + kind: + description: 'Kind of the resource. Supported kinds are: Secrets + and ConfigMaps.' + enum: + - Secret + - ConfigMap + type: string + name: + description: Name of the resource that is in the same namespace + with ClusterResourceSet object. + minLength: 1 + type: string + required: + - kind + - name + type: object + type: array + strategy: + description: Strategy is the strategy to be used during applying resources. + Defaults to ApplyOnce. This field is immutable. + enum: + - ApplyOnce + type: string + required: + - clusterSelector + type: object + status: + description: ClusterResourceSetStatus defines the observed state of ClusterResourceSet. + properties: + conditions: + description: Conditions defines current state of the ClusterResourceSet. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: ObservedGeneration reflects the generation of the most + recently observed ClusterResourceSet. + format: int64 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of ClusterResourceSet jsonPath: .metadata.creationTimestamp diff --git a/config/crd/bases/cluster.x-k8s.io_clusters.yaml b/config/crd/bases/cluster.x-k8s.io_clusters.yaml index f8bd0a4267b1..f052a5b8ef49 100644 --- a/config/crd/bases/cluster.x-k8s.io_clusters.yaml +++ b/config/crd/bases/cluster.x-k8s.io_clusters.yaml @@ -18,6 +18,264 @@ spec: singular: cluster scope: Namespaced versions: + - additionalPrinterColumns: + - description: Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed + jsonPath: .status.phase + name: Phase + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: Cluster is the Schema for the clusters 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: ClusterSpec defines the desired state of Cluster. + properties: + clusterNetwork: + description: Cluster network configuration. + properties: + apiServerPort: + description: APIServerPort specifies the port the API Server should + bind to. Defaults to 6443. + format: int32 + type: integer + pods: + description: The network ranges from which Pod networks are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + serviceDomain: + description: Domain name for services. + type: string + services: + description: The network ranges from which service VIPs are allocated. + properties: + cidrBlocks: + items: + type: string + type: array + required: + - cidrBlocks + type: object + type: object + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to + communicate with the control plane. + properties: + host: + description: The hostname on which the API server is serving. + type: string + port: + description: The port on which the API server is serving. + format: int32 + type: integer + required: + - host + - port + type: object + controlPlaneRef: + description: ControlPlaneRef is an optional reference to a provider-specific + resource that holds the details for provisioning the Control Plane + for a Cluster. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + infrastructureRef: + description: InfrastructureRef is a reference to a provider-specific + resource that holds the details for provisioning infrastructure + for a cluster in said provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + paused: + description: Paused can be used to prevent controllers from processing + the Cluster and all its associated objects. + type: boolean + type: object + status: + description: ClusterStatus defines the observed state of Cluster. + properties: + conditions: + description: Conditions defines current service state of the cluster. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + controlPlaneInitialized: + description: ControlPlaneInitialized defines if the control plane + has been initialized. + type: boolean + controlPlaneReady: + description: ControlPlaneReady defines if the control plane is ready. + type: boolean + failureDomains: + additionalProperties: + description: FailureDomainSpec is the Schema for Cluster API failure + domains. It allows controllers to understand how many failure + domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an + infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain + is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains is a slice of failure domain objects synced + from the infrastructure provider. + type: object + failureMessage: + description: FailureMessage indicates that there is a fatal problem + reconciling the state, and will be set to a descriptive error message. + type: string + failureReason: + description: FailureReason indicates that there is a fatal problem + reconciling the state, and will be set to a token value suitable + for programmatic interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure + provider. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of Cluster jsonPath: .metadata.creationTimestamp diff --git a/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml b/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml index 8abaa5ec1ff5..5b9790178cef 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml @@ -18,6 +18,499 @@ spec: singular: machinedeployment scope: Namespaced versions: + - additionalPrinterColumns: + - description: MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown + jsonPath: .status.phase + name: Phase + type: string + - description: Total number of non-terminated machines targeted by this MachineDeployment + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of ready machines targeted by this MachineDeployment + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this deployment + that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this MachineDeployment + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "MachineDeployment is the Schema for the machinedeployments API. + \n Deprecated: This type will be removed in one of the next releases." + 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: MachineDeploymentSpec defines the desired state of MachineDeployment. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs + to. + minLength: 1 + type: string + minReadySeconds: + description: Minimum number of seconds for which a newly created machine + should be ready. Defaults to 0 (machine will be considered available + as soon as it is ready) + format: int32 + type: integer + paused: + description: Indicates that the deployment is paused. + type: boolean + progressDeadlineSeconds: + description: The maximum time in seconds for a deployment to make + progress before it is considered to be failed. The deployment controller + will continue to process failed deployments and a condition with + a ProgressDeadlineExceeded reason will be surfaced in the deployment + status. Note that progress will not be estimated during the time + a deployment is paused. Defaults to 600s. + format: int32 + type: integer + replicas: + description: Number of desired machines. Defaults to 1. This is a + pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + revisionHistoryLimit: + description: The number of old MachineSets to retain to allow rollback. + This is a pointer to distinguish between explicit zero and not specified. + Defaults to 1. + format: int32 + type: integer + selector: + description: Label selector for machines. Existing MachineSets whose + machines are selected by this will be the ones affected by this + deployment. It must match the machine template's labels. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + strategy: + description: The deployment strategy to use to replace existing machines + with new ones. + properties: + rollingUpdate: + description: Rolling update config params. Present only if MachineDeploymentStrategyType + = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: 'The maximum number of machines that can be scheduled + above the desired number of machines. Value can be an absolute + number (ex: 5) or a percentage of desired machines (ex: + 10%). This can not be 0 if MaxUnavailable is 0. Absolute + number is calculated from percentage by rounding up. Defaults + to 1. Example: when this is set to 30%, the new MachineSet + can be scaled up immediately when the rolling update starts, + such that the total number of old and new machines do not + exceed 130% of desired machines. Once old machines have + been killed, new MachineSet can be scaled up further, ensuring + that total number of machines running at any time during + the update is at most 130% of desired machines.' + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of machines that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired machines (ex: 10%). Absolute + number is calculated from percentage by rounding down. This + can not be 0 if MaxSurge is 0. Defaults to 0. Example: when + this is set to 30%, the old MachineSet can be scaled down + to 70% of desired machines immediately when the rolling + update starts. Once new machines are ready, old MachineSet + can be scaled down further, followed by scaling up the new + MachineSet, ensuring that the total number of machines available + at all times during the update is at least 70% of desired + machines.' + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Currently the only supported + strategy is "RollingUpdate". Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map + stored with a resource that may be set by external tools + to store and retrieve arbitrary metadata. They are not queryable + and should be preserved when modifying objects. More info: + http://kubernetes.io/docs/user-guide/annotations' + type: object + generateName: + description: "GenerateName is an optional prefix, used by + the server, to generate a unique name ONLY IF the Name field + has not been provided. If this field is used, the name returned + to the client will be different than the name passed. This + value will also be combined with a unique suffix. The provided + value has the same validation rules as the Name field, and + may be truncated by the length of the suffix required to + make the value unique on the server. \n If this field is + specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created + or 500 with Reason ServerTimeout indicating a unique name + could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the + Retry-After header). \n Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used + to organize and categorize (scope and select) objects. May + match selectors of replication controllers and services. + More info: http://kubernetes.io/docs/user-guide/labels' + type: object + name: + description: "Name must be unique within a namespace. Is required + when creating resources, although some resources may allow + a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence + and configuration definition. Cannot be updated. More info: + http://kubernetes.io/docs/user-guide/identifiers#names \n + Deprecated: This field has no function and is going to be + removed in a next release." + type: string + namespace: + description: "Namespace defines the space within each name + must be unique. An empty namespace is equivalent to the + \"default\" namespace, but \"default\" is the canonical + representation. Not all objects are required to be scoped + to a namespace - the value of this field for those objects + will be empty. \n Must be a DNS_LABEL. Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + ownerReferences: + description: "List of objects depended by this object. If + ALL objects in the list have been deleted, this object will + be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, + with the controller field set to true. There cannot be more + than one managing controller. \n Deprecated: This field + has no function and is going to be removed in a next release." + items: + description: OwnerReference contains enough information + to let you identify an owning object. An owning object + must be in the same namespace as the dependent, or be + cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the + key-value store until this reference is removed. See + https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this + field and enforces the foreground deletion. Defaults + to false. To set this field, a user needs "delete" + permission of the owner, otherwise 422 (Unprocessable + Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: 'Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + bootstrap: + description: Bootstrap is a reference to a local struct which + encapsulates fields to configure the Machine’s bootstrapping + mechanism. + properties: + configRef: + description: ConfigRef is a reference to a bootstrap provider-specific + resource that holds configuration details. The reference + is optional to allow users/operators to specify Bootstrap.Data + without the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object + instead of an entire object, this string should + contain a valid JSON/Go field access statement, + such as desiredState.manifest.containers[2]. For + example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container + that triggered the event) or if no container name + is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only + to have some well-defined way of referencing a part + of an object. TODO: this design is not final and + this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this + reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: "Data contains the bootstrap data, such as + cloud-init details scripts. If nil, the Machine should + remain in the Pending state. \n Deprecated: Switch to + DataSecretName." + type: string + dataSecretName: + description: DataSecretName is the name of the secret + that stores the bootstrap data script. If nil, the Machine + should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object + belongs to. + minLength: 1 + type: string + failureDomain: + description: FailureDomain is the failure domain the machine + will be created in. Must match a key in the FailureDomains + map stored on the cluster object. + type: string + infrastructureRef: + description: InfrastructureRef is a required reference to + a custom resource offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: 'NodeDrainTimeout is the total amount of time + that the controller will spend on draining a node. The default + value is 0, meaning that the node can be drained without + any time limitations. NOTE: NodeDrainTimeout is different + from `kubectl drain --timeout`' + type: string + providerID: + description: ProviderID is the identification ID of the machine + provided by the provider. This field must match the provider + ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. + Example use case is cluster autoscaler with cluster-api + as provider. Clean-up logic in the autoscaler compares machines + to nodes to find out machines at provider which could not + get registered as Kubernetes nodes. With cluster-api as + a generic out-of-tree provider for autoscaler, this field + is required by autoscaler to be able to have a provider + view of the list of machines. Another list of nodes is queried + from the k8s apiserver and then a comparison is done to + find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by + higher level entities like autoscaler that will be interfacing + with cluster-api as generic provider. + type: string + version: + description: Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + - template + type: object + status: + description: MachineDeploymentStatus defines the observed state of MachineDeployment. + properties: + availableReplicas: + description: Total number of available machines (ready for at least + minReadySeconds) targeted by this deployment. + format: int32 + type: integer + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of a MachineDeployment + (ScalingUp, ScalingDown, Running, Failed, or Unknown). + type: string + readyReplicas: + description: Total number of ready machines targeted by this deployment. + format: int32 + type: integer + replicas: + description: Total number of non-terminated machines targeted by this + deployment (their labels match the selector). + format: int32 + type: integer + selector: + description: 'Selector is the same as the label selector but in the + string format to avoid introspection by clients. The string will + be in the same format as the query-param syntax. More info about + label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors' + type: string + unavailableReplicas: + description: Total number of unavailable machines targeted by this + deployment. This is the total number of machines that are still + required for the deployment to have 100% available capacity. They + may either be machines that are running but not yet available or + machines that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: Total number of non-terminated machines targeted by this + deployment that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: Cluster jsonPath: .spec.clusterName diff --git a/config/crd/bases/cluster.x-k8s.io_machinehealthchecks.yaml b/config/crd/bases/cluster.x-k8s.io_machinehealthchecks.yaml index bf7eb5dcbb66..9cbe65194b1b 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinehealthchecks.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinehealthchecks.yaml @@ -19,6 +19,259 @@ spec: singular: machinehealthcheck scope: Namespaced versions: + - additionalPrinterColumns: + - description: Maximum number of unhealthy machines allowed + jsonPath: .spec.maxUnhealthy + name: MaxUnhealthy + type: string + - description: Number of machines currently monitored + jsonPath: .status.expectedMachines + name: ExpectedMachines + type: integer + - description: Current observed healthy machines + jsonPath: .status.currentHealthy + name: CurrentHealthy + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "MachineHealthCheck is the Schema for the machinehealthchecks + API. \n Deprecated: This type will be removed in one of the next releases." + 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: Specification of machine health check policy + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs + to. + minLength: 1 + type: string + maxUnhealthy: + anyOf: + - type: integer + - type: string + description: Any further remediation is only allowed if at most "MaxUnhealthy" + machines selected by "selector" are not healthy. + x-kubernetes-int-or-string: true + nodeStartupTimeout: + description: Machines older than this duration without a node will + be considered to have failed and will be remediated. + type: string + remediationTemplate: + description: "RemediationTemplate is a reference to a remediation + template provided by an infrastructure provider. \n This field is + completely optional, when filled, the MachineHealthCheck controller + creates a new object from the template referenced and hands off + remediation of the machine to a controller that lives outside of + Cluster API." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to match machines whose health will be + exercised + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + unhealthyConditions: + description: UnhealthyConditions contains a list of the conditions + that determine whether a node is considered unhealthy. The conditions + are combined in a logical OR, i.e. if any of the conditions is met, + the node is unhealthy. + items: + description: UnhealthyCondition represents a Node condition type + and value with a timeout specified as a duration. When the named + condition has been in the given status for at least the timeout + value, a node is considered unhealthy. + properties: + status: + minLength: 1 + type: string + timeout: + type: string + type: + minLength: 1 + type: string + required: + - status + - timeout + - type + type: object + minItems: 1 + type: array + required: + - clusterName + - selector + - unhealthyConditions + type: object + status: + description: Most recently observed status of MachineHealthCheck resource + properties: + conditions: + description: Conditions defines current service state of the MachineHealthCheck. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + currentHealthy: + description: total number of healthy machines counted by this machine + health check + format: int32 + minimum: 0 + type: integer + expectedMachines: + description: total number of machines counted by this machine health + check + format: int32 + minimum: 0 + type: integer + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + remediationsAllowed: + description: RemediationsAllowed is the number of further remediations + allowed by this machine health check before maxUnhealthy short circuiting + will be applied + format: int32 + minimum: 0 + type: integer + targets: + description: Targets shows the current list of machines the machine + health check is watching + items: + type: string + type: array + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Cluster jsonPath: .spec.clusterName diff --git a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml b/config/crd/bases/cluster.x-k8s.io_machinepools.yaml index cd2a686da9fb..572da470419b 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinepools.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinepools.yaml @@ -18,6 +18,555 @@ spec: singular: machinepool scope: Namespaced versions: + - additionalPrinterColumns: + - description: MachinePool replicas count + jsonPath: .status.replicas + name: Replicas + type: string + - description: MachinePool status such as Terminating/Pending/Provisioning/Running/Failed + etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this MachinePool + jsonPath: .spec.template.spec.version + name: Version + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "MachinePool is the Schema for the machinepools API. \n Deprecated: + This type will be removed in one of the next releases." + 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: MachinePoolSpec defines the desired state of MachinePool. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs + to. + minLength: 1 + type: string + failureDomains: + description: FailureDomains is the list of failure domains this MachinePool + should be attached to. + items: + type: string + type: array + minReadySeconds: + description: Minimum number of seconds for which a newly created machine + instances should be ready. Defaults to 0 (machine instance will + be considered available as soon as it is ready) + format: int32 + type: integer + providerIDList: + description: ProviderIDList are the identification IDs of machine + instances provided by the provider. This field must match the provider + IDs as seen on the node objects corresponding to a machine pool's + machine instances. + items: + type: string + type: array + replicas: + description: Number of desired machines. Defaults to 1. This is a + pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + strategy: + description: The deployment strategy to use to replace existing machine + instances with new ones. + properties: + rollingUpdate: + description: Rolling update config params. Present only if MachineDeploymentStrategyType + = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: 'The maximum number of machines that can be scheduled + above the desired number of machines. Value can be an absolute + number (ex: 5) or a percentage of desired machines (ex: + 10%). This can not be 0 if MaxUnavailable is 0. Absolute + number is calculated from percentage by rounding up. Defaults + to 1. Example: when this is set to 30%, the new MachineSet + can be scaled up immediately when the rolling update starts, + such that the total number of old and new machines do not + exceed 130% of desired machines. Once old machines have + been killed, new MachineSet can be scaled up further, ensuring + that total number of machines running at any time during + the update is at most 130% of desired machines.' + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of machines that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired machines (ex: 10%). Absolute + number is calculated from percentage by rounding down. This + can not be 0 if MaxSurge is 0. Defaults to 0. Example: when + this is set to 30%, the old MachineSet can be scaled down + to 70% of desired machines immediately when the rolling + update starts. Once new machines are ready, old MachineSet + can be scaled down further, followed by scaling up the new + MachineSet, ensuring that the total number of machines available + at all times during the update is at least 70% of desired + machines.' + x-kubernetes-int-or-string: true + type: object + type: + description: Type of deployment. Currently the only supported + strategy is "RollingUpdate". Default is RollingUpdate. + type: string + type: object + template: + description: Template describes the machines that will be created. + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map + stored with a resource that may be set by external tools + to store and retrieve arbitrary metadata. They are not queryable + and should be preserved when modifying objects. More info: + http://kubernetes.io/docs/user-guide/annotations' + type: object + generateName: + description: "GenerateName is an optional prefix, used by + the server, to generate a unique name ONLY IF the Name field + has not been provided. If this field is used, the name returned + to the client will be different than the name passed. This + value will also be combined with a unique suffix. The provided + value has the same validation rules as the Name field, and + may be truncated by the length of the suffix required to + make the value unique on the server. \n If this field is + specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created + or 500 with Reason ServerTimeout indicating a unique name + could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the + Retry-After header). \n Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used + to organize and categorize (scope and select) objects. May + match selectors of replication controllers and services. + More info: http://kubernetes.io/docs/user-guide/labels' + type: object + name: + description: "Name must be unique within a namespace. Is required + when creating resources, although some resources may allow + a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence + and configuration definition. Cannot be updated. More info: + http://kubernetes.io/docs/user-guide/identifiers#names \n + Deprecated: This field has no function and is going to be + removed in a next release." + type: string + namespace: + description: "Namespace defines the space within each name + must be unique. An empty namespace is equivalent to the + \"default\" namespace, but \"default\" is the canonical + representation. Not all objects are required to be scoped + to a namespace - the value of this field for those objects + will be empty. \n Must be a DNS_LABEL. Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + ownerReferences: + description: "List of objects depended by this object. If + ALL objects in the list have been deleted, this object will + be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, + with the controller field set to true. There cannot be more + than one managing controller. \n Deprecated: This field + has no function and is going to be removed in a next release." + items: + description: OwnerReference contains enough information + to let you identify an owning object. An owning object + must be in the same namespace as the dependent, or be + cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the + key-value store until this reference is removed. See + https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this + field and enforces the foreground deletion. Defaults + to false. To set this field, a user needs "delete" + permission of the owner, otherwise 422 (Unprocessable + Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: 'Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + bootstrap: + description: Bootstrap is a reference to a local struct which + encapsulates fields to configure the Machine’s bootstrapping + mechanism. + properties: + configRef: + description: ConfigRef is a reference to a bootstrap provider-specific + resource that holds configuration details. The reference + is optional to allow users/operators to specify Bootstrap.Data + without the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object + instead of an entire object, this string should + contain a valid JSON/Go field access statement, + such as desiredState.manifest.containers[2]. For + example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container + that triggered the event) or if no container name + is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only + to have some well-defined way of referencing a part + of an object. TODO: this design is not final and + this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this + reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: "Data contains the bootstrap data, such as + cloud-init details scripts. If nil, the Machine should + remain in the Pending state. \n Deprecated: Switch to + DataSecretName." + type: string + dataSecretName: + description: DataSecretName is the name of the secret + that stores the bootstrap data script. If nil, the Machine + should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object + belongs to. + minLength: 1 + type: string + failureDomain: + description: FailureDomain is the failure domain the machine + will be created in. Must match a key in the FailureDomains + map stored on the cluster object. + type: string + infrastructureRef: + description: InfrastructureRef is a required reference to + a custom resource offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: 'NodeDrainTimeout is the total amount of time + that the controller will spend on draining a node. The default + value is 0, meaning that the node can be drained without + any time limitations. NOTE: NodeDrainTimeout is different + from `kubectl drain --timeout`' + type: string + providerID: + description: ProviderID is the identification ID of the machine + provided by the provider. This field must match the provider + ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. + Example use case is cluster autoscaler with cluster-api + as provider. Clean-up logic in the autoscaler compares machines + to nodes to find out machines at provider which could not + get registered as Kubernetes nodes. With cluster-api as + a generic out-of-tree provider for autoscaler, this field + is required by autoscaler to be able to have a provider + view of the list of machines. Another list of nodes is queried + from the k8s apiserver and then a comparison is done to + find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by + higher level entities like autoscaler that will be interfacing + with cluster-api as generic provider. + type: string + version: + description: Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - template + type: object + status: + description: MachinePoolStatus defines the observed state of MachinePool. + properties: + availableReplicas: + description: The number of available replicas (ready for at least + minReadySeconds) for this MachinePool. + format: int32 + type: integer + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions define the current service state of the MachinePool. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: FailureMessage indicates that there is a problem reconciling + the state, and will be set to a descriptive error message. + type: string + failureReason: + description: FailureReason indicates that there is a problem reconciling + the state, and will be set to a token value suitable for programmatic + interpretation. + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure + provider. + type: boolean + nodeRefs: + description: NodeRefs will point to the corresponding Nodes if it + they exist. + items: + description: "ObjectReference contains enough information to let + you inspect or modify the referred object. --- New uses of this + type are discouraged because of difficulty describing its usage + when embedded in APIs. 1. Ignored fields. It includes many fields + which are not generally honored. For instance, ResourceVersion + and FieldPath are both very rarely valid in actual usage. 2. Invalid + usage help. It is impossible to add specific help for individual + usage. In most embedded usages, there are particular restrictions + like, \"must refer only to types A and B\" or \"UID not honored\" + or \"name must be restricted\". Those cannot be well described + when embedded. 3. Inconsistent validation. Because the usages + are different, the validation rules are different by usage, which + makes it hard for users to predict what will happen. 4. The fields + are both imprecise and overly precise. Kind is not a precise + mapping to a URL. This can produce ambiguity during interpretation + and require a REST mapping. In most cases, the dependency is + on the group,resource tuple and the version of the actual struct + is irrelevant. 5. We cannot easily change it. Because this type + is embedded in many locations, updates to this type will affect + numerous schemas. Don't make new APIs embed an underspecified + API type they do not control. \n Instead of using this type, create + a locally provided and used type that is well-focused on your + reference. For example, ServiceReferences for admission registration: + https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + ." + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of cluster actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + readyReplicas: + description: The number of ready replicas for this MachinePool. A + machine is considered ready when the node has been created and is + "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + unavailableReplicas: + description: Total number of unavailable machine instances targeted + by this machine pool. This is the total number of machine instances + that are still required for the machine pool to have 100% available + capacity. They may either be machine instances that are running + but not yet available or machine instances that still have not been + created. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: Time duration since creation of MachinePool jsonPath: .metadata.creationTimestamp diff --git a/config/crd/bases/cluster.x-k8s.io_machines.yaml b/config/crd/bases/cluster.x-k8s.io_machines.yaml index c7c75731ac60..12bee202b945 100644 --- a/config/crd/bases/cluster.x-k8s.io_machines.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machines.yaml @@ -18,6 +18,346 @@ spec: singular: machine scope: Namespaced versions: + - additionalPrinterColumns: + - description: Provider ID + jsonPath: .spec.providerID + name: ProviderID + type: string + - description: Machine status such as Terminating/Pending/Running/Failed etc + jsonPath: .status.phase + name: Phase + type: string + - description: Kubernetes version associated with this Machine + jsonPath: .spec.version + name: Version + type: string + - description: Node name associated with this machine + jsonPath: .status.nodeRef.name + name: NodeName + priority: 1 + type: string + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "Machine is the Schema for the machines API. \n Deprecated: This + type will be removed in one of the next releases." + 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: MachineSpec defines the desired state of Machine. + properties: + bootstrap: + description: Bootstrap is a reference to a local struct which encapsulates + fields to configure the Machine’s bootstrapping mechanism. + properties: + configRef: + description: ConfigRef is a reference to a bootstrap provider-specific + resource that holds configuration details. The reference is + optional to allow users/operators to specify Bootstrap.Data + without the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part + of an object. TODO: this design is not final and this field + is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: "Data contains the bootstrap data, such as cloud-init + details scripts. If nil, the Machine should remain in the Pending + state. \n Deprecated: Switch to DataSecretName." + type: string + dataSecretName: + description: DataSecretName is the name of the secret that stores + the bootstrap data script. If nil, the Machine should remain + in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object belongs + to. + minLength: 1 + type: string + failureDomain: + description: FailureDomain is the failure domain the machine will + be created in. Must match a key in the FailureDomains map stored + on the cluster object. + type: string + infrastructureRef: + description: InfrastructureRef is a required reference to a custom + resource offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: 'NodeDrainTimeout is the total amount of time that the + controller will spend on draining a node. The default value is 0, + meaning that the node can be drained without any time limitations. + NOTE: NodeDrainTimeout is different from `kubectl drain --timeout`' + type: string + providerID: + description: ProviderID is the identification ID of the machine provided + by the provider. This field must match the provider ID as seen on + the node object corresponding to this machine. This field is required + by higher level consumers of cluster-api. Example use case is cluster + autoscaler with cluster-api as provider. Clean-up logic in the autoscaler + compares machines to nodes to find out machines at provider which + could not get registered as Kubernetes nodes. With cluster-api as + a generic out-of-tree provider for autoscaler, this field is required + by autoscaler to be able to have a provider view of the list of + machines. Another list of nodes is queried from the k8s apiserver + and then a comparison is done to find out unregistered machines + and are marked for delete. This field will be set by the actuators + and consumed by higher level entities like autoscaler that will + be interfacing with cluster-api as generic provider. + type: string + version: + description: Version defines the desired Kubernetes version. This + field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + status: + description: MachineStatus defines the observed state of Machine. + properties: + addresses: + description: Addresses is a list of addresses assigned to the machine. + This field is copied from the infrastructure provider reference. + items: + description: MachineAddress contains information for the node's + address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP + or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapReady: + description: BootstrapReady is the state of the bootstrap provider. + type: boolean + conditions: + description: Conditions defines current service state of the Machine. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: "FailureMessage will be set in the event that there is + a terminal problem reconciling the Machine and will contain a more + verbose string suitable for logging and human consumption. \n This + field should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over time (like + service outages), but instead indicate that something is fundamentally + wrong with the Machine's spec or the configuration of the controller, + and that manual intervention is required. Examples of terminal errors + would be invalid combinations of settings in the spec, values that + are unsupported by the controller, or the responsible controller + itself being critically misconfigured. \n Any transient errors that + occur during the reconciliation of Machines can be added as events + to the Machine object and/or logged in the controller's output." + type: string + failureReason: + description: "FailureReason will be set in the event that there is + a terminal problem reconciling the Machine and will contain a succinct + value suitable for machine interpretation. \n This field should + not be set for transitive errors that a controller faces that are + expected to be fixed automatically over time (like service outages), + but instead indicate that something is fundamentally wrong with + the Machine's spec or the configuration of the controller, and that + manual intervention is required. Examples of terminal errors would + be invalid combinations of settings in the spec, values that are + unsupported by the controller, or the responsible controller itself + being critically misconfigured. \n Any transient errors that occur + during the reconciliation of Machines can be added as events to + the Machine object and/or logged in the controller's output." + type: string + infrastructureReady: + description: InfrastructureReady is the state of the infrastructure + provider. + type: boolean + lastUpdated: + description: LastUpdated identifies when the phase of the Machine + last transitioned. + format: date-time + type: string + nodeRef: + description: NodeRef will point to the corresponding Node if it exists. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + phase: + description: Phase represents the current phase of machine actuation. + E.g. Pending, Running, Terminating, Failed etc. + type: string + version: + description: Version specifies the current version of Kubernetes running + on the corresponding Node. This is meant to be a means of bubbling + up status from the Node to the Machine. It is entirely optional, + but useful for end-user UX if it’s present. + type: string + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Cluster jsonPath: .spec.clusterName diff --git a/config/crd/bases/cluster.x-k8s.io_machinesets.yaml b/config/crd/bases/cluster.x-k8s.io_machinesets.yaml index d670ba9aed76..8225464eeea0 100644 --- a/config/crd/bases/cluster.x-k8s.io_machinesets.yaml +++ b/config/crd/bases/cluster.x-k8s.io_machinesets.yaml @@ -18,6 +18,445 @@ spec: singular: machineset scope: Namespaced versions: + - additionalPrinterColumns: + - description: Total number of non-terminated machines targeted by this machineset + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of available machines (ready for at least minReadySeconds) + jsonPath: .status.availableReplicas + name: Available + type: integer + - description: Total number of ready machines targeted by this machineset. + jsonPath: .status.readyReplicas + name: Ready + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "MachineSet is the Schema for the machinesets API. \n Deprecated: + This type will be removed in one of the next releases." + 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: MachineSetSpec defines the desired state of MachineSet. + properties: + clusterName: + description: ClusterName is the name of the Cluster this object belongs + to. + minLength: 1 + type: string + deletePolicy: + description: DeletePolicy defines the policy used to identify nodes + to delete when downscaling. Defaults to "Random". Valid values + are "Random, "Newest", "Oldest" + enum: + - Random + - Newest + - Oldest + type: string + minReadySeconds: + description: MinReadySeconds is the minimum number of seconds for + which a newly created machine should be ready. Defaults to 0 (machine + will be considered available as soon as it is ready) + format: int32 + type: integer + replicas: + description: Replicas is the number of desired replicas. This is a + pointer to distinguish between explicit zero and unspecified. Defaults + to 1. + format: int32 + type: integer + selector: + description: 'Selector is a label query over machines that should + match the replica count. Label keys and values that must match in + order to be controlled by this MachineSet. It must match the machine + template''s labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + template: + description: Template is the object that describes the machine that + will be created if insufficient replicas are detected. Object references + to custom resources are treated as templates. + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map + stored with a resource that may be set by external tools + to store and retrieve arbitrary metadata. They are not queryable + and should be preserved when modifying objects. More info: + http://kubernetes.io/docs/user-guide/annotations' + type: object + generateName: + description: "GenerateName is an optional prefix, used by + the server, to generate a unique name ONLY IF the Name field + has not been provided. If this field is used, the name returned + to the client will be different than the name passed. This + value will also be combined with a unique suffix. The provided + value has the same validation rules as the Name field, and + may be truncated by the length of the suffix required to + make the value unique on the server. \n If this field is + specified and the generated name exists, the server will + NOT return a 409 - instead, it will either return 201 Created + or 500 with Reason ServerTimeout indicating a unique name + could not be found in the time allotted, and the client + should retry (optionally after the time indicated in the + Retry-After header). \n Applied only if Name is not specified. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used + to organize and categorize (scope and select) objects. May + match selectors of replication controllers and services. + More info: http://kubernetes.io/docs/user-guide/labels' + type: object + name: + description: "Name must be unique within a namespace. Is required + when creating resources, although some resources may allow + a client to request the generation of an appropriate name + automatically. Name is primarily intended for creation idempotence + and configuration definition. Cannot be updated. More info: + http://kubernetes.io/docs/user-guide/identifiers#names \n + Deprecated: This field has no function and is going to be + removed in a next release." + type: string + namespace: + description: "Namespace defines the space within each name + must be unique. An empty namespace is equivalent to the + \"default\" namespace, but \"default\" is the canonical + representation. Not all objects are required to be scoped + to a namespace - the value of this field for those objects + will be empty. \n Must be a DNS_LABEL. Cannot be updated. + More info: http://kubernetes.io/docs/user-guide/namespaces + \n Deprecated: This field has no function and is going to + be removed in a next release." + type: string + ownerReferences: + description: "List of objects depended by this object. If + ALL objects in the list have been deleted, this object will + be garbage collected. If this object is managed by a controller, + then an entry in this list will point to this controller, + with the controller field set to true. There cannot be more + than one managing controller. \n Deprecated: This field + has no function and is going to be removed in a next release." + items: + description: OwnerReference contains enough information + to let you identify an owning object. An owning object + must be in the same namespace as the dependent, or be + cluster-scoped, so there is no namespace field. + properties: + apiVersion: + description: API version of the referent. + type: string + blockOwnerDeletion: + description: If true, AND if the owner has the "foregroundDeletion" + finalizer, then the owner cannot be deleted from the + key-value store until this reference is removed. See + https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion + for how the garbage collector interacts with this + field and enforces the foreground deletion. Defaults + to false. To set this field, a user needs "delete" + permission of the owner, otherwise 422 (Unprocessable + Entity) will be returned. + type: boolean + controller: + description: If true, this reference points to the managing + controller. + type: boolean + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids' + type: string + required: + - apiVersion + - kind + - name + - uid + type: object + x-kubernetes-map-type: atomic + type: array + type: object + spec: + description: 'Specification of the desired behavior of the machine. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + bootstrap: + description: Bootstrap is a reference to a local struct which + encapsulates fields to configure the Machine’s bootstrapping + mechanism. + properties: + configRef: + description: ConfigRef is a reference to a bootstrap provider-specific + resource that holds configuration details. The reference + is optional to allow users/operators to specify Bootstrap.Data + without the need of a controller. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object + instead of an entire object, this string should + contain a valid JSON/Go field access statement, + such as desiredState.manifest.containers[2]. For + example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container + that triggered the event) or if no container name + is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only + to have some well-defined way of referencing a part + of an object. TODO: this design is not final and + this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this + reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + data: + description: "Data contains the bootstrap data, such as + cloud-init details scripts. If nil, the Machine should + remain in the Pending state. \n Deprecated: Switch to + DataSecretName." + type: string + dataSecretName: + description: DataSecretName is the name of the secret + that stores the bootstrap data script. If nil, the Machine + should remain in the Pending state. + type: string + type: object + clusterName: + description: ClusterName is the name of the Cluster this object + belongs to. + minLength: 1 + type: string + failureDomain: + description: FailureDomain is the failure domain the machine + will be created in. Must match a key in the FailureDomains + map stored on the cluster object. + type: string + infrastructureRef: + description: InfrastructureRef is a required reference to + a custom resource offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead + of an entire object, this string should contain a valid + JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container + within a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that + triggered the event) or if no container name is specified + "spec.containers[2]" (container with index 2 in this + pod). This syntax is chosen only to have some well-defined + way of referencing a part of an object. TODO: this design + is not final and this field is subject to change in + the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + nodeDrainTimeout: + description: 'NodeDrainTimeout is the total amount of time + that the controller will spend on draining a node. The default + value is 0, meaning that the node can be drained without + any time limitations. NOTE: NodeDrainTimeout is different + from `kubectl drain --timeout`' + type: string + providerID: + description: ProviderID is the identification ID of the machine + provided by the provider. This field must match the provider + ID as seen on the node object corresponding to this machine. + This field is required by higher level consumers of cluster-api. + Example use case is cluster autoscaler with cluster-api + as provider. Clean-up logic in the autoscaler compares machines + to nodes to find out machines at provider which could not + get registered as Kubernetes nodes. With cluster-api as + a generic out-of-tree provider for autoscaler, this field + is required by autoscaler to be able to have a provider + view of the list of machines. Another list of nodes is queried + from the k8s apiserver and then a comparison is done to + find out unregistered machines and are marked for delete. + This field will be set by the actuators and consumed by + higher level entities like autoscaler that will be interfacing + with cluster-api as generic provider. + type: string + version: + description: Version defines the desired Kubernetes version. + This field is meant to be optionally used by bootstrap providers. + type: string + required: + - bootstrap + - clusterName + - infrastructureRef + type: object + type: object + required: + - clusterName + - selector + type: object + status: + description: MachineSetStatus defines the observed state of MachineSet. + properties: + availableReplicas: + description: The number of available replicas (ready for at least + minReadySeconds) for this MachineSet. + format: int32 + type: integer + failureMessage: + type: string + failureReason: + description: "In the event that there is a terminal problem reconciling + the replicas, both FailureReason and FailureMessage will be set. + FailureReason will be populated with a succinct value suitable for + machine interpretation, while FailureMessage will contain a more + verbose string suitable for logging and human consumption. \n These + fields should not be set for transitive errors that a controller + faces that are expected to be fixed automatically over time (like + service outages), but instead indicate that something is fundamentally + wrong with the MachineTemplate's spec or the configuration of the + machine controller, and that manual intervention is required. Examples + of terminal errors would be invalid combinations of settings in + the spec, values that are unsupported by the machine controller, + or the responsible machine controller itself being critically misconfigured. + \n Any transient errors that occur during the reconciliation of + Machines can be added as events to the MachineSet object and/or + logged in the controller's output." + type: string + fullyLabeledReplicas: + description: The number of replicas that have labels matching the + labels of the machine template of the MachineSet. + format: int32 + type: integer + observedGeneration: + description: ObservedGeneration reflects the generation of the most + recently observed MachineSet. + format: int64 + type: integer + readyReplicas: + description: The number of ready replicas for this MachineSet. A machine + is considered ready when the node has been created and is "Ready". + format: int32 + type: integer + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + selector: + description: 'Selector is the same as the label selector but in the + string format to avoid introspection by clients. The string will + be in the same format as the query-param syntax. More info about + label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors' + type: string + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: Cluster jsonPath: .spec.clusterName diff --git a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml index 5b75edf5a020..eb6893bb8de6 100644 --- a/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml +++ b/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml @@ -18,6 +18,1180 @@ spec: singular: kubeadmcontrolplane scope: Namespaced versions: + - additionalPrinterColumns: + - description: This denotes whether or not the control plane has the uploaded + kubeadm-config configmap + jsonPath: .status.initialized + name: Initialized + type: boolean + - description: KubeadmControlPlane API Server is ready to receive requests + jsonPath: .status.ready + name: API Server Available + type: boolean + - description: Kubernetes version associated with this control plane + jsonPath: .spec.version + name: Version + type: string + - description: Total number of non-terminated machines targeted by this control + plane + jsonPath: .status.replicas + name: Replicas + type: integer + - description: Total number of fully running and ready control plane machines + jsonPath: .status.readyReplicas + name: Ready + type: integer + - description: Total number of non-terminated machines targeted by this control + plane that have the desired template spec + jsonPath: .status.updatedReplicas + name: Updated + type: integer + - description: Total number of unavailable machines targeted by this control plane + jsonPath: .status.unavailableReplicas + name: Unavailable + type: integer + deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "KubeadmControlPlane is the Schema for the KubeadmControlPlane + API. \n Deprecated: This type will be removed in one of the next releases." + 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: KubeadmControlPlaneSpec defines the desired state of KubeadmControlPlane. + properties: + infrastructureTemplate: + description: InfrastructureTemplate is a required reference to a custom + resource offered by an infrastructure provider. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + kubeadmConfigSpec: + description: KubeadmConfigSpec is a KubeadmConfigSpec to use for initializing + and joining machines to the control plane. + properties: + clusterConfiguration: + description: ClusterConfiguration along with InitConfiguration + are the configurations necessary for the init command + properties: + apiServer: + description: APIServer contains extra settings for the API + server control plane component + properties: + certSANs: + description: CertSANs sets extra Subject Alternative Names + for the API Server signing cert. + items: + type: string + type: array + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass + to the control plane component. TODO: This is temporary + and ideally we would like to switch all components to + use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that + will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod + where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the + volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + timeoutForControlPlane: + description: TimeoutForControlPlane controls the timeout + that we use for API server to appear + type: string + type: object + 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 + certificatesDir: + description: 'CertificatesDir specifies where to store or + look for all required certificates. NB: if not provided, + this will default to `/etc/kubernetes/pki`' + type: string + clusterName: + description: The cluster name + type: string + controlPlaneEndpoint: + description: 'ControlPlaneEndpoint sets a stable IP address + or DNS name for the control plane; it can be a valid IP + address or a RFC-1123 DNS subdomain, both with optional + TCP port. In case the ControlPlaneEndpoint is not specified, + the AdvertiseAddress + BindPort are used; in case the ControlPlaneEndpoint + is specified but without a TCP port, the BindPort is used. + Possible usages are: e.g. In a cluster with more than one + control plane instances, this field should be assigned the + address of the external load balancer in front of the control + plane instances. e.g. in environments with enforced node + recycling, the ControlPlaneEndpoint could be used for assigning + a stable DNS to the control plane. NB: This value defaults + to the first value in the Cluster object status.apiEndpoints + array.' + type: string + controllerManager: + description: ControllerManager contains extra settings for + the controller manager control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass + to the control plane component. TODO: This is temporary + and ideally we would like to switch all components to + use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that + will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod + where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the + volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + dns: + description: DNS defines the options for the DNS add-on installed + in the cluster. + properties: + imageRepository: + description: ImageRepository sets the container registry + to pull images from. if not set, the ImageRepository + defined in ClusterConfiguration will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag for the + image. In case this value is set, kubeadm does not change + automatically the version of the above components during + upgrades. + type: string + type: + description: Type defines the DNS add-on to be used + type: string + type: object + etcd: + description: 'Etcd holds configuration for etcd. NB: This + value defaults to a Local (stacked) etcd' + properties: + external: + description: External describes how to connect to an external + etcd cluster Local and External are mutually exclusive + properties: + caFile: + description: CAFile is an SSL Certificate Authority + file used to secure etcd communication. Required + if using a TLS connection. + type: string + certFile: + description: CertFile is an SSL certification file + used to secure etcd communication. Required if using + a TLS connection. + type: string + endpoints: + description: Endpoints of etcd members. Required for + ExternalEtcd. + items: + type: string + type: array + keyFile: + description: KeyFile is an SSL key file used to secure + etcd communication. Required if using a TLS connection. + type: string + required: + - caFile + - certFile + - endpoints + - keyFile + type: object + local: + description: Local provides configuration knobs for configuring + the local etcd instance Local and External are mutually + exclusive + properties: + dataDir: + description: DataDir is the directory etcd will place + its data. Defaults to "/var/lib/etcd". + type: string + extraArgs: + additionalProperties: + type: string + description: ExtraArgs are extra arguments provided + to the etcd binary when run inside a static pod. + type: object + imageRepository: + description: ImageRepository sets the container registry + to pull images from. if not set, the ImageRepository + defined in ClusterConfiguration will be used instead. + type: string + imageTag: + description: ImageTag allows to specify a tag for + the image. In case this value is set, kubeadm does + not change automatically the version of the above + components during upgrades. + type: string + peerCertSANs: + description: PeerCertSANs sets extra Subject Alternative + Names for the etcd peer signing cert. + items: + type: string + type: array + serverCertSANs: + description: ServerCertSANs sets extra Subject Alternative + Names for the etcd server signing cert. + items: + type: string + type: array + type: object + type: object + featureGates: + additionalProperties: + type: boolean + description: FeatureGates enabled by the user. + type: object + imageRepository: + description: ImageRepository sets the container registry to + pull images from. If empty, `k8s.gcr.io` will be used by + default; in case of kubernetes version is a CI build (kubernetes + version starts with `ci/` or `ci-cross/`) `gcr.io/k8s-staging-ci-images` + will be used as a default for control plane components and + for kube-proxy, while `k8s.gcr.io` will be used for all + the other images. + 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 + kubernetesVersion: + description: 'KubernetesVersion is the target version of the + control plane. NB: This value defaults to the Machine object + spec.version' + type: string + networking: + description: 'Networking holds configuration for the networking + topology of the cluster. NB: This value defaults to the + Cluster object spec.clusterNetwork.' + properties: + dnsDomain: + description: DNSDomain is the dns domain used by k8s services. + Defaults to "cluster.local". + type: string + podSubnet: + description: PodSubnet is the subnet used by pods. If + unset, the API server will not allocate CIDR ranges + for every node. Defaults to a comma-delimited string + of the Cluster object's spec.clusterNetwork.services.cidrBlocks + if that is set + type: string + serviceSubnet: + description: ServiceSubnet is the subnet used by k8s services. + Defaults to a comma-delimited string of the Cluster + object's spec.clusterNetwork.pods.cidrBlocks, or to + "10.96.0.0/12" if that's unset. + type: string + type: object + scheduler: + description: Scheduler contains extra settings for the scheduler + control plane component + properties: + extraArgs: + additionalProperties: + type: string + description: 'ExtraArgs is an extra set of flags to pass + to the control plane component. TODO: This is temporary + and ideally we would like to switch all components to + use ComponentConfig + ConfigMaps.' + type: object + extraVolumes: + description: ExtraVolumes is an extra set of host volumes, + mounted to the control plane component. + items: + description: HostPathMount contains elements describing + volumes that are mounted from the host. + properties: + hostPath: + description: HostPath is the path in the host that + will be mounted inside the pod. + type: string + mountPath: + description: MountPath is the path inside the pod + where hostPath will be mounted. + type: string + name: + description: Name of the volume inside the pod template. + type: string + pathType: + description: PathType is the type of the HostPath. + type: string + readOnly: + description: ReadOnly controls write access to the + volume + type: boolean + required: + - hostPath + - mountPath + - name + type: object + type: array + type: object + useHyperKubeImage: + description: UseHyperKubeImage controls if hyperkube should + be used for Kubernetes components instead of their respective + separate images + type: boolean + type: object + diskSetup: + description: DiskSetup specifies options for the creation of partition + tables and file systems on devices. + properties: + filesystems: + description: Filesystems specifies the list of file systems + to setup. + items: + description: Filesystem defines the file systems to be created. + properties: + device: + description: Device specifies the device name + type: string + extraOpts: + description: ExtraOpts defined extra options to add + to the command for creating the file system. + items: + type: string + type: array + filesystem: + description: Filesystem specifies the file system type. + type: string + label: + description: Label specifies the file system label to + be used. If set to None, no label is used. + type: string + overwrite: + description: Overwrite defines whether or not to overwrite + any existing filesystem. If true, any pre-existing + file system will be destroyed. Use with Caution. + type: boolean + partition: + description: 'Partition specifies the partition to use. + The valid options are: "auto|any", "auto", "any", + "none", and , where NUM is the actual partition + number.' + type: string + replaceFS: + description: 'ReplaceFS is a special directive, used + for Microsoft Azure that instructs cloud-init to replace + a file system of . NOTE: unless you define + a label, this requires the use of the ''any'' partition + directive.' + type: string + required: + - device + - filesystem + - label + type: object + type: array + partitions: + description: Partitions specifies the list of the partitions + to setup. + items: + description: Partition defines how to create and layout + a partition. + properties: + device: + description: Device is the name of the device. + type: string + layout: + description: Layout specifies the device layout. If + it is true, a single partition will be created for + the entire device. When layout is false, it means + don't partition or ignore existing partitioning. + type: boolean + overwrite: + description: Overwrite describes whether to skip checks + and create the partition if a partition or filesystem + is found on the device. Use with caution. Default + is 'false'. + type: boolean + tableType: + description: 'TableType specifies the tupe of partition + table. The following are supported: ''mbr'': default + and setups a MS-DOS partition table ''gpt'': setups + a GPT partition table' + type: string + required: + - device + - layout + type: object + type: array + type: object + files: + description: Files specifies extra files to be passed to user_data + upon creation. + items: + description: File defines the input for generating write_files + in cloud-init. + properties: + content: + description: Content is the actual content of the file. + type: string + contentFrom: + description: ContentFrom is a referenced source of content + to populate the file. + properties: + secret: + description: Secret represents a secret that should + populate this file. + properties: + key: + description: Key is the key in the secret's data + map for this value. + type: string + name: + description: Name of the secret in the KubeadmBootstrapConfig's + namespace to use. + type: string + required: + - key + - name + type: object + required: + - secret + type: object + encoding: + description: Encoding specifies the encoding of the file + contents. + enum: + - base64 + - gzip + - gzip+base64 + type: string + owner: + description: Owner specifies the ownership of the file, + e.g. "root:root". + type: string + path: + description: Path specifies the full path on disk where + to store the file. + type: string + permissions: + description: Permissions specifies the permissions to assign + to the file, e.g. "0640". + type: string + required: + - path + type: object + type: array + format: + description: Format specifies the output format of the bootstrap + data + enum: + - cloud-config + type: string + initConfiguration: + description: InitConfiguration along with ClusterConfiguration + are the configurations necessary for the init command + 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 + bootstrapTokens: + description: BootstrapTokens is respected at `kubeadm init` + time and describes a set of Bootstrap Tokens to create. + This information IS NOT uploaded to the kubeadm cluster + configmap, partly because of its sensitive nature + items: + description: BootstrapToken describes one bootstrap token, + stored as a Secret in the cluster. + properties: + description: + description: Description sets a human-friendly message + why this token exists and what it's used for, so other + administrators can know its purpose. + type: string + expires: + description: Expires specifies the timestamp when this + token expires. Defaults to being set dynamically at + runtime based on the TTL. Expires and TTL are mutually + exclusive. + format: date-time + type: string + groups: + description: Groups specifies the extra groups that + this token will authenticate as when/if used for authentication + items: + type: string + type: array + token: + description: Token is used for establishing bidirectional + trust between nodes and control-planes. Used for joining + nodes in the cluster. + type: string + ttl: + description: TTL defines the time to live for this token. + Defaults to 24h. Expires and TTL are mutually exclusive. + type: string + usages: + description: Usages describes the ways in which this + token can be used. Can by default be used for establishing + bidirectional trust, but that can be changed here. + items: + type: string + type: array + required: + - token + type: object + type: array + 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 + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint of the + API server instance that's deployed on this control plane + node In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint + in the sense that ControlPlaneEndpoint is the global endpoint + for the cluster, which then loadbalances the requests to + each individual API server. This configuration object lets + you customize what IP/DNS name and port the local API server + advertises it's accessible on. By default, kubeadm tries + to auto-detect the IP of the default interface and use that, + but in case that process fails you may set the desired value + here. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address for + the API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for the API + Server to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + nodeRegistration: + description: NodeRegistration holds fields that relate to + registering the new control-plane node to the cluster. When + used in the context of control plane nodes, NodeRegistration + should remain consistent across both InitConfiguration and + JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container runtime + info. This information will be annotated to the Node + API object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra arguments + to the kubelet. The arguments here are passed to the + kubelet command line via the environment file kubeadm + writes at runtime for the kubelet to source. This overrides + the generic base-level configuration in the kubelet-config-1.X + ConfigMap Flags have higher priority when parsing. These + values are local and specific to the node kubeadm is + executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of the + Node API object that will be created in this `kubeadm + init` or `kubeadm join` operation. This field is also + used in the CommonName field of the kubelet's client + certificate to the API server. Defaults to the hostname + of the node if not provided. + type: string + taints: + description: 'Taints specifies the taints the Node API + object should be registered with. If this field is unset, + i.e. nil, in the `kubeadm init` process it will be defaulted + to []v1.Taint{''node-role.kubernetes.io/master=""''}. + If you don''t want to taint your control-plane node, + set this field to an empty slice, i.e. `taints: {}` + in the YAML file. This field is solely used for Node + registration.' + items: + description: The node this Taint is attached to has + the "effect" on any pod that does not tolerate the + Taint. + properties: + effect: + description: Required. The effect of the taint on + pods that do not tolerate the taint. Valid effects + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied + to a node. + type: string + timeAdded: + description: TimeAdded represents the time at which + the taint was added. It is only written for NoExecute + taints. + format: date-time + type: string + value: + description: The taint value corresponding to the + taint key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + joinConfiguration: + description: JoinConfiguration is the kubeadm configuration for + the join command + 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 + caCertPath: + description: 'CACertPath is the path to the SSL certificate + authority used to secure comunications between node and + control-plane. Defaults to "/etc/kubernetes/pki/ca.crt". + TODO: revisit when there is defaulting from k/k' + type: string + controlPlane: + description: ControlPlane defines the additional control plane + instance to be deployed on the joining node. If nil, no + additional control plane instance will be deployed. + properties: + localAPIEndpoint: + description: LocalAPIEndpoint represents the endpoint + of the API server instance to be deployed on this node. + properties: + advertiseAddress: + description: AdvertiseAddress sets the IP address + for the API server to advertise. + type: string + bindPort: + description: BindPort sets the secure port for the + API Server to bind to. Defaults to 6443. + format: int32 + type: integer + required: + - advertiseAddress + - bindPort + type: object + type: object + discovery: + description: 'Discovery specifies the options for the kubelet + to use during the TLS Bootstrap process TODO: revisit when + there is defaulting from k/k' + properties: + bootstrapToken: + description: BootstrapToken is used to set the options + for bootstrap token based discovery BootstrapToken and + File are mutually exclusive + properties: + apiServerEndpoint: + description: APIServerEndpoint is an IP or domain + name to the API server from which info will be fetched. + type: string + caCertHashes: + description: 'CACertHashes specifies a set of public + key pins to verify when token-based discovery is + used. The root CA found during discovery must match + one of these values. Specifying an empty set disables + root CA pinning, which can be unsafe. Each hash + is specified as ":", where the only + currently supported type is "sha256". This is a + hex-encoded SHA-256 hash of the Subject Public Key + Info (SPKI) object in DER-encoded ASN.1. These hashes + can be calculated using, for example, OpenSSL: openssl + x509 -pubkey -in ca.crt openssl rsa -pubin -outform + der 2>&/dev/null | openssl dgst -sha256 -hex' + items: + type: string + type: array + token: + description: Token is a token used to validate cluster + information fetched from the control-plane. + type: string + unsafeSkipCAVerification: + description: UnsafeSkipCAVerification allows token-based + discovery without CA verification via CACertHashes. + This can weaken the security of kubeadm since other + nodes can impersonate the control-plane. + type: boolean + required: + - token + - unsafeSkipCAVerification + type: object + file: + description: File is used to specify a file or URL to + a kubeconfig file from which to load cluster information + BootstrapToken and File are mutually exclusive + properties: + kubeConfigPath: + description: KubeConfigPath is used to specify the + actual file path or URL to the kubeconfig file from + which to load cluster information + type: string + required: + - kubeConfigPath + type: object + timeout: + description: Timeout modifies the discovery timeout + type: string + tlsBootstrapToken: + description: 'TLSBootstrapToken is a token used for TLS + bootstrapping. If .BootstrapToken is set, this field + is defaulted to .BootstrapToken.Token, but can be overridden. + If .File is set, this field **must be set** in case + the KubeConfigFile does not contain any other authentication + information TODO: revisit when there is defaulting from + k/k' + type: string + type: object + 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 + nodeRegistration: + description: NodeRegistration holds fields that relate to + registering the new control-plane node to the cluster. When + used in the context of control plane nodes, NodeRegistration + should remain consistent across both InitConfiguration and + JoinConfiguration + properties: + criSocket: + description: CRISocket is used to retrieve container runtime + info. This information will be annotated to the Node + API object, for later re-use + type: string + kubeletExtraArgs: + additionalProperties: + type: string + description: KubeletExtraArgs passes through extra arguments + to the kubelet. The arguments here are passed to the + kubelet command line via the environment file kubeadm + writes at runtime for the kubelet to source. This overrides + the generic base-level configuration in the kubelet-config-1.X + ConfigMap Flags have higher priority when parsing. These + values are local and specific to the node kubeadm is + executing on. + type: object + name: + description: Name is the `.Metadata.Name` field of the + Node API object that will be created in this `kubeadm + init` or `kubeadm join` operation. This field is also + used in the CommonName field of the kubelet's client + certificate to the API server. Defaults to the hostname + of the node if not provided. + type: string + taints: + description: 'Taints specifies the taints the Node API + object should be registered with. If this field is unset, + i.e. nil, in the `kubeadm init` process it will be defaulted + to []v1.Taint{''node-role.kubernetes.io/master=""''}. + If you don''t want to taint your control-plane node, + set this field to an empty slice, i.e. `taints: {}` + in the YAML file. This field is solely used for Node + registration.' + items: + description: The node this Taint is attached to has + the "effect" on any pod that does not tolerate the + Taint. + properties: + effect: + description: Required. The effect of the taint on + pods that do not tolerate the taint. Valid effects + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Required. The taint key to be applied + to a node. + type: string + timeAdded: + description: TimeAdded represents the time at which + the taint was added. It is only written for NoExecute + taints. + format: date-time + type: string + value: + description: The taint value corresponding to the + taint key. + type: string + required: + - effect + - key + type: object + type: array + type: object + type: object + mounts: + description: Mounts specifies a list of mount points to be setup. + items: + description: MountPoints defines input for generated mounts + in cloud-init. + items: + type: string + type: array + type: array + ntp: + description: NTP specifies NTP configuration + properties: + enabled: + description: Enabled specifies whether NTP should be enabled + type: boolean + servers: + description: Servers specifies which NTP servers to use + items: + type: string + type: array + type: object + postKubeadmCommands: + description: PostKubeadmCommands specifies extra commands to run + after kubeadm runs + items: + type: string + type: array + preKubeadmCommands: + description: PreKubeadmCommands specifies extra commands to run + before kubeadm runs + items: + type: string + type: array + useExperimentalRetryJoin: + description: "UseExperimentalRetryJoin replaces a basic kubeadm + command with a shell script with retries for joins. \n This + is meant to be an experimental temporary workaround on some + environments where joins fail due to timing (and other issues). + The long term goal is to add retries to kubeadm proper and use + that functionality. \n This will add about 40KB to userdata + \n For more information, refer to https://github.com/kubernetes-sigs/cluster-api/pull/2763#discussion_r397306055." + type: boolean + users: + description: Users specifies extra users to add + items: + description: User defines the input for a generated user in + cloud-init. + properties: + gecos: + description: Gecos specifies the gecos to use for the user + type: string + groups: + description: Groups specifies the additional groups for + the user + type: string + homeDir: + description: HomeDir specifies the home directory to use + for the user + type: string + inactive: + description: Inactive specifies whether to mark the user + as inactive + type: boolean + lockPassword: + description: LockPassword specifies if password login should + be disabled + type: boolean + name: + description: Name specifies the user name + type: string + passwd: + description: Passwd specifies a hashed password for the + user + type: string + primaryGroup: + description: PrimaryGroup specifies the primary group for + the user + type: string + shell: + description: Shell specifies the user's shell + type: string + sshAuthorizedKeys: + description: SSHAuthorizedKeys specifies a list of ssh authorized + keys for the user + items: + type: string + type: array + sudo: + description: Sudo specifies a sudo role for the user + type: string + required: + - name + type: object + type: array + verbosity: + description: Verbosity is the number for the kubeadm log level + verbosity. It overrides the `--v` flag in kubeadm commands. + format: int32 + type: integer + type: object + nodeDrainTimeout: + description: 'NodeDrainTimeout is the total amount of time that the + controller will spend on draining a controlplane node The default + value is 0, meaning that the node can be drained without any time + limitations. NOTE: NodeDrainTimeout is different from `kubectl drain + --timeout`' + type: string + replicas: + description: Number of desired machines. Defaults to 1. When stacked + etcd is used only odd numbers are permitted, as per [etcd best practice](https://etcd.io/docs/v3.3.12/faq/#why-an-odd-number-of-cluster-members). + This is a pointer to distinguish between explicit zero and not specified. + format: int32 + type: integer + rolloutStrategy: + description: The RolloutStrategy to use to replace control plane machines + with new ones. + properties: + rollingUpdate: + description: Rolling update config params. Present only if RolloutStrategyType + = RollingUpdate. + properties: + maxSurge: + anyOf: + - type: integer + - type: string + description: 'The maximum number of control planes that can + be scheduled above or under the desired number of control + planes. Value can be an absolute number 1 or 0. Defaults + to 1. Example: when this is set to 1, the control plane + can be scaled up immediately when the rolling update starts.' + x-kubernetes-int-or-string: true + type: object + type: + description: Type of rollout. Currently the only supported strategy + is "RollingUpdate". Default is RollingUpdate. + type: string + type: object + upgradeAfter: + description: UpgradeAfter is a field to indicate an upgrade should + be performed after the specified time even if no changes have been + made to the KubeadmControlPlane + format: date-time + type: string + version: + description: Version defines the desired Kubernetes version. + type: string + required: + - infrastructureTemplate + - kubeadmConfigSpec + - version + type: object + status: + description: KubeadmControlPlaneStatus defines the observed state of KubeadmControlPlane. + properties: + conditions: + description: Conditions defines current service state of the KubeadmControlPlane. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + failureMessage: + description: ErrorMessage indicates that there is a terminal problem + reconciling the state, and will be set to a descriptive error message. + type: string + failureReason: + description: FailureReason indicates that there is a terminal problem + reconciling the state, and will be set to a token value suitable + for programmatic interpretation. + type: string + initialized: + description: Initialized denotes whether or not the control plane + has the uploaded kubeadm-config configmap. + type: boolean + observedGeneration: + description: ObservedGeneration is the latest generation observed + by the controller. + format: int64 + type: integer + ready: + description: Ready denotes that the KubeadmControlPlane API Server + is ready to receive requests. + type: boolean + readyReplicas: + description: Total number of fully running and ready control plane + machines. + format: int32 + type: integer + replicas: + description: Total number of non-terminated machines targeted by this + control plane (their labels match the selector). + format: int32 + type: integer + selector: + description: 'Selector is the label selector in string format to avoid + introspection by clients, and is used to provide the CRD-based integration + for the scale subresource and additional integrations for things + like kubectl describe.. The string will be in the same format as + the query-param syntax. More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors' + type: string + unavailableReplicas: + description: Total number of unavailable machines targeted by this + control plane. This is the total number of machines that are still + required for the deployment to have 100% available capacity. They + may either be machines that are running but not yet ready or machines + that still have not been created. + format: int32 + type: integer + updatedReplicas: + description: Total number of non-terminated machines targeted by this + control plane that have the desired template spec. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} - additionalPrinterColumns: - description: Time duration since creation of KubeadmControlPlane jsonPath: .metadata.creationTimestamp diff --git a/controlplane/kubeadm/main.go b/controlplane/kubeadm/main.go index 2311d494379e..579c74f5f83b 100644 --- a/controlplane/kubeadm/main.go +++ b/controlplane/kubeadm/main.go @@ -54,6 +54,7 @@ import ( "sigs.k8s.io/cluster-api/controlplane/kubeadm/internal/etcd" kcpwebhooks "sigs.k8s.io/cluster-api/controlplane/kubeadm/webhooks" "sigs.k8s.io/cluster-api/feature" + controlplanev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/controlplane/kubeadm/v1alpha3" "sigs.k8s.io/cluster-api/util/flags" "sigs.k8s.io/cluster-api/version" ) @@ -91,6 +92,7 @@ var ( func init() { _ = clientgoscheme.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) + _ = controlplanev1alpha3.AddToScheme(scheme) _ = controlplanev1alpha4.AddToScheme(scheme) _ = controlplanev1.AddToScheme(scheme) _ = bootstrapv1.AddToScheme(scheme) diff --git a/exp/addons/api/v1alpha4/zz_generated.conversion.go b/exp/addons/api/v1alpha4/zz_generated.conversion.go index 3eafdc8da85a..f7a252692f8a 100644 --- a/exp/addons/api/v1alpha4/zz_generated.conversion.go +++ b/exp/addons/api/v1alpha4/zz_generated.conversion.go @@ -1,5 +1,5 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated +//go:build !ignore_autogenerated_core_exp +// +build !ignore_autogenerated_core_exp /* Copyright The Kubernetes Authors. diff --git a/exp/api/v1alpha4/zz_generated.conversion.go b/exp/api/v1alpha4/zz_generated.conversion.go index 3609aa05f248..4ce432555b6e 100644 --- a/exp/api/v1alpha4/zz_generated.conversion.go +++ b/exp/api/v1alpha4/zz_generated.conversion.go @@ -1,5 +1,5 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated +//go:build !ignore_autogenerated_core_exp +// +build !ignore_autogenerated_core_exp /* Copyright The Kubernetes Authors. diff --git a/exp/ipam/api/v1alpha1/zz_generated.conversion.go b/exp/ipam/api/v1alpha1/zz_generated.conversion.go index 3e397d16b8e2..50d181393b97 100644 --- a/exp/ipam/api/v1alpha1/zz_generated.conversion.go +++ b/exp/ipam/api/v1alpha1/zz_generated.conversion.go @@ -1,5 +1,5 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated +//go:build !ignore_autogenerated_core_exp_ipam +// +build !ignore_autogenerated_core_exp_ipam /* Copyright The Kubernetes Authors. diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/condition_consts.go b/internal/apis/bootstrap/kubeadm/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..5d51ad359603 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/condition_consts.go @@ -0,0 +1,68 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + +// Conditions and condition Reasons for the KubeadmConfig object. + +const ( + // DataSecretAvailableCondition documents the status of the bootstrap secret generation process. + // + // NOTE: When the DataSecret generation starts the process completes immediately and within the + // same reconciliation, so the user will always see a transition from Wait to Generated without having + // evidence that BootstrapSecret generation is started/in progress. + DataSecretAvailableCondition clusterv1alpha3.ConditionType = "DataSecretAvailable" + + // WaitingForClusterInfrastructureReason (Severity=Info) document a bootstrap secret generation process + // waiting for the cluster infrastructure to be ready. + // + // NOTE: Having the cluster infrastructure ready is a pre-condition for starting to create machines; + // the KubeadmConfig controller ensure this pre-condition is satisfied. + WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure" + + // WaitingForControlPlaneAvailableReason (Severity=Info) document a bootstrap secret generation process + // waiting for the control plane machine to be available. + // + // NOTE: Having the control plane machine available is a pre-condition for joining additional control planes + // or workers nodes. + WaitingForControlPlaneAvailableReason = "WaitingForControlPlaneAvailable" + + // DataSecretGenerationFailedReason (Severity=Warning) documents a KubeadmConfig controller detecting + // an error while generating a data secret; those kind of errors are usually due to misconfigurations + // and user intervention is required to get them fixed. + DataSecretGenerationFailedReason = "DataSecretGenerationFailed" +) + +const ( + // CertificatesAvailableCondition documents that cluster certificates are available. + // + // NOTE: Cluster certificates are generated only for the KubeadmConfig object linked to the initial control plane + // machine, if the cluster is not using a control plane ref object, if the certificates are not provided + // by the users. + // IMPORTANT: This condition won't be re-created after clusterctl move. + CertificatesAvailableCondition clusterv1alpha3.ConditionType = "CertificatesAvailable" + + // CertificatesGenerationFailedReason (Severity=Warning) documents a KubeadmConfig controller detecting + // an error while generating certificates; those kind of errors are usually temporary and the controller + // automatically recover from them. + CertificatesGenerationFailedReason = "CertificatesGenerationFailed" + + // CertificatesCorruptedReason (Severity=Error) documents a KubeadmConfig controller detecting + // an error while retrieving certificates for a joining node. + CertificatesCorruptedReason = "CertificatesCorrupted" +) diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/conversion.go b/internal/apis/bootstrap/kubeadm/v1alpha3/conversion.go new file mode 100644 index 000000000000..12e4c657c1d1 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/conversion.go @@ -0,0 +1,284 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *KubeadmConfig) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.KubeadmConfig) + + if err := Convert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &bootstrapv1.KubeadmConfig{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.Files = restored.Spec.Files + + dst.Spec.Users = restored.Spec.Users + if restored.Spec.Users != nil { + for i := range restored.Spec.Users { + if restored.Spec.Users[i].PasswdFrom != nil { + dst.Spec.Users[i].PasswdFrom = restored.Spec.Users[i].PasswdFrom + } + } + } + + if restored.Spec.JoinConfiguration != nil && restored.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.JoinConfiguration == nil { + dst.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.InitConfiguration != nil && restored.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.InitConfiguration == nil { + dst.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + + dst.Spec.Ignition = restored.Spec.Ignition + if restored.Spec.InitConfiguration != nil { + if dst.Spec.InitConfiguration == nil { + dst.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.InitConfiguration.Patches = restored.Spec.InitConfiguration.Patches + dst.Spec.InitConfiguration.SkipPhases = restored.Spec.InitConfiguration.SkipPhases + } + if restored.Spec.JoinConfiguration != nil { + if dst.Spec.JoinConfiguration == nil { + dst.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.JoinConfiguration.Patches = restored.Spec.JoinConfiguration.Patches + dst.Spec.JoinConfiguration.SkipPhases = restored.Spec.JoinConfiguration.SkipPhases + } + + if restored.Spec.JoinConfiguration != nil && restored.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.JoinConfiguration == nil { + dst.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy + } + + if restored.Spec.InitConfiguration != nil && restored.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.InitConfiguration == nil { + dst.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy + } + + return nil +} + +func (dst *KubeadmConfig) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.KubeadmConfig) + + if err := Convert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *KubeadmConfigList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.KubeadmConfigList) + + return Convert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList(src, dst, nil) +} + +func (dst *KubeadmConfigList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.KubeadmConfigList) + + return Convert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList(src, dst, nil) +} + +func (src *KubeadmConfigTemplate) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.KubeadmConfigTemplate) + + if err := Convert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &bootstrapv1.KubeadmConfigTemplate{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.Template.Spec.Files = restored.Spec.Template.Spec.Files + + dst.Spec.Template.Spec.Users = restored.Spec.Template.Spec.Users + if restored.Spec.Template.Spec.Users != nil { + for i := range restored.Spec.Template.Spec.Users { + if restored.Spec.Template.Spec.Users[i].PasswdFrom != nil { + dst.Spec.Template.Spec.Users[i].PasswdFrom = restored.Spec.Template.Spec.Users[i].PasswdFrom + } + } + } + + dst.Spec.Template.ObjectMeta = restored.Spec.Template.ObjectMeta + + if restored.Spec.Template.Spec.JoinConfiguration != nil && restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.Template.Spec.JoinConfiguration == nil { + dst.Spec.Template.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.Template.Spec.InitConfiguration != nil && restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.Template.Spec.InitConfiguration == nil { + dst.Spec.Template.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + + dst.Spec.Template.Spec.Ignition = restored.Spec.Template.Spec.Ignition + if restored.Spec.Template.Spec.InitConfiguration != nil { + if dst.Spec.Template.Spec.InitConfiguration == nil { + dst.Spec.Template.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.Template.Spec.InitConfiguration.Patches = restored.Spec.Template.Spec.InitConfiguration.Patches + dst.Spec.Template.Spec.InitConfiguration.SkipPhases = restored.Spec.Template.Spec.InitConfiguration.SkipPhases + } + if restored.Spec.Template.Spec.JoinConfiguration != nil { + if dst.Spec.Template.Spec.JoinConfiguration == nil { + dst.Spec.Template.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.Template.Spec.JoinConfiguration.Patches = restored.Spec.Template.Spec.JoinConfiguration.Patches + dst.Spec.Template.Spec.JoinConfiguration.SkipPhases = restored.Spec.Template.Spec.JoinConfiguration.SkipPhases + } + + if restored.Spec.Template.Spec.JoinConfiguration != nil && restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.Template.Spec.JoinConfiguration == nil { + dst.Spec.Template.Spec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.Template.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.Template.Spec.JoinConfiguration.NodeRegistration.ImagePullPolicy + } + + if restored.Spec.Template.Spec.InitConfiguration != nil && restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.Template.Spec.InitConfiguration == nil { + dst.Spec.Template.Spec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.Template.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.Template.Spec.InitConfiguration.NodeRegistration.ImagePullPolicy + } + + return nil +} + +func (dst *KubeadmConfigTemplate) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.KubeadmConfigTemplate) + + if err := Convert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *KubeadmConfigTemplateList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*bootstrapv1.KubeadmConfigTemplateList) + + return Convert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList(src, dst, nil) +} + +func (dst *KubeadmConfigTemplateList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*bootstrapv1.KubeadmConfigTemplateList) + + return Convert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList(src, dst, nil) +} + +func Convert_v1alpha3_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(in *KubeadmConfigStatus, out *bootstrapv1.KubeadmConfigStatus, s apiconversion.Scope) error { + // KubeadmConfigStatus.BootstrapData has been removed in v1alpha4 because its content has been moved to the bootstrap data secret, value will be lost during conversion. + return autoConvert_v1alpha3_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(in, out, s) +} + +func Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(in *bootstrapv1.ClusterConfiguration, out *upstreamv1beta1.ClusterConfiguration, s apiconversion.Scope) error { + // DNS.Type was removed in v1alpha4 because only CoreDNS is supported; the information will be left to empty (kubeadm defaults it to CoredDNS); + // Existing clusters using kube-dns or other DNS solutions will continue to be managed/supported via the skip-coredns annotation. + + // ClusterConfiguration.UseHyperKubeImage was removed in kubeadm v1alpha4 API + return upstreamv1beta1.Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(in, out, s) +} + +func Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in *upstreamv1beta1.ClusterConfiguration, out *bootstrapv1.ClusterConfiguration, s apiconversion.Scope) error { + // DNS.Type was removed in v1alpha4 because only CoreDNS is supported; the information will be left to empty (kubeadm defaults it to CoredDNS); + // ClusterConfiguration.UseHyperKubeImage was removed in kubeadm v1alpha4 API + return upstreamv1beta1.Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(in, out, s) +} + +func Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(in *upstreamv1beta1.InitConfiguration, out *bootstrapv1.InitConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return upstreamv1beta1.Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(in, out, s) +} + +func Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(in *bootstrapv1.InitConfiguration, out *upstreamv1beta1.InitConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return upstreamv1beta1.Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(in, out, s) +} + +func Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(in *upstreamv1beta1.JoinConfiguration, out *bootstrapv1.JoinConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return upstreamv1beta1.Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(in, out, s) +} + +func Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(in *bootstrapv1.JoinConfiguration, out *upstreamv1beta1.JoinConfiguration, s apiconversion.Scope) error { + // NodeRegistrationOptions.IgnorePreflightErrors does not exist in kubeadm v1beta1 API + return upstreamv1beta1.Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(in, out, s) +} + +// Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(in *bootstrapv1.KubeadmConfigSpec, out *KubeadmConfigSpec, s apiconversion.Scope) error { + // KubeadmConfigSpec.Ignition does not exist in kubeadm v1alpha3 API. + return autoConvert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(in, out, s) +} + +func Convert_v1beta1_File_To_v1alpha3_File(in *bootstrapv1.File, out *File, s apiconversion.Scope) error { + // File.Append does not exist in kubeadm v1alpha3 API. + return autoConvert_v1beta1_File_To_v1alpha3_File(in, out, s) +} + +func Convert_v1beta1_User_To_v1alpha3_User(in *bootstrapv1.User, out *User, s apiconversion.Scope) error { + // User.PasswdFrom does not exist in kubeadm v1alpha3 API. + return autoConvert_v1beta1_User_To_v1alpha3_User(in, out, s) +} + +func Convert_v1beta1_KubeadmConfigTemplateResource_To_v1alpha3_KubeadmConfigTemplateResource(in *bootstrapv1.KubeadmConfigTemplateResource, out *KubeadmConfigTemplateResource, s apiconversion.Scope) error { + // KubeadmConfigTemplateResource.metadata does not exist in kubeadm v1alpha3. + return autoConvert_v1beta1_KubeadmConfigTemplateResource_To_v1alpha3_KubeadmConfigTemplateResource(in, out, s) +} diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/conversion_test.go b/internal/apis/bootstrap/kubeadm/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..cac6e82f4c9a --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/conversion_test.go @@ -0,0 +1,93 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for KubeadmConfig", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.KubeadmConfig{}, + Spoke: &KubeadmConfig{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) + t.Run("for KubeadmConfigTemplate", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &bootstrapv1.KubeadmConfigTemplate{}, + Spoke: &KubeadmConfigTemplate{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) +} + +func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + KubeadmConfigStatusFuzzer, + dnsFuzzer, + clusterConfigurationFuzzer, + // This custom functions are needed when ConvertTo/ConvertFrom functions + // uses the json package to unmarshal the bootstrap token string. + // + // The Kubeadm BootstrapTokenString type ships with a custom + // json string representation, in particular it supplies a customized + // UnmarshalJSON function that can return an error if the string + // isn't in the correct form. + // + // This function effectively disables any fuzzing for the token by setting + // the values for ID and Secret to working alphanumeric values. + kubeadmBootstrapTokenStringFuzzerV1UpstreamBeta1, + kubeadmBootstrapTokenStringFuzzerV1Beta1, + } +} + +func KubeadmConfigStatusFuzzer(obj *KubeadmConfigStatus, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // KubeadmConfigStatus.BootstrapData has been removed in v1alpha4, so setting it to nil in order to avoid v1alpha3 --> --> v1alpha3 round trip errors. + obj.BootstrapData = nil +} + +func dnsFuzzer(obj *upstreamv1beta1.DNS, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // DNS.Type does not exists in v1alpha4, so setting it to empty string in order to avoid v1alpha3 --> --> v1alpha3 round trip errors. + obj.Type = "" +} + +func clusterConfigurationFuzzer(obj *upstreamv1beta1.ClusterConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // ClusterConfiguration.UseHyperKubeImage has been removed in v1alpha4, so setting it to false in order to avoid v1beta1 --> --> v1beta1 round trip errors. + obj.UseHyperKubeImage = false +} + +func kubeadmBootstrapTokenStringFuzzerV1UpstreamBeta1(in *upstreamv1beta1.BootstrapTokenString, _ fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} + +func kubeadmBootstrapTokenStringFuzzerV1Beta1(in *bootstrapv1.BootstrapTokenString, _ fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/doc.go b/internal/apis/bootstrap/kubeadm/v1alpha3/doc.go new file mode 100644 index 000000000000..b407ea788857 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/groupversion_info.go b/internal/apis/bootstrap/kubeadm/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..6f82b4ce6bf5 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the kubeadm v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=bootstrap.cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "bootstrap.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfig_types.go b/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfig_types.go new file mode 100644 index 000000000000..194293985a72 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfig_types.go @@ -0,0 +1,344 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +// Format specifies the output format of the bootstrap data +// +kubebuilder:validation:Enum=cloud-config +type Format string + +const ( + // CloudConfig make the bootstrap data to be of cloud-config format. + CloudConfig Format = "cloud-config" +) + +// KubeadmConfigSpec defines the desired state of KubeadmConfig. +// Either ClusterConfiguration and InitConfiguration should be defined or the JoinConfiguration should be defined. +type KubeadmConfigSpec struct { + // ClusterConfiguration along with InitConfiguration are the configurations necessary for the init command + // +optional + ClusterConfiguration *upstreamv1beta1.ClusterConfiguration `json:"clusterConfiguration,omitempty"` + + // InitConfiguration along with ClusterConfiguration are the configurations necessary for the init command + // +optional + InitConfiguration *upstreamv1beta1.InitConfiguration `json:"initConfiguration,omitempty"` + + // JoinConfiguration is the kubeadm configuration for the join command + // +optional + JoinConfiguration *upstreamv1beta1.JoinConfiguration `json:"joinConfiguration,omitempty"` + + // Files specifies extra files to be passed to user_data upon creation. + // +optional + Files []File `json:"files,omitempty"` + + // DiskSetup specifies options for the creation of partition tables and file systems on devices. + // +optional + DiskSetup *DiskSetup `json:"diskSetup,omitempty"` + + // Mounts specifies a list of mount points to be setup. + // +optional + Mounts []MountPoints `json:"mounts,omitempty"` + + // PreKubeadmCommands specifies extra commands to run before kubeadm runs + // +optional + PreKubeadmCommands []string `json:"preKubeadmCommands,omitempty"` + + // PostKubeadmCommands specifies extra commands to run after kubeadm runs + // +optional + PostKubeadmCommands []string `json:"postKubeadmCommands,omitempty"` + + // Users specifies extra users to add + // +optional + Users []User `json:"users,omitempty"` + + // NTP specifies NTP configuration + // +optional + NTP *NTP `json:"ntp,omitempty"` + + // Format specifies the output format of the bootstrap data + // +optional + Format Format `json:"format,omitempty"` + + // Verbosity is the number for the kubeadm log level verbosity. + // It overrides the `--v` flag in kubeadm commands. + // +optional + Verbosity *int32 `json:"verbosity,omitempty"` + + // UseExperimentalRetryJoin replaces a basic kubeadm command with a shell + // script with retries for joins. + // + // This is meant to be an experimental temporary workaround on some environments + // where joins fail due to timing (and other issues). The long term goal is to add retries to + // kubeadm proper and use that functionality. + // + // This will add about 40KB to userdata + // + // For more information, refer to https://github.com/kubernetes-sigs/cluster-api/pull/2763#discussion_r397306055. + // +optional + UseExperimentalRetryJoin bool `json:"useExperimentalRetryJoin,omitempty"` +} + +// KubeadmConfigStatus defines the observed state of KubeadmConfig. +type KubeadmConfigStatus struct { + // Ready indicates the BootstrapData field is ready to be consumed + Ready bool `json:"ready,omitempty"` + + // DataSecretName is the name of the secret that stores the bootstrap data script. + // +optional + DataSecretName *string `json:"dataSecretName,omitempty"` + + // BootstrapData will be a cloud-init script for now. + // + // Deprecated: Switch to DataSecretName. + // + // +optional + BootstrapData []byte `json:"bootstrapData,omitempty"` + + // FailureReason will be set on non-retryable errors + // +optional + FailureReason string `json:"failureReason,omitempty"` + + // FailureMessage will be set on non-retryable errors + // +optional + FailureMessage string `json:"failureMessage,omitempty"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions defines current service state of the KubeadmConfig. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=kubeadmconfigs,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status + +// KubeadmConfig is the Schema for the kubeadmconfigs API. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmConfig struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KubeadmConfigSpec `json:"spec,omitempty"` + Status KubeadmConfigStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (c *KubeadmConfig) GetConditions() clusterv1alpha3.Conditions { + return c.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (c *KubeadmConfig) SetConditions(conditions clusterv1alpha3.Conditions) { + c.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// KubeadmConfigList contains a list of KubeadmConfig. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmConfigList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []KubeadmConfig `json:"items"` +} + +func init() { + SchemeBuilder.Register(&KubeadmConfig{}, &KubeadmConfigList{}) +} + +// Encoding specifies the cloud-init file encoding. +// +kubebuilder:validation:Enum=base64;gzip;gzip+base64 +type Encoding string + +const ( + // Base64 implies the contents of the file are encoded as base64. + Base64 Encoding = "base64" + // Gzip implies the contents of the file are encoded with gzip. + Gzip Encoding = "gzip" + // GzipBase64 implies the contents of the file are first base64 encoded and then gzip encoded. + GzipBase64 Encoding = "gzip+base64" +) + +// File defines the input for generating write_files in cloud-init. +type File struct { + // Path specifies the full path on disk where to store the file. + Path string `json:"path"` + + // Owner specifies the ownership of the file, e.g. "root:root". + // +optional + Owner string `json:"owner,omitempty"` + + // Permissions specifies the permissions to assign to the file, e.g. "0640". + // +optional + Permissions string `json:"permissions,omitempty"` + + // Encoding specifies the encoding of the file contents. + // +optional + Encoding Encoding `json:"encoding,omitempty"` + + // Content is the actual content of the file. + // +optional + Content string `json:"content,omitempty"` + + // ContentFrom is a referenced source of content to populate the file. + // +optional + ContentFrom *FileSource `json:"contentFrom,omitempty"` +} + +// FileSource is a union of all possible external source types for file data. +// Only one field may be populated in any given instance. Developers adding new +// sources of data for target systems should add them here. +type FileSource struct { + // Secret represents a secret that should populate this file. + Secret SecretFileSource `json:"secret"` +} + +// SecretFileSource adapts a Secret into a FileSource. +// +// The contents of the target Secret's Data field will be presented +// as files using the keys in the Data field as the file names. +type SecretFileSource struct { + // Name of the secret in the KubeadmBootstrapConfig's namespace to use. + Name string `json:"name"` + + // Key is the key in the secret's data map for this value. + Key string `json:"key"` +} + +// User defines the input for a generated user in cloud-init. +type User struct { + // Name specifies the user name + Name string `json:"name"` + + // Gecos specifies the gecos to use for the user + // +optional + Gecos *string `json:"gecos,omitempty"` + + // Groups specifies the additional groups for the user + // +optional + Groups *string `json:"groups,omitempty"` + + // HomeDir specifies the home directory to use for the user + // +optional + HomeDir *string `json:"homeDir,omitempty"` + + // Inactive specifies whether to mark the user as inactive + // +optional + Inactive *bool `json:"inactive,omitempty"` + + // Shell specifies the user's shell + // +optional + Shell *string `json:"shell,omitempty"` + + // Passwd specifies a hashed password for the user + // +optional + Passwd *string `json:"passwd,omitempty"` + + // PrimaryGroup specifies the primary group for the user + // +optional + PrimaryGroup *string `json:"primaryGroup,omitempty"` + + // LockPassword specifies if password login should be disabled + // +optional + LockPassword *bool `json:"lockPassword,omitempty"` + + // Sudo specifies a sudo role for the user + // +optional + Sudo *string `json:"sudo,omitempty"` + + // SSHAuthorizedKeys specifies a list of ssh authorized keys for the user + // +optional + SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty"` +} + +// NTP defines input for generated ntp in cloud-init. +type NTP struct { + // Servers specifies which NTP servers to use + // +optional + Servers []string `json:"servers,omitempty"` + + // Enabled specifies whether NTP should be enabled + // +optional + Enabled *bool `json:"enabled,omitempty"` +} + +// DiskSetup defines input for generated disk_setup and fs_setup in cloud-init. +type DiskSetup struct { + // Partitions specifies the list of the partitions to setup. + Partitions []Partition `json:"partitions,omitempty"` + // Filesystems specifies the list of file systems to setup. + Filesystems []Filesystem `json:"filesystems,omitempty"` +} + +// Partition defines how to create and layout a partition. +type Partition struct { + // Device is the name of the device. + Device string `json:"device"` + // Layout specifies the device layout. + // If it is true, a single partition will be created for the entire device. + // When layout is false, it means don't partition or ignore existing partitioning. + Layout bool `json:"layout"` + // Overwrite describes whether to skip checks and create the partition if a partition or filesystem is found on the device. + // Use with caution. Default is 'false'. + // +optional + Overwrite *bool `json:"overwrite,omitempty"` + // TableType specifies the tupe of partition table. The following are supported: + // 'mbr': default and setups a MS-DOS partition table + // 'gpt': setups a GPT partition table + // +optional + TableType *string `json:"tableType,omitempty"` +} + +// Filesystem defines the file systems to be created. +type Filesystem struct { + // Device specifies the device name + Device string `json:"device"` + // Filesystem specifies the file system type. + Filesystem string `json:"filesystem"` + // Label specifies the file system label to be used. If set to None, no label is used. + Label string `json:"label"` + // Partition specifies the partition to use. The valid options are: "auto|any", "auto", "any", "none", and , where NUM is the actual partition number. + // +optional + Partition *string `json:"partition,omitempty"` + // Overwrite defines whether or not to overwrite any existing filesystem. + // If true, any pre-existing file system will be destroyed. Use with Caution. + // +optional + Overwrite *bool `json:"overwrite,omitempty"` + // ReplaceFS is a special directive, used for Microsoft Azure that instructs cloud-init to replace a file system of . + // NOTE: unless you define a label, this requires the use of the 'any' partition directive. + // +optional + ReplaceFS *string `json:"replaceFS,omitempty"` + // ExtraOpts defined extra options to add to the command for creating the file system. + // +optional + ExtraOpts []string `json:"extraOpts,omitempty"` +} + +// MountPoints defines input for generated mounts in cloud-init. +type MountPoints []string diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfigtemplate_types.go b/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfigtemplate_types.go new file mode 100644 index 000000000000..7acf083db2c0 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/kubeadmconfigtemplate_types.go @@ -0,0 +1,61 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// KubeadmConfigTemplateSpec defines the desired state of KubeadmConfigTemplate. +type KubeadmConfigTemplateSpec struct { + Template KubeadmConfigTemplateResource `json:"template"` +} + +// KubeadmConfigTemplateResource defines the Template structure. +type KubeadmConfigTemplateResource struct { + Spec KubeadmConfigSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=kubeadmconfigtemplates,scope=Namespaced,categories=cluster-api + +// KubeadmConfigTemplate is the Schema for the kubeadmconfigtemplates API. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmConfigTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KubeadmConfigTemplateSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true + +// KubeadmConfigTemplateList contains a list of KubeadmConfigTemplate. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmConfigTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []KubeadmConfigTemplate `json:"items"` +} + +func init() { + SchemeBuilder.Register(&KubeadmConfigTemplate{}, &KubeadmConfigTemplateList{}) +} diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/suite_test.go b/internal/apis/bootstrap/kubeadm/v1alpha3/suite_test.go new file mode 100644 index 000000000000..1bff9a48c8b3 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/suite_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "os" + "testing" + + // +kubebuilder:scaffold:imports + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/cluster-api/internal/test/envtest" +) + +var ( + env *envtest.Environment + ctx = ctrl.SetupSignalHandler() +) + +func TestMain(m *testing.M) { + utilruntime.Must(AddToScheme(scheme.Scheme)) + + os.Exit(envtest.Run(ctx, envtest.RunInput{ + M: m, + SetupEnv: func(e *envtest.Environment) { env = e }, + })) +} diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.conversion.go b/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..fd375ac9db46 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,803 @@ +//go:build !ignore_autogenerated_kubeadm_bootstrap +// +build !ignore_autogenerated_kubeadm_bootstrap + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + v1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + upstreamv1beta1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*DiskSetup)(nil), (*v1beta1.DiskSetup)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DiskSetup_To_v1beta1_DiskSetup(a.(*DiskSetup), b.(*v1beta1.DiskSetup), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DiskSetup)(nil), (*DiskSetup)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DiskSetup_To_v1alpha3_DiskSetup(a.(*v1beta1.DiskSetup), b.(*DiskSetup), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*File)(nil), (*v1beta1.File)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_File_To_v1beta1_File(a.(*File), b.(*v1beta1.File), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*FileSource)(nil), (*v1beta1.FileSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_FileSource_To_v1beta1_FileSource(a.(*FileSource), b.(*v1beta1.FileSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.FileSource)(nil), (*FileSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_FileSource_To_v1alpha3_FileSource(a.(*v1beta1.FileSource), b.(*FileSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Filesystem)(nil), (*v1beta1.Filesystem)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Filesystem_To_v1beta1_Filesystem(a.(*Filesystem), b.(*v1beta1.Filesystem), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Filesystem)(nil), (*Filesystem)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Filesystem_To_v1alpha3_Filesystem(a.(*v1beta1.Filesystem), b.(*Filesystem), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfig)(nil), (*v1beta1.KubeadmConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(a.(*KubeadmConfig), b.(*v1beta1.KubeadmConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfig)(nil), (*KubeadmConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(a.(*v1beta1.KubeadmConfig), b.(*KubeadmConfig), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigList)(nil), (*v1beta1.KubeadmConfigList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList(a.(*KubeadmConfigList), b.(*v1beta1.KubeadmConfigList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfigList)(nil), (*KubeadmConfigList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList(a.(*v1beta1.KubeadmConfigList), b.(*KubeadmConfigList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigSpec)(nil), (*v1beta1.KubeadmConfigSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(a.(*KubeadmConfigSpec), b.(*v1beta1.KubeadmConfigSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfigStatus)(nil), (*KubeadmConfigStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(a.(*v1beta1.KubeadmConfigStatus), b.(*KubeadmConfigStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigTemplate)(nil), (*v1beta1.KubeadmConfigTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(a.(*KubeadmConfigTemplate), b.(*v1beta1.KubeadmConfigTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfigTemplate)(nil), (*KubeadmConfigTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(a.(*v1beta1.KubeadmConfigTemplate), b.(*KubeadmConfigTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigTemplateList)(nil), (*v1beta1.KubeadmConfigTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList(a.(*KubeadmConfigTemplateList), b.(*v1beta1.KubeadmConfigTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfigTemplateList)(nil), (*KubeadmConfigTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList(a.(*v1beta1.KubeadmConfigTemplateList), b.(*KubeadmConfigTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigTemplateResource)(nil), (*v1beta1.KubeadmConfigTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource(a.(*KubeadmConfigTemplateResource), b.(*v1beta1.KubeadmConfigTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmConfigTemplateSpec)(nil), (*v1beta1.KubeadmConfigTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec(a.(*KubeadmConfigTemplateSpec), b.(*v1beta1.KubeadmConfigTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmConfigTemplateSpec)(nil), (*KubeadmConfigTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec(a.(*v1beta1.KubeadmConfigTemplateSpec), b.(*KubeadmConfigTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*NTP)(nil), (*v1beta1.NTP)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_NTP_To_v1beta1_NTP(a.(*NTP), b.(*v1beta1.NTP), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.NTP)(nil), (*NTP)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NTP_To_v1alpha3_NTP(a.(*v1beta1.NTP), b.(*NTP), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Partition)(nil), (*v1beta1.Partition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Partition_To_v1beta1_Partition(a.(*Partition), b.(*v1beta1.Partition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Partition)(nil), (*Partition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Partition_To_v1alpha3_Partition(a.(*v1beta1.Partition), b.(*Partition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*SecretFileSource)(nil), (*v1beta1.SecretFileSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource(a.(*SecretFileSource), b.(*v1beta1.SecretFileSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.SecretFileSource)(nil), (*SecretFileSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource(a.(*v1beta1.SecretFileSource), b.(*SecretFileSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*User)(nil), (*v1beta1.User)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_User_To_v1beta1_User(a.(*User), b.(*v1beta1.User), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*upstreamv1beta1.ClusterConfiguration)(nil), (*v1beta1.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(a.(*upstreamv1beta1.ClusterConfiguration), b.(*v1beta1.ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*upstreamv1beta1.InitConfiguration)(nil), (*v1beta1.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(a.(*upstreamv1beta1.InitConfiguration), b.(*v1beta1.InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*upstreamv1beta1.JoinConfiguration)(nil), (*v1beta1.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(a.(*upstreamv1beta1.JoinConfiguration), b.(*v1beta1.JoinConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*KubeadmConfigStatus)(nil), (*v1beta1.KubeadmConfigStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(a.(*KubeadmConfigStatus), b.(*v1beta1.KubeadmConfigStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.ClusterConfiguration)(nil), (*upstreamv1beta1.ClusterConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(a.(*v1beta1.ClusterConfiguration), b.(*upstreamv1beta1.ClusterConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.File)(nil), (*File)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_File_To_v1alpha3_File(a.(*v1beta1.File), b.(*File), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.InitConfiguration)(nil), (*upstreamv1beta1.InitConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(a.(*v1beta1.InitConfiguration), b.(*upstreamv1beta1.InitConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.JoinConfiguration)(nil), (*upstreamv1beta1.JoinConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(a.(*v1beta1.JoinConfiguration), b.(*upstreamv1beta1.JoinConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.KubeadmConfigSpec)(nil), (*KubeadmConfigSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(a.(*v1beta1.KubeadmConfigSpec), b.(*KubeadmConfigSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.KubeadmConfigTemplateResource)(nil), (*KubeadmConfigTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmConfigTemplateResource_To_v1alpha3_KubeadmConfigTemplateResource(a.(*v1beta1.KubeadmConfigTemplateResource), b.(*KubeadmConfigTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.User)(nil), (*User)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_User_To_v1alpha3_User(a.(*v1beta1.User), b.(*User), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_DiskSetup_To_v1beta1_DiskSetup(in *DiskSetup, out *v1beta1.DiskSetup, s conversion.Scope) error { + out.Partitions = *(*[]v1beta1.Partition)(unsafe.Pointer(&in.Partitions)) + out.Filesystems = *(*[]v1beta1.Filesystem)(unsafe.Pointer(&in.Filesystems)) + return nil +} + +// Convert_v1alpha3_DiskSetup_To_v1beta1_DiskSetup is an autogenerated conversion function. +func Convert_v1alpha3_DiskSetup_To_v1beta1_DiskSetup(in *DiskSetup, out *v1beta1.DiskSetup, s conversion.Scope) error { + return autoConvert_v1alpha3_DiskSetup_To_v1beta1_DiskSetup(in, out, s) +} + +func autoConvert_v1beta1_DiskSetup_To_v1alpha3_DiskSetup(in *v1beta1.DiskSetup, out *DiskSetup, s conversion.Scope) error { + out.Partitions = *(*[]Partition)(unsafe.Pointer(&in.Partitions)) + out.Filesystems = *(*[]Filesystem)(unsafe.Pointer(&in.Filesystems)) + return nil +} + +// Convert_v1beta1_DiskSetup_To_v1alpha3_DiskSetup is an autogenerated conversion function. +func Convert_v1beta1_DiskSetup_To_v1alpha3_DiskSetup(in *v1beta1.DiskSetup, out *DiskSetup, s conversion.Scope) error { + return autoConvert_v1beta1_DiskSetup_To_v1alpha3_DiskSetup(in, out, s) +} + +func autoConvert_v1alpha3_File_To_v1beta1_File(in *File, out *v1beta1.File, s conversion.Scope) error { + out.Path = in.Path + out.Owner = in.Owner + out.Permissions = in.Permissions + out.Encoding = v1beta1.Encoding(in.Encoding) + out.Content = in.Content + out.ContentFrom = (*v1beta1.FileSource)(unsafe.Pointer(in.ContentFrom)) + return nil +} + +// Convert_v1alpha3_File_To_v1beta1_File is an autogenerated conversion function. +func Convert_v1alpha3_File_To_v1beta1_File(in *File, out *v1beta1.File, s conversion.Scope) error { + return autoConvert_v1alpha3_File_To_v1beta1_File(in, out, s) +} + +func autoConvert_v1beta1_File_To_v1alpha3_File(in *v1beta1.File, out *File, s conversion.Scope) error { + out.Path = in.Path + out.Owner = in.Owner + out.Permissions = in.Permissions + out.Encoding = Encoding(in.Encoding) + // WARNING: in.Append requires manual conversion: does not exist in peer-type + out.Content = in.Content + out.ContentFrom = (*FileSource)(unsafe.Pointer(in.ContentFrom)) + return nil +} + +func autoConvert_v1alpha3_FileSource_To_v1beta1_FileSource(in *FileSource, out *v1beta1.FileSource, s conversion.Scope) error { + if err := Convert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource(&in.Secret, &out.Secret, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_FileSource_To_v1beta1_FileSource is an autogenerated conversion function. +func Convert_v1alpha3_FileSource_To_v1beta1_FileSource(in *FileSource, out *v1beta1.FileSource, s conversion.Scope) error { + return autoConvert_v1alpha3_FileSource_To_v1beta1_FileSource(in, out, s) +} + +func autoConvert_v1beta1_FileSource_To_v1alpha3_FileSource(in *v1beta1.FileSource, out *FileSource, s conversion.Scope) error { + if err := Convert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource(&in.Secret, &out.Secret, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_FileSource_To_v1alpha3_FileSource is an autogenerated conversion function. +func Convert_v1beta1_FileSource_To_v1alpha3_FileSource(in *v1beta1.FileSource, out *FileSource, s conversion.Scope) error { + return autoConvert_v1beta1_FileSource_To_v1alpha3_FileSource(in, out, s) +} + +func autoConvert_v1alpha3_Filesystem_To_v1beta1_Filesystem(in *Filesystem, out *v1beta1.Filesystem, s conversion.Scope) error { + out.Device = in.Device + out.Filesystem = in.Filesystem + out.Label = in.Label + out.Partition = (*string)(unsafe.Pointer(in.Partition)) + out.Overwrite = (*bool)(unsafe.Pointer(in.Overwrite)) + out.ReplaceFS = (*string)(unsafe.Pointer(in.ReplaceFS)) + out.ExtraOpts = *(*[]string)(unsafe.Pointer(&in.ExtraOpts)) + return nil +} + +// Convert_v1alpha3_Filesystem_To_v1beta1_Filesystem is an autogenerated conversion function. +func Convert_v1alpha3_Filesystem_To_v1beta1_Filesystem(in *Filesystem, out *v1beta1.Filesystem, s conversion.Scope) error { + return autoConvert_v1alpha3_Filesystem_To_v1beta1_Filesystem(in, out, s) +} + +func autoConvert_v1beta1_Filesystem_To_v1alpha3_Filesystem(in *v1beta1.Filesystem, out *Filesystem, s conversion.Scope) error { + out.Device = in.Device + out.Filesystem = in.Filesystem + out.Label = in.Label + out.Partition = (*string)(unsafe.Pointer(in.Partition)) + out.Overwrite = (*bool)(unsafe.Pointer(in.Overwrite)) + out.ReplaceFS = (*string)(unsafe.Pointer(in.ReplaceFS)) + out.ExtraOpts = *(*[]string)(unsafe.Pointer(&in.ExtraOpts)) + return nil +} + +// Convert_v1beta1_Filesystem_To_v1alpha3_Filesystem is an autogenerated conversion function. +func Convert_v1beta1_Filesystem_To_v1alpha3_Filesystem(in *v1beta1.Filesystem, out *Filesystem, s conversion.Scope) error { + return autoConvert_v1beta1_Filesystem_To_v1alpha3_Filesystem(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(in *KubeadmConfig, out *v1beta1.KubeadmConfig, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(in *KubeadmConfig, out *v1beta1.KubeadmConfig, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(in *v1beta1.KubeadmConfig, out *KubeadmConfig, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(in *v1beta1.KubeadmConfig, out *KubeadmConfig, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList(in *KubeadmConfigList, out *v1beta1.KubeadmConfigList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.KubeadmConfig, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_KubeadmConfig_To_v1beta1_KubeadmConfig(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList(in *KubeadmConfigList, out *v1beta1.KubeadmConfigList, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigList_To_v1beta1_KubeadmConfigList(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList(in *v1beta1.KubeadmConfigList, out *KubeadmConfigList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmConfig, len(*in)) + for i := range *in { + if err := Convert_v1beta1_KubeadmConfig_To_v1alpha3_KubeadmConfig(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList(in *v1beta1.KubeadmConfigList, out *KubeadmConfigList, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfigList_To_v1alpha3_KubeadmConfigList(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(in *KubeadmConfigSpec, out *v1beta1.KubeadmConfigSpec, s conversion.Scope) error { + if in.ClusterConfiguration != nil { + in, out := &in.ClusterConfiguration, &out.ClusterConfiguration + *out = new(v1beta1.ClusterConfiguration) + if err := Convert_upstreamv1beta1_ClusterConfiguration_To_v1beta1_ClusterConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.ClusterConfiguration = nil + } + if in.InitConfiguration != nil { + in, out := &in.InitConfiguration, &out.InitConfiguration + *out = new(v1beta1.InitConfiguration) + if err := Convert_upstreamv1beta1_InitConfiguration_To_v1beta1_InitConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.InitConfiguration = nil + } + if in.JoinConfiguration != nil { + in, out := &in.JoinConfiguration, &out.JoinConfiguration + *out = new(v1beta1.JoinConfiguration) + if err := Convert_upstreamv1beta1_JoinConfiguration_To_v1beta1_JoinConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.JoinConfiguration = nil + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make([]v1beta1.File, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_File_To_v1beta1_File(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Files = nil + } + out.DiskSetup = (*v1beta1.DiskSetup)(unsafe.Pointer(in.DiskSetup)) + out.Mounts = *(*[]v1beta1.MountPoints)(unsafe.Pointer(&in.Mounts)) + out.PreKubeadmCommands = *(*[]string)(unsafe.Pointer(&in.PreKubeadmCommands)) + out.PostKubeadmCommands = *(*[]string)(unsafe.Pointer(&in.PostKubeadmCommands)) + if in.Users != nil { + in, out := &in.Users, &out.Users + *out = make([]v1beta1.User, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_User_To_v1beta1_User(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Users = nil + } + out.NTP = (*v1beta1.NTP)(unsafe.Pointer(in.NTP)) + out.Format = v1beta1.Format(in.Format) + out.Verbosity = (*int32)(unsafe.Pointer(in.Verbosity)) + out.UseExperimentalRetryJoin = in.UseExperimentalRetryJoin + return nil +} + +// Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(in *KubeadmConfigSpec, out *v1beta1.KubeadmConfigSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(in *v1beta1.KubeadmConfigSpec, out *KubeadmConfigSpec, s conversion.Scope) error { + if in.ClusterConfiguration != nil { + in, out := &in.ClusterConfiguration, &out.ClusterConfiguration + *out = new(upstreamv1beta1.ClusterConfiguration) + if err := Convert_v1beta1_ClusterConfiguration_To_upstreamv1beta1_ClusterConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.ClusterConfiguration = nil + } + if in.InitConfiguration != nil { + in, out := &in.InitConfiguration, &out.InitConfiguration + *out = new(upstreamv1beta1.InitConfiguration) + if err := Convert_v1beta1_InitConfiguration_To_upstreamv1beta1_InitConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.InitConfiguration = nil + } + if in.JoinConfiguration != nil { + in, out := &in.JoinConfiguration, &out.JoinConfiguration + *out = new(upstreamv1beta1.JoinConfiguration) + if err := Convert_v1beta1_JoinConfiguration_To_upstreamv1beta1_JoinConfiguration(*in, *out, s); err != nil { + return err + } + } else { + out.JoinConfiguration = nil + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make([]File, len(*in)) + for i := range *in { + if err := Convert_v1beta1_File_To_v1alpha3_File(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Files = nil + } + out.DiskSetup = (*DiskSetup)(unsafe.Pointer(in.DiskSetup)) + out.Mounts = *(*[]MountPoints)(unsafe.Pointer(&in.Mounts)) + out.PreKubeadmCommands = *(*[]string)(unsafe.Pointer(&in.PreKubeadmCommands)) + out.PostKubeadmCommands = *(*[]string)(unsafe.Pointer(&in.PostKubeadmCommands)) + if in.Users != nil { + in, out := &in.Users, &out.Users + *out = make([]User, len(*in)) + for i := range *in { + if err := Convert_v1beta1_User_To_v1alpha3_User(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Users = nil + } + out.NTP = (*NTP)(unsafe.Pointer(in.NTP)) + out.Format = Format(in.Format) + out.Verbosity = (*int32)(unsafe.Pointer(in.Verbosity)) + out.UseExperimentalRetryJoin = in.UseExperimentalRetryJoin + // WARNING: in.Ignition requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_KubeadmConfigStatus_To_v1beta1_KubeadmConfigStatus(in *KubeadmConfigStatus, out *v1beta1.KubeadmConfigStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.DataSecretName = (*string)(unsafe.Pointer(in.DataSecretName)) + // WARNING: in.BootstrapData requires manual conversion: does not exist in peer-type + out.FailureReason = in.FailureReason + out.FailureMessage = in.FailureMessage + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +func autoConvert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(in *v1beta1.KubeadmConfigStatus, out *KubeadmConfigStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.DataSecretName = (*string)(unsafe.Pointer(in.DataSecretName)) + out.FailureReason = in.FailureReason + out.FailureMessage = in.FailureMessage + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(in *v1beta1.KubeadmConfigStatus, out *KubeadmConfigStatus, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfigStatus_To_v1alpha3_KubeadmConfigStatus(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(in *KubeadmConfigTemplate, out *v1beta1.KubeadmConfigTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(in *KubeadmConfigTemplate, out *v1beta1.KubeadmConfigTemplate, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(in *v1beta1.KubeadmConfigTemplate, out *KubeadmConfigTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(in *v1beta1.KubeadmConfigTemplate, out *KubeadmConfigTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList(in *KubeadmConfigTemplateList, out *v1beta1.KubeadmConfigTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.KubeadmConfigTemplate, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_KubeadmConfigTemplate_To_v1beta1_KubeadmConfigTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList(in *KubeadmConfigTemplateList, out *v1beta1.KubeadmConfigTemplateList, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigTemplateList_To_v1beta1_KubeadmConfigTemplateList(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList(in *v1beta1.KubeadmConfigTemplateList, out *KubeadmConfigTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmConfigTemplate, len(*in)) + for i := range *in { + if err := Convert_v1beta1_KubeadmConfigTemplate_To_v1alpha3_KubeadmConfigTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList(in *v1beta1.KubeadmConfigTemplateList, out *KubeadmConfigTemplateList, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfigTemplateList_To_v1alpha3_KubeadmConfigTemplateList(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource(in *KubeadmConfigTemplateResource, out *v1beta1.KubeadmConfigTemplateResource, s conversion.Scope) error { + if err := Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource(in *KubeadmConfigTemplateResource, out *v1beta1.KubeadmConfigTemplateResource, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigTemplateResource_To_v1alpha3_KubeadmConfigTemplateResource(in *v1beta1.KubeadmConfigTemplateResource, out *KubeadmConfigTemplateResource, s conversion.Scope) error { + // WARNING: in.ObjectMeta requires manual conversion: does not exist in peer-type + if err := Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec(in *KubeadmConfigTemplateSpec, out *v1beta1.KubeadmConfigTemplateSpec, s conversion.Scope) error { + if err := Convert_v1alpha3_KubeadmConfigTemplateResource_To_v1beta1_KubeadmConfigTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec(in *KubeadmConfigTemplateSpec, out *v1beta1.KubeadmConfigTemplateSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmConfigTemplateSpec_To_v1beta1_KubeadmConfigTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec(in *v1beta1.KubeadmConfigTemplateSpec, out *KubeadmConfigTemplateSpec, s conversion.Scope) error { + if err := Convert_v1beta1_KubeadmConfigTemplateResource_To_v1alpha3_KubeadmConfigTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec(in *v1beta1.KubeadmConfigTemplateSpec, out *KubeadmConfigTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmConfigTemplateSpec_To_v1alpha3_KubeadmConfigTemplateSpec(in, out, s) +} + +func autoConvert_v1alpha3_NTP_To_v1beta1_NTP(in *NTP, out *v1beta1.NTP, s conversion.Scope) error { + out.Servers = *(*[]string)(unsafe.Pointer(&in.Servers)) + out.Enabled = (*bool)(unsafe.Pointer(in.Enabled)) + return nil +} + +// Convert_v1alpha3_NTP_To_v1beta1_NTP is an autogenerated conversion function. +func Convert_v1alpha3_NTP_To_v1beta1_NTP(in *NTP, out *v1beta1.NTP, s conversion.Scope) error { + return autoConvert_v1alpha3_NTP_To_v1beta1_NTP(in, out, s) +} + +func autoConvert_v1beta1_NTP_To_v1alpha3_NTP(in *v1beta1.NTP, out *NTP, s conversion.Scope) error { + out.Servers = *(*[]string)(unsafe.Pointer(&in.Servers)) + out.Enabled = (*bool)(unsafe.Pointer(in.Enabled)) + return nil +} + +// Convert_v1beta1_NTP_To_v1alpha3_NTP is an autogenerated conversion function. +func Convert_v1beta1_NTP_To_v1alpha3_NTP(in *v1beta1.NTP, out *NTP, s conversion.Scope) error { + return autoConvert_v1beta1_NTP_To_v1alpha3_NTP(in, out, s) +} + +func autoConvert_v1alpha3_Partition_To_v1beta1_Partition(in *Partition, out *v1beta1.Partition, s conversion.Scope) error { + out.Device = in.Device + out.Layout = in.Layout + out.Overwrite = (*bool)(unsafe.Pointer(in.Overwrite)) + out.TableType = (*string)(unsafe.Pointer(in.TableType)) + return nil +} + +// Convert_v1alpha3_Partition_To_v1beta1_Partition is an autogenerated conversion function. +func Convert_v1alpha3_Partition_To_v1beta1_Partition(in *Partition, out *v1beta1.Partition, s conversion.Scope) error { + return autoConvert_v1alpha3_Partition_To_v1beta1_Partition(in, out, s) +} + +func autoConvert_v1beta1_Partition_To_v1alpha3_Partition(in *v1beta1.Partition, out *Partition, s conversion.Scope) error { + out.Device = in.Device + out.Layout = in.Layout + out.Overwrite = (*bool)(unsafe.Pointer(in.Overwrite)) + out.TableType = (*string)(unsafe.Pointer(in.TableType)) + return nil +} + +// Convert_v1beta1_Partition_To_v1alpha3_Partition is an autogenerated conversion function. +func Convert_v1beta1_Partition_To_v1alpha3_Partition(in *v1beta1.Partition, out *Partition, s conversion.Scope) error { + return autoConvert_v1beta1_Partition_To_v1alpha3_Partition(in, out, s) +} + +func autoConvert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource(in *SecretFileSource, out *v1beta1.SecretFileSource, s conversion.Scope) error { + out.Name = in.Name + out.Key = in.Key + return nil +} + +// Convert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource is an autogenerated conversion function. +func Convert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource(in *SecretFileSource, out *v1beta1.SecretFileSource, s conversion.Scope) error { + return autoConvert_v1alpha3_SecretFileSource_To_v1beta1_SecretFileSource(in, out, s) +} + +func autoConvert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource(in *v1beta1.SecretFileSource, out *SecretFileSource, s conversion.Scope) error { + out.Name = in.Name + out.Key = in.Key + return nil +} + +// Convert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource is an autogenerated conversion function. +func Convert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource(in *v1beta1.SecretFileSource, out *SecretFileSource, s conversion.Scope) error { + return autoConvert_v1beta1_SecretFileSource_To_v1alpha3_SecretFileSource(in, out, s) +} + +func autoConvert_v1alpha3_User_To_v1beta1_User(in *User, out *v1beta1.User, s conversion.Scope) error { + out.Name = in.Name + out.Gecos = (*string)(unsafe.Pointer(in.Gecos)) + out.Groups = (*string)(unsafe.Pointer(in.Groups)) + out.HomeDir = (*string)(unsafe.Pointer(in.HomeDir)) + out.Inactive = (*bool)(unsafe.Pointer(in.Inactive)) + out.Shell = (*string)(unsafe.Pointer(in.Shell)) + out.Passwd = (*string)(unsafe.Pointer(in.Passwd)) + out.PrimaryGroup = (*string)(unsafe.Pointer(in.PrimaryGroup)) + out.LockPassword = (*bool)(unsafe.Pointer(in.LockPassword)) + out.Sudo = (*string)(unsafe.Pointer(in.Sudo)) + out.SSHAuthorizedKeys = *(*[]string)(unsafe.Pointer(&in.SSHAuthorizedKeys)) + return nil +} + +// Convert_v1alpha3_User_To_v1beta1_User is an autogenerated conversion function. +func Convert_v1alpha3_User_To_v1beta1_User(in *User, out *v1beta1.User, s conversion.Scope) error { + return autoConvert_v1alpha3_User_To_v1beta1_User(in, out, s) +} + +func autoConvert_v1beta1_User_To_v1alpha3_User(in *v1beta1.User, out *User, s conversion.Scope) error { + out.Name = in.Name + out.Gecos = (*string)(unsafe.Pointer(in.Gecos)) + out.Groups = (*string)(unsafe.Pointer(in.Groups)) + out.HomeDir = (*string)(unsafe.Pointer(in.HomeDir)) + out.Inactive = (*bool)(unsafe.Pointer(in.Inactive)) + out.Shell = (*string)(unsafe.Pointer(in.Shell)) + out.Passwd = (*string)(unsafe.Pointer(in.Passwd)) + // WARNING: in.PasswdFrom requires manual conversion: does not exist in peer-type + out.PrimaryGroup = (*string)(unsafe.Pointer(in.PrimaryGroup)) + out.LockPassword = (*bool)(unsafe.Pointer(in.LockPassword)) + out.Sudo = (*string)(unsafe.Pointer(in.Sudo)) + out.SSHAuthorizedKeys = *(*[]string)(unsafe.Pointer(&in.SSHAuthorizedKeys)) + return nil +} diff --git a/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.deepcopy.go b/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..7273cb8498d2 --- /dev/null +++ b/internal/apis/bootstrap/kubeadm/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,537 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime" + apiv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DiskSetup) DeepCopyInto(out *DiskSetup) { + *out = *in + if in.Partitions != nil { + in, out := &in.Partitions, &out.Partitions + *out = make([]Partition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Filesystems != nil { + in, out := &in.Filesystems, &out.Filesystems + *out = make([]Filesystem, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DiskSetup. +func (in *DiskSetup) DeepCopy() *DiskSetup { + if in == nil { + return nil + } + out := new(DiskSetup) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *File) DeepCopyInto(out *File) { + *out = *in + if in.ContentFrom != nil { + in, out := &in.ContentFrom, &out.ContentFrom + *out = new(FileSource) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new File. +func (in *File) DeepCopy() *File { + if in == nil { + return nil + } + out := new(File) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FileSource) DeepCopyInto(out *FileSource) { + *out = *in + out.Secret = in.Secret +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FileSource. +func (in *FileSource) DeepCopy() *FileSource { + if in == nil { + return nil + } + out := new(FileSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Filesystem) DeepCopyInto(out *Filesystem) { + *out = *in + if in.Partition != nil { + in, out := &in.Partition, &out.Partition + *out = new(string) + **out = **in + } + if in.Overwrite != nil { + in, out := &in.Overwrite, &out.Overwrite + *out = new(bool) + **out = **in + } + if in.ReplaceFS != nil { + in, out := &in.ReplaceFS, &out.ReplaceFS + *out = new(string) + **out = **in + } + if in.ExtraOpts != nil { + in, out := &in.ExtraOpts, &out.ExtraOpts + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Filesystem. +func (in *Filesystem) DeepCopy() *Filesystem { + if in == nil { + return nil + } + out := new(Filesystem) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfig) DeepCopyInto(out *KubeadmConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfig. +func (in *KubeadmConfig) DeepCopy() *KubeadmConfig { + if in == nil { + return nil + } + out := new(KubeadmConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigList) DeepCopyInto(out *KubeadmConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigList. +func (in *KubeadmConfigList) DeepCopy() *KubeadmConfigList { + if in == nil { + return nil + } + out := new(KubeadmConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigSpec) DeepCopyInto(out *KubeadmConfigSpec) { + *out = *in + if in.ClusterConfiguration != nil { + in, out := &in.ClusterConfiguration, &out.ClusterConfiguration + *out = new(upstreamv1beta1.ClusterConfiguration) + (*in).DeepCopyInto(*out) + } + if in.InitConfiguration != nil { + in, out := &in.InitConfiguration, &out.InitConfiguration + *out = new(upstreamv1beta1.InitConfiguration) + (*in).DeepCopyInto(*out) + } + if in.JoinConfiguration != nil { + in, out := &in.JoinConfiguration, &out.JoinConfiguration + *out = new(upstreamv1beta1.JoinConfiguration) + (*in).DeepCopyInto(*out) + } + if in.Files != nil { + in, out := &in.Files, &out.Files + *out = make([]File, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DiskSetup != nil { + in, out := &in.DiskSetup, &out.DiskSetup + *out = new(DiskSetup) + (*in).DeepCopyInto(*out) + } + if in.Mounts != nil { + in, out := &in.Mounts, &out.Mounts + *out = make([]MountPoints, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = make(MountPoints, len(*in)) + copy(*out, *in) + } + } + } + if in.PreKubeadmCommands != nil { + in, out := &in.PreKubeadmCommands, &out.PreKubeadmCommands + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.PostKubeadmCommands != nil { + in, out := &in.PostKubeadmCommands, &out.PostKubeadmCommands + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Users != nil { + in, out := &in.Users, &out.Users + *out = make([]User, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.NTP != nil { + in, out := &in.NTP, &out.NTP + *out = new(NTP) + (*in).DeepCopyInto(*out) + } + if in.Verbosity != nil { + in, out := &in.Verbosity, &out.Verbosity + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigSpec. +func (in *KubeadmConfigSpec) DeepCopy() *KubeadmConfigSpec { + if in == nil { + return nil + } + out := new(KubeadmConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigStatus) DeepCopyInto(out *KubeadmConfigStatus) { + *out = *in + if in.DataSecretName != nil { + in, out := &in.DataSecretName, &out.DataSecretName + *out = new(string) + **out = **in + } + if in.BootstrapData != nil { + in, out := &in.BootstrapData, &out.BootstrapData + *out = make([]byte, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigStatus. +func (in *KubeadmConfigStatus) DeepCopy() *KubeadmConfigStatus { + if in == nil { + return nil + } + out := new(KubeadmConfigStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigTemplate) DeepCopyInto(out *KubeadmConfigTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigTemplate. +func (in *KubeadmConfigTemplate) DeepCopy() *KubeadmConfigTemplate { + if in == nil { + return nil + } + out := new(KubeadmConfigTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmConfigTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigTemplateList) DeepCopyInto(out *KubeadmConfigTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmConfigTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigTemplateList. +func (in *KubeadmConfigTemplateList) DeepCopy() *KubeadmConfigTemplateList { + if in == nil { + return nil + } + out := new(KubeadmConfigTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmConfigTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigTemplateResource) DeepCopyInto(out *KubeadmConfigTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigTemplateResource. +func (in *KubeadmConfigTemplateResource) DeepCopy() *KubeadmConfigTemplateResource { + if in == nil { + return nil + } + out := new(KubeadmConfigTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmConfigTemplateSpec) DeepCopyInto(out *KubeadmConfigTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmConfigTemplateSpec. +func (in *KubeadmConfigTemplateSpec) DeepCopy() *KubeadmConfigTemplateSpec { + if in == nil { + return nil + } + out := new(KubeadmConfigTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in MountPoints) DeepCopyInto(out *MountPoints) { + { + in := &in + *out = make(MountPoints, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MountPoints. +func (in MountPoints) DeepCopy() MountPoints { + if in == nil { + return nil + } + out := new(MountPoints) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NTP) DeepCopyInto(out *NTP) { + *out = *in + if in.Servers != nil { + in, out := &in.Servers, &out.Servers + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NTP. +func (in *NTP) DeepCopy() *NTP { + if in == nil { + return nil + } + out := new(NTP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Partition) DeepCopyInto(out *Partition) { + *out = *in + if in.Overwrite != nil { + in, out := &in.Overwrite, &out.Overwrite + *out = new(bool) + **out = **in + } + if in.TableType != nil { + in, out := &in.TableType, &out.TableType + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Partition. +func (in *Partition) DeepCopy() *Partition { + if in == nil { + return nil + } + out := new(Partition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretFileSource) DeepCopyInto(out *SecretFileSource) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretFileSource. +func (in *SecretFileSource) DeepCopy() *SecretFileSource { + if in == nil { + return nil + } + out := new(SecretFileSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *User) DeepCopyInto(out *User) { + *out = *in + if in.Gecos != nil { + in, out := &in.Gecos, &out.Gecos + *out = new(string) + **out = **in + } + if in.Groups != nil { + in, out := &in.Groups, &out.Groups + *out = new(string) + **out = **in + } + if in.HomeDir != nil { + in, out := &in.HomeDir, &out.HomeDir + *out = new(string) + **out = **in + } + if in.Inactive != nil { + in, out := &in.Inactive, &out.Inactive + *out = new(bool) + **out = **in + } + if in.Shell != nil { + in, out := &in.Shell, &out.Shell + *out = new(string) + **out = **in + } + if in.Passwd != nil { + in, out := &in.Passwd, &out.Passwd + *out = new(string) + **out = **in + } + if in.PrimaryGroup != nil { + in, out := &in.PrimaryGroup, &out.PrimaryGroup + *out = new(string) + **out = **in + } + if in.LockPassword != nil { + in, out := &in.LockPassword, &out.LockPassword + *out = new(bool) + **out = **in + } + if in.Sudo != nil { + in, out := &in.Sudo, &out.Sudo + *out = new(string) + **out = **in + } + if in.SSHAuthorizedKeys != nil { + in, out := &in.SSHAuthorizedKeys, &out.SSHAuthorizedKeys + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new User. +func (in *User) DeepCopy() *User { + if in == nil { + return nil + } + out := new(User) + in.DeepCopyInto(out) + return out +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/condition_consts.go b/internal/apis/controlplane/kubeadm/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..e84bd8a5ec7d --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/condition_consts.go @@ -0,0 +1,134 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + +// Conditions and condition Reasons for the KubeadmControlPlane object. + +const ( + // MachinesReadyCondition reports an aggregate of current status of the machines controlled by the KubeadmControlPlane. + MachinesReadyCondition clusterv1alpha3.ConditionType = "MachinesReady" +) + +const ( + // CertificatesAvailableCondition documents that cluster certificates were generated as part of the + // processing of a KubeadmControlPlane object. + CertificatesAvailableCondition clusterv1alpha3.ConditionType = "CertificatesAvailable" + + // CertificatesGenerationFailedReason (Severity=Warning) documents a KubeadmControlPlane controller detecting + // an error while generating certificates; those kind of errors are usually temporary and the controller + // automatically recover from them. + CertificatesGenerationFailedReason = "CertificatesGenerationFailed" +) + +const ( + // AvailableCondition documents that the first control plane instance has completed the kubeadm init operation + // and so the control plane is available and an API server instance is ready for processing requests. + AvailableCondition clusterv1alpha3.ConditionType = "Available" + + // WaitingForKubeadmInitReason (Severity=Info) documents a KubeadmControlPlane object waiting for the first + // control plane instance to complete the kubeadm init operation. + WaitingForKubeadmInitReason = "WaitingForKubeadmInit" +) + +const ( + // MachinesSpecUpToDateCondition documents that the spec of the machines controlled by the KubeadmControlPlane + // is up to date. When this condition is false, the KubeadmControlPlane is executing a rolling upgrade. + MachinesSpecUpToDateCondition clusterv1alpha3.ConditionType = "MachinesSpecUpToDate" + + // RollingUpdateInProgressReason (Severity=Warning) documents a KubeadmControlPlane object executing a + // rolling upgrade for aligning the machines spec to the desired state. + RollingUpdateInProgressReason = "RollingUpdateInProgress" +) + +const ( + // ResizedCondition documents a KubeadmControlPlane that is resizing the set of controlled machines. + ResizedCondition clusterv1alpha3.ConditionType = "Resized" + + // ScalingUpReason (Severity=Info) documents a KubeadmControlPlane that is increasing the number of replicas. + ScalingUpReason = "ScalingUp" + + // ScalingDownReason (Severity=Info) documents a KubeadmControlPlane that is decreasing the number of replicas. + ScalingDownReason = "ScalingDown" +) + +const ( + // ControlPlaneComponentsHealthyCondition reports the overall status of control plane components + // implemented as static pods generated by kubeadm including kube-api-server, kube-controller manager, + // kube-scheduler and etcd if managed. + ControlPlaneComponentsHealthyCondition clusterv1alpha3.ConditionType = "ControlPlaneComponentsHealthy" + + // ControlPlaneComponentsUnhealthyReason (Severity=Error) documents a control plane component not healthy. + ControlPlaneComponentsUnhealthyReason = "ControlPlaneComponentsUnhealthy" + + // ControlPlaneComponentsUnknownReason reports a control plane component in unknown status. + ControlPlaneComponentsUnknownReason = "ControlPlaneComponentsUnknown" + + // ControlPlaneComponentsInspectionFailedReason documents a failure in inspecting the control plane component status. + ControlPlaneComponentsInspectionFailedReason = "ControlPlaneComponentsInspectionFailed" + + // MachineAPIServerPodHealthyCondition reports a machine's kube-apiserver's operational status. + MachineAPIServerPodHealthyCondition clusterv1alpha3.ConditionType = "APIServerPodHealthy" + + // MachineControllerManagerPodHealthyCondition reports a machine's kube-controller-manager's health status. + MachineControllerManagerPodHealthyCondition clusterv1alpha3.ConditionType = "ControllerManagerPodHealthy" + + // MachineSchedulerPodHealthyCondition reports a machine's kube-scheduler's operational status. + MachineSchedulerPodHealthyCondition clusterv1alpha3.ConditionType = "SchedulerPodHealthy" + + // MachineEtcdPodHealthyCondition reports a machine's etcd pod's operational status. + // NOTE: This conditions exists only if a stacked etcd cluster is used. + MachineEtcdPodHealthyCondition clusterv1alpha3.ConditionType = "EtcdPodHealthy" + + // PodProvisioningReason (Severity=Info) documents a pod waiting to be provisioned i.e., Pod is in "Pending" phase. + PodProvisioningReason = "PodProvisioning" + + // PodMissingReason (Severity=Error) documents a pod does not exist. + PodMissingReason = "PodMissing" + + // PodFailedReason (Severity=Error) documents if a pod failed during provisioning i.e., e.g CrashLoopbackOff, ImagePullBackOff + // or if all the containers in a pod have terminated. + PodFailedReason = "PodFailed" + + // PodInspectionFailedReason documents a failure in inspecting the pod status. + PodInspectionFailedReason = "PodInspectionFailed" +) + +const ( + // EtcdClusterHealthyCondition documents the overall etcd cluster's health. + EtcdClusterHealthyCondition clusterv1alpha3.ConditionType = "EtcdClusterHealthyCondition" + + // EtcdClusterInspectionFailedReason documents a failure in inspecting the etcd cluster status. + EtcdClusterInspectionFailedReason = "EtcdClusterInspectionFailed" + + // EtcdClusterUnknownReason reports an etcd cluster in unknown status. + EtcdClusterUnknownReason = "EtcdClusterUnknown" + + // EtcdClusterUnhealthyReason (Severity=Error) is set when the etcd cluster is unhealthy. + EtcdClusterUnhealthyReason = "EtcdClusterUnhealthy" + + // MachineEtcdMemberHealthyCondition report the machine's etcd member's health status. + // NOTE: This conditions exists only if a stacked etcd cluster is used. + MachineEtcdMemberHealthyCondition clusterv1alpha3.ConditionType = "EtcdMemberHealthy" + + // EtcdMemberInspectionFailedReason documents a failure in inspecting the etcd member status. + EtcdMemberInspectionFailedReason = "MemberInspectionFailed" + + // EtcdMemberUnhealthyReason (Severity=Error) documents a Machine's etcd member is unhealthy. + EtcdMemberUnhealthyReason = "EtcdMemberUnhealthy" +) diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/conversion.go b/internal/apis/controlplane/kubeadm/v1alpha3/conversion.go new file mode 100644 index 000000000000..e8fb091e02d0 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/conversion.go @@ -0,0 +1,156 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *KubeadmControlPlane) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*controlplanev1.KubeadmControlPlane) + + if err := Convert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &controlplanev1.KubeadmControlPlane{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.MachineTemplate.ObjectMeta = restored.Spec.MachineTemplate.ObjectMeta + dst.Spec.MachineTemplate.NodeDeletionTimeout = restored.Spec.MachineTemplate.NodeDeletionTimeout + dst.Spec.KubeadmConfigSpec.Files = restored.Spec.KubeadmConfigSpec.Files + dst.Spec.KubeadmConfigSpec.Users = restored.Spec.KubeadmConfigSpec.Users + dst.Spec.MachineTemplate.NodeVolumeDetachTimeout = restored.Spec.MachineTemplate.NodeVolumeDetachTimeout + dst.Status.Version = restored.Status.Version + + if restored.Spec.KubeadmConfigSpec.Users != nil { + for i := range restored.Spec.KubeadmConfigSpec.Users { + if restored.Spec.KubeadmConfigSpec.Users[i].PasswdFrom != nil { + dst.Spec.KubeadmConfigSpec.Users[i].PasswdFrom = restored.Spec.KubeadmConfigSpec.Users[i].PasswdFrom + } + } + } + + if restored.Spec.KubeadmConfigSpec.JoinConfiguration != nil && restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.KubeadmConfigSpec.JoinConfiguration == nil { + dst.Spec.KubeadmConfigSpec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.IgnorePreflightErrors + } + + if restored.Spec.KubeadmConfigSpec.InitConfiguration != nil && restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors != nil { + if dst.Spec.KubeadmConfigSpec.InitConfiguration == nil { + dst.Spec.KubeadmConfigSpec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors = restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.IgnorePreflightErrors + } + + dst.Spec.KubeadmConfigSpec.Ignition = restored.Spec.KubeadmConfigSpec.Ignition + if restored.Spec.KubeadmConfigSpec.InitConfiguration != nil { + if dst.Spec.KubeadmConfigSpec.InitConfiguration == nil { + dst.Spec.KubeadmConfigSpec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.KubeadmConfigSpec.InitConfiguration.Patches = restored.Spec.KubeadmConfigSpec.InitConfiguration.Patches + dst.Spec.KubeadmConfigSpec.InitConfiguration.SkipPhases = restored.Spec.KubeadmConfigSpec.InitConfiguration.SkipPhases + } + if restored.Spec.KubeadmConfigSpec.JoinConfiguration != nil { + if dst.Spec.KubeadmConfigSpec.JoinConfiguration == nil { + dst.Spec.KubeadmConfigSpec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.KubeadmConfigSpec.JoinConfiguration.Patches = restored.Spec.KubeadmConfigSpec.JoinConfiguration.Patches + dst.Spec.KubeadmConfigSpec.JoinConfiguration.SkipPhases = restored.Spec.KubeadmConfigSpec.JoinConfiguration.SkipPhases + } + + dst.Spec.RolloutBefore = restored.Spec.RolloutBefore + + if restored.Spec.KubeadmConfigSpec.JoinConfiguration != nil && restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.KubeadmConfigSpec.JoinConfiguration == nil { + dst.Spec.KubeadmConfigSpec.JoinConfiguration = &bootstrapv1.JoinConfiguration{} + } + dst.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.KubeadmConfigSpec.JoinConfiguration.NodeRegistration.ImagePullPolicy + } + + if restored.Spec.KubeadmConfigSpec.InitConfiguration != nil && restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.ImagePullPolicy != "" { + if dst.Spec.KubeadmConfigSpec.InitConfiguration == nil { + dst.Spec.KubeadmConfigSpec.InitConfiguration = &bootstrapv1.InitConfiguration{} + } + dst.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.ImagePullPolicy = restored.Spec.KubeadmConfigSpec.InitConfiguration.NodeRegistration.ImagePullPolicy + } + + if restored.Spec.RemediationStrategy != nil { + dst.Spec.RemediationStrategy = restored.Spec.RemediationStrategy + } + if restored.Status.LastRemediation != nil { + dst.Status.LastRemediation = restored.Status.LastRemediation + } + + return nil +} + +func (dst *KubeadmControlPlane) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*controlplanev1.KubeadmControlPlane) + + if err := Convert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *KubeadmControlPlaneList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*controlplanev1.KubeadmControlPlaneList) + + return Convert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList(src, dst, nil) +} + +func (dst *KubeadmControlPlaneList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*controlplanev1.KubeadmControlPlaneList) + + return Convert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList(src, dst, nil) +} + +func Convert_v1beta1_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlaneSpec(in *controlplanev1.KubeadmControlPlaneSpec, out *KubeadmControlPlaneSpec, s apiconversion.Scope) error { + out.UpgradeAfter = in.RolloutAfter + out.InfrastructureTemplate = in.MachineTemplate.InfrastructureRef + out.NodeDrainTimeout = in.MachineTemplate.NodeDrainTimeout + return autoConvert_v1beta1_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlaneSpec(in, out, s) +} + +func Convert_v1beta1_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPlaneStatus(in *controlplanev1.KubeadmControlPlaneStatus, out *KubeadmControlPlaneStatus, s apiconversion.Scope) error { + // NOTE: custom conversion func is required because status.Version does not exist in v1alpha3. + return autoConvert_v1beta1_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPlaneStatus(in, out, s) +} + +func Convert_v1alpha3_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(in *KubeadmControlPlaneSpec, out *controlplanev1.KubeadmControlPlaneSpec, s apiconversion.Scope) error { + out.RolloutAfter = in.UpgradeAfter + out.MachineTemplate.InfrastructureRef = in.InfrastructureTemplate + out.MachineTemplate.NodeDrainTimeout = in.NodeDrainTimeout + return autoConvert_v1alpha3_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(in, out, s) +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/conversion_test.go b/internal/apis/controlplane/kubeadm/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..2d8217c19da4 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/conversion_test.go @@ -0,0 +1,80 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + + bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1" + "sigs.k8s.io/cluster-api/bootstrap/kubeadm/types/upstreamv1beta1" + controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for KubeadmControlPlane", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &controlplanev1.KubeadmControlPlane{}, + Spoke: &KubeadmControlPlane{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) +} + +func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + // This custom function is needed when ConvertTo/ConvertFrom functions + // uses the json package to unmarshal the bootstrap token string. + // + // The Kubeadm v1beta1.BootstrapTokenString type ships with a custom + // json string representation, in particular it supplies a customized + // UnmarshalJSON function that can return an error if the string + // isn't in the correct form. + // + // This function effectively disables any fuzzing for the token by setting + // the values for ID and Secret to working alphanumeric values. + return []interface{}{ + kubeadmBootstrapTokenStringFuzzer, + cabpkBootstrapTokenStringFuzzer, + dnsFuzzer, + kubeadmClusterConfigurationFuzzer, + } +} + +func kubeadmBootstrapTokenStringFuzzer(in *upstreamv1beta1.BootstrapTokenString, _ fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} +func cabpkBootstrapTokenStringFuzzer(in *bootstrapv1.BootstrapTokenString, _ fuzz.Continue) { + in.ID = "abcdef" + in.Secret = "abcdef0123456789" +} + +func dnsFuzzer(obj *upstreamv1beta1.DNS, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // DNS.Type does not exists in v1alpha4, so setting it to empty string in order to avoid v1alpha3 --> v1alpha4 --> v1alpha3 round trip errors. + obj.Type = "" +} + +func kubeadmClusterConfigurationFuzzer(obj *upstreamv1beta1.ClusterConfiguration, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // ClusterConfiguration.UseHyperKubeImage has been removed in v1alpha4, so setting it to false in order to avoid v1alpha3 --> v1alpha4 --> v1alpha3 round trip errors. + obj.UseHyperKubeImage = false +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/doc.go b/internal/apis/controlplane/kubeadm/v1alpha3/doc.go new file mode 100644 index 000000000000..9c0ccfc20100 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/groupversion_info.go b/internal/apis/controlplane/kubeadm/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..f5d0d7553035 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the kubeadm v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=controlplane.cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "controlplane.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/kubeadm_control_plane_types.go b/internal/apis/controlplane/kubeadm/v1alpha3/kubeadm_control_plane_types.go new file mode 100644 index 000000000000..732f31f9e380 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/kubeadm_control_plane_types.go @@ -0,0 +1,234 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + "sigs.k8s.io/cluster-api/errors" + bootstrapv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3" + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +// RolloutStrategyType defines the rollout strategies for a KubeadmControlPlane. +type RolloutStrategyType string + +const ( + // RollingUpdateStrategyType replaces the old control planes by new one using rolling update + // i.e. gradually scale up or down the old control planes and scale up or down the new one. + RollingUpdateStrategyType RolloutStrategyType = "RollingUpdate" +) + +const ( + // KubeadmControlPlaneFinalizer is the finalizer applied to KubeadmControlPlane resources + // by its managing controller. + KubeadmControlPlaneFinalizer = "kubeadm.controlplane.cluster.x-k8s.io" + + // KubeadmControlPlaneHashLabelKey was used to determine the hash of the + // template used to generate a control plane machine. + // + // Deprecated: This label has been deprecated and it's not in use anymore. + KubeadmControlPlaneHashLabelKey = "kubeadm.controlplane.cluster.x-k8s.io/hash" + + // SkipCoreDNSAnnotation annotation explicitly skips reconciling CoreDNS if set. + SkipCoreDNSAnnotation = "controlplane.cluster.x-k8s.io/skip-coredns" + + // SkipKubeProxyAnnotation annotation explicitly skips reconciling kube-proxy if set. + SkipKubeProxyAnnotation = "controlplane.cluster.x-k8s.io/skip-kube-proxy" + + // KubeadmClusterConfigurationAnnotation is a machine annotation that stores the json-marshalled string of KCP ClusterConfiguration. + // This annotation is used to detect any changes in ClusterConfiguration and trigger machine rollout in KCP. + KubeadmClusterConfigurationAnnotation = "controlplane.cluster.x-k8s.io/kubeadm-cluster-configuration" +) + +// KubeadmControlPlaneSpec defines the desired state of KubeadmControlPlane. +type KubeadmControlPlaneSpec struct { + // Number of desired machines. Defaults to 1. When stacked etcd is used only + // odd numbers are permitted, as per [etcd best practice](https://etcd.io/docs/v3.3.12/faq/#why-an-odd-number-of-cluster-members). + // This is a pointer to distinguish between explicit zero and not specified. + // +optional + Replicas *int32 `json:"replicas,omitempty"` + + // Version defines the desired Kubernetes version. + Version string `json:"version"` + + // InfrastructureTemplate is a required reference to a custom resource + // offered by an infrastructure provider. + InfrastructureTemplate corev1.ObjectReference `json:"infrastructureTemplate"` + + // KubeadmConfigSpec is a KubeadmConfigSpec + // to use for initializing and joining machines to the control plane. + KubeadmConfigSpec bootstrapv1alpha3.KubeadmConfigSpec `json:"kubeadmConfigSpec"` + + // UpgradeAfter is a field to indicate an upgrade should be performed + // after the specified time even if no changes have been made to the + // KubeadmControlPlane + // +optional + UpgradeAfter *metav1.Time `json:"upgradeAfter,omitempty"` + + // NodeDrainTimeout is the total amount of time that the controller will spend on draining a controlplane node + // The default value is 0, meaning that the node can be drained without any time limitations. + // NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + // +optional + NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"` + + // The RolloutStrategy to use to replace control plane machines with + // new ones. + // +optional + RolloutStrategy *RolloutStrategy `json:"rolloutStrategy,omitempty"` +} + +// RolloutStrategy describes how to replace existing machines +// with new ones. +type RolloutStrategy struct { + // Type of rollout. Currently the only supported strategy is + // "RollingUpdate". + // Default is RollingUpdate. + // +optional + Type RolloutStrategyType `json:"type,omitempty"` + + // Rolling update config params. Present only if + // RolloutStrategyType = RollingUpdate. + // +optional + RollingUpdate *RollingUpdate `json:"rollingUpdate,omitempty"` +} + +// RollingUpdate is used to control the desired behavior of rolling update. +type RollingUpdate struct { + // The maximum number of control planes that can be scheduled above or under the + // desired number of control planes. + // Value can be an absolute number 1 or 0. + // Defaults to 1. + // Example: when this is set to 1, the control plane can be scaled + // up immediately when the rolling update starts. + // +optional + MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` +} + +// KubeadmControlPlaneStatus defines the observed state of KubeadmControlPlane. +type KubeadmControlPlaneStatus struct { + // Selector is the label selector in string format to avoid introspection + // by clients, and is used to provide the CRD-based integration for the + // scale subresource and additional integrations for things like kubectl + // describe.. The string will be in the same format as the query-param syntax. + // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // +optional + Selector string `json:"selector,omitempty"` + + // Total number of non-terminated machines targeted by this control plane + // (their labels match the selector). + // +optional + Replicas int32 `json:"replicas,omitempty"` + + // Total number of non-terminated machines targeted by this control plane + // that have the desired template spec. + // +optional + UpdatedReplicas int32 `json:"updatedReplicas,omitempty"` + + // Total number of fully running and ready control plane machines. + // +optional + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // Total number of unavailable machines targeted by this control plane. + // This is the total number of machines that are still required for + // the deployment to have 100% available capacity. They may either + // be machines that are running but not yet ready or machines + // that still have not been created. + // +optional + UnavailableReplicas int32 `json:"unavailableReplicas,omitempty"` + + // Initialized denotes whether or not the control plane has the + // uploaded kubeadm-config configmap. + // +optional + Initialized bool `json:"initialized"` + + // Ready denotes that the KubeadmControlPlane API Server is ready to + // receive requests. + // +optional + Ready bool `json:"ready"` + + // FailureReason indicates that there is a terminal problem reconciling the + // state, and will be set to a token value suitable for + // programmatic interpretation. + // +optional + FailureReason errors.KubeadmControlPlaneStatusError `json:"failureReason,omitempty"` + + // ErrorMessage indicates that there is a terminal problem reconciling the + // state, and will be set to a descriptive error message. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions defines current service state of the KubeadmControlPlane. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=kubeadmcontrolplanes,shortName=kcp,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector +// +kubebuilder:printcolumn:name="Initialized",type=boolean,JSONPath=".status.initialized",description="This denotes whether or not the control plane has the uploaded kubeadm-config configmap" +// +kubebuilder:printcolumn:name="API Server Available",type=boolean,JSONPath=".status.ready",description="KubeadmControlPlane API Server is ready to receive requests" +// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=".spec.version",description="Kubernetes version associated with this control plane" +// +kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this control plane" +// +kubebuilder:printcolumn:name="Ready",type=integer,JSONPath=".status.readyReplicas",description="Total number of fully running and ready control plane machines" +// +kubebuilder:printcolumn:name="Updated",type=integer,JSONPath=".status.updatedReplicas",description="Total number of non-terminated machines targeted by this control plane that have the desired template spec" +// +kubebuilder:printcolumn:name="Unavailable",type=integer,JSONPath=".status.unavailableReplicas",description="Total number of unavailable machines targeted by this control plane" + +// KubeadmControlPlane is the Schema for the KubeadmControlPlane API. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmControlPlane struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec KubeadmControlPlaneSpec `json:"spec,omitempty"` + Status KubeadmControlPlaneStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (in *KubeadmControlPlane) GetConditions() clusterv1alpha3.Conditions { + return in.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (in *KubeadmControlPlane) SetConditions(conditions clusterv1alpha3.Conditions) { + in.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// KubeadmControlPlaneList contains a list of KubeadmControlPlane. +// +// Deprecated: This type will be removed in one of the next releases. +type KubeadmControlPlaneList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []KubeadmControlPlane `json:"items"` +} + +func init() { + SchemeBuilder.Register(&KubeadmControlPlane{}, &KubeadmControlPlaneList{}) +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/suite_test.go b/internal/apis/controlplane/kubeadm/v1alpha3/suite_test.go new file mode 100644 index 000000000000..1bff9a48c8b3 --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/suite_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "os" + "testing" + + // +kubebuilder:scaffold:imports + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/cluster-api/internal/test/envtest" +) + +var ( + env *envtest.Environment + ctx = ctrl.SetupSignalHandler() +) + +func TestMain(m *testing.M) { + utilruntime.Must(AddToScheme(scheme.Scheme)) + + os.Exit(envtest.Run(ctx, envtest.RunInput{ + M: m, + SetupEnv: func(e *envtest.Environment) { env = e }, + })) +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.conversion.go b/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..795319d2d4de --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,305 @@ +//go:build !ignore_autogenerated_kubeadm_controlplane +// +build !ignore_autogenerated_kubeadm_controlplane + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + intstr "k8s.io/apimachinery/pkg/util/intstr" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + v1beta1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1" + errors "sigs.k8s.io/cluster-api/errors" + kubeadmv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/bootstrap/kubeadm/v1alpha3" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*KubeadmControlPlane)(nil), (*v1beta1.KubeadmControlPlane)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(a.(*KubeadmControlPlane), b.(*v1beta1.KubeadmControlPlane), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmControlPlane)(nil), (*KubeadmControlPlane)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(a.(*v1beta1.KubeadmControlPlane), b.(*KubeadmControlPlane), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmControlPlaneList)(nil), (*v1beta1.KubeadmControlPlaneList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList(a.(*KubeadmControlPlaneList), b.(*v1beta1.KubeadmControlPlaneList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.KubeadmControlPlaneList)(nil), (*KubeadmControlPlaneList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList(a.(*v1beta1.KubeadmControlPlaneList), b.(*KubeadmControlPlaneList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*KubeadmControlPlaneStatus)(nil), (*v1beta1.KubeadmControlPlaneStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus(a.(*KubeadmControlPlaneStatus), b.(*v1beta1.KubeadmControlPlaneStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*RollingUpdate)(nil), (*v1beta1.RollingUpdate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_RollingUpdate_To_v1beta1_RollingUpdate(a.(*RollingUpdate), b.(*v1beta1.RollingUpdate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.RollingUpdate)(nil), (*RollingUpdate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RollingUpdate_To_v1alpha3_RollingUpdate(a.(*v1beta1.RollingUpdate), b.(*RollingUpdate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*RolloutStrategy)(nil), (*v1beta1.RolloutStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_RolloutStrategy_To_v1beta1_RolloutStrategy(a.(*RolloutStrategy), b.(*v1beta1.RolloutStrategy), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.RolloutStrategy)(nil), (*RolloutStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RolloutStrategy_To_v1alpha3_RolloutStrategy(a.(*v1beta1.RolloutStrategy), b.(*RolloutStrategy), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*KubeadmControlPlaneSpec)(nil), (*v1beta1.KubeadmControlPlaneSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(a.(*KubeadmControlPlaneSpec), b.(*v1beta1.KubeadmControlPlaneSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.KubeadmControlPlaneSpec)(nil), (*KubeadmControlPlaneSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlaneSpec(a.(*v1beta1.KubeadmControlPlaneSpec), b.(*KubeadmControlPlaneSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.KubeadmControlPlaneStatus)(nil), (*KubeadmControlPlaneStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPlaneStatus(a.(*v1beta1.KubeadmControlPlaneStatus), b.(*KubeadmControlPlaneStatus), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(in *KubeadmControlPlane, out *v1beta1.KubeadmControlPlane, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(in *KubeadmControlPlane, out *v1beta1.KubeadmControlPlane, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(in, out, s) +} + +func autoConvert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(in *v1beta1.KubeadmControlPlane, out *KubeadmControlPlane, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlaneSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPlaneStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane is an autogenerated conversion function. +func Convert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(in *v1beta1.KubeadmControlPlane, out *KubeadmControlPlane, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList(in *KubeadmControlPlaneList, out *v1beta1.KubeadmControlPlaneList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.KubeadmControlPlane, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_KubeadmControlPlane_To_v1beta1_KubeadmControlPlane(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList(in *KubeadmControlPlaneList, out *v1beta1.KubeadmControlPlaneList, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmControlPlaneList_To_v1beta1_KubeadmControlPlaneList(in, out, s) +} + +func autoConvert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList(in *v1beta1.KubeadmControlPlaneList, out *KubeadmControlPlaneList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmControlPlane, len(*in)) + for i := range *in { + if err := Convert_v1beta1_KubeadmControlPlane_To_v1alpha3_KubeadmControlPlane(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList is an autogenerated conversion function. +func Convert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList(in *v1beta1.KubeadmControlPlaneList, out *KubeadmControlPlaneList, s conversion.Scope) error { + return autoConvert_v1beta1_KubeadmControlPlaneList_To_v1alpha3_KubeadmControlPlaneList(in, out, s) +} + +func autoConvert_v1alpha3_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(in *KubeadmControlPlaneSpec, out *v1beta1.KubeadmControlPlaneSpec, s conversion.Scope) error { + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.Version = in.Version + // WARNING: in.InfrastructureTemplate requires manual conversion: does not exist in peer-type + if err := kubeadmv1alpha3.Convert_v1alpha3_KubeadmConfigSpec_To_v1beta1_KubeadmConfigSpec(&in.KubeadmConfigSpec, &out.KubeadmConfigSpec, s); err != nil { + return err + } + // WARNING: in.UpgradeAfter requires manual conversion: does not exist in peer-type + // WARNING: in.NodeDrainTimeout requires manual conversion: does not exist in peer-type + out.RolloutStrategy = (*v1beta1.RolloutStrategy)(unsafe.Pointer(in.RolloutStrategy)) + return nil +} + +func autoConvert_v1beta1_KubeadmControlPlaneSpec_To_v1alpha3_KubeadmControlPlaneSpec(in *v1beta1.KubeadmControlPlaneSpec, out *KubeadmControlPlaneSpec, s conversion.Scope) error { + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.Version = in.Version + // WARNING: in.MachineTemplate requires manual conversion: does not exist in peer-type + if err := kubeadmv1alpha3.Convert_v1beta1_KubeadmConfigSpec_To_v1alpha3_KubeadmConfigSpec(&in.KubeadmConfigSpec, &out.KubeadmConfigSpec, s); err != nil { + return err + } + // WARNING: in.RolloutBefore requires manual conversion: does not exist in peer-type + // WARNING: in.RolloutAfter requires manual conversion: does not exist in peer-type + out.RolloutStrategy = (*RolloutStrategy)(unsafe.Pointer(in.RolloutStrategy)) + // WARNING: in.RemediationStrategy requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus(in *KubeadmControlPlaneStatus, out *v1beta1.KubeadmControlPlaneStatus, s conversion.Scope) error { + out.Selector = in.Selector + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + out.ReadyReplicas = in.ReadyReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.Initialized = in.Initialized + out.Ready = in.Ready + out.FailureReason = errors.KubeadmControlPlaneStatusError(in.FailureReason) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus is an autogenerated conversion function. +func Convert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus(in *KubeadmControlPlaneStatus, out *v1beta1.KubeadmControlPlaneStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_KubeadmControlPlaneStatus_To_v1beta1_KubeadmControlPlaneStatus(in, out, s) +} + +func autoConvert_v1beta1_KubeadmControlPlaneStatus_To_v1alpha3_KubeadmControlPlaneStatus(in *v1beta1.KubeadmControlPlaneStatus, out *KubeadmControlPlaneStatus, s conversion.Scope) error { + out.Selector = in.Selector + out.Replicas = in.Replicas + // WARNING: in.Version requires manual conversion: does not exist in peer-type + out.UpdatedReplicas = in.UpdatedReplicas + out.ReadyReplicas = in.ReadyReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.Initialized = in.Initialized + out.Ready = in.Ready + out.FailureReason = errors.KubeadmControlPlaneStatusError(in.FailureReason) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + // WARNING: in.LastRemediation requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_RollingUpdate_To_v1beta1_RollingUpdate(in *RollingUpdate, out *v1beta1.RollingUpdate, s conversion.Scope) error { + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + return nil +} + +// Convert_v1alpha3_RollingUpdate_To_v1beta1_RollingUpdate is an autogenerated conversion function. +func Convert_v1alpha3_RollingUpdate_To_v1beta1_RollingUpdate(in *RollingUpdate, out *v1beta1.RollingUpdate, s conversion.Scope) error { + return autoConvert_v1alpha3_RollingUpdate_To_v1beta1_RollingUpdate(in, out, s) +} + +func autoConvert_v1beta1_RollingUpdate_To_v1alpha3_RollingUpdate(in *v1beta1.RollingUpdate, out *RollingUpdate, s conversion.Scope) error { + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + return nil +} + +// Convert_v1beta1_RollingUpdate_To_v1alpha3_RollingUpdate is an autogenerated conversion function. +func Convert_v1beta1_RollingUpdate_To_v1alpha3_RollingUpdate(in *v1beta1.RollingUpdate, out *RollingUpdate, s conversion.Scope) error { + return autoConvert_v1beta1_RollingUpdate_To_v1alpha3_RollingUpdate(in, out, s) +} + +func autoConvert_v1alpha3_RolloutStrategy_To_v1beta1_RolloutStrategy(in *RolloutStrategy, out *v1beta1.RolloutStrategy, s conversion.Scope) error { + out.Type = v1beta1.RolloutStrategyType(in.Type) + out.RollingUpdate = (*v1beta1.RollingUpdate)(unsafe.Pointer(in.RollingUpdate)) + return nil +} + +// Convert_v1alpha3_RolloutStrategy_To_v1beta1_RolloutStrategy is an autogenerated conversion function. +func Convert_v1alpha3_RolloutStrategy_To_v1beta1_RolloutStrategy(in *RolloutStrategy, out *v1beta1.RolloutStrategy, s conversion.Scope) error { + return autoConvert_v1alpha3_RolloutStrategy_To_v1beta1_RolloutStrategy(in, out, s) +} + +func autoConvert_v1beta1_RolloutStrategy_To_v1alpha3_RolloutStrategy(in *v1beta1.RolloutStrategy, out *RolloutStrategy, s conversion.Scope) error { + out.Type = RolloutStrategyType(in.Type) + out.RollingUpdate = (*RollingUpdate)(unsafe.Pointer(in.RollingUpdate)) + return nil +} + +// Convert_v1beta1_RolloutStrategy_To_v1alpha3_RolloutStrategy is an autogenerated conversion function. +func Convert_v1beta1_RolloutStrategy_To_v1alpha3_RolloutStrategy(in *v1beta1.RolloutStrategy, out *RolloutStrategy, s conversion.Scope) error { + return autoConvert_v1beta1_RolloutStrategy_To_v1alpha3_RolloutStrategy(in, out, s) +} diff --git a/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.deepcopy.go b/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..01589af55c3b --- /dev/null +++ b/internal/apis/controlplane/kubeadm/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,190 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + apiv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmControlPlane) DeepCopyInto(out *KubeadmControlPlane) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmControlPlane. +func (in *KubeadmControlPlane) DeepCopy() *KubeadmControlPlane { + if in == nil { + return nil + } + out := new(KubeadmControlPlane) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmControlPlane) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmControlPlaneList) DeepCopyInto(out *KubeadmControlPlaneList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KubeadmControlPlane, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmControlPlaneList. +func (in *KubeadmControlPlaneList) DeepCopy() *KubeadmControlPlaneList { + if in == nil { + return nil + } + out := new(KubeadmControlPlaneList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KubeadmControlPlaneList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmControlPlaneSpec) DeepCopyInto(out *KubeadmControlPlaneSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + out.InfrastructureTemplate = in.InfrastructureTemplate + in.KubeadmConfigSpec.DeepCopyInto(&out.KubeadmConfigSpec) + if in.UpgradeAfter != nil { + in, out := &in.UpgradeAfter, &out.UpgradeAfter + *out = (*in).DeepCopy() + } + if in.NodeDrainTimeout != nil { + in, out := &in.NodeDrainTimeout, &out.NodeDrainTimeout + *out = new(v1.Duration) + **out = **in + } + if in.RolloutStrategy != nil { + in, out := &in.RolloutStrategy, &out.RolloutStrategy + *out = new(RolloutStrategy) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmControlPlaneSpec. +func (in *KubeadmControlPlaneSpec) DeepCopy() *KubeadmControlPlaneSpec { + if in == nil { + return nil + } + out := new(KubeadmControlPlaneSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KubeadmControlPlaneStatus) DeepCopyInto(out *KubeadmControlPlaneStatus) { + *out = *in + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeadmControlPlaneStatus. +func (in *KubeadmControlPlaneStatus) DeepCopy() *KubeadmControlPlaneStatus { + if in == nil { + return nil + } + out := new(KubeadmControlPlaneStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RollingUpdate) DeepCopyInto(out *RollingUpdate) { + *out = *in + if in.MaxSurge != nil { + in, out := &in.MaxSurge, &out.MaxSurge + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RollingUpdate. +func (in *RollingUpdate) DeepCopy() *RollingUpdate { + if in == nil { + return nil + } + out := new(RollingUpdate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RolloutStrategy) DeepCopyInto(out *RolloutStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(RollingUpdate) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutStrategy. +func (in *RolloutStrategy) DeepCopy() *RolloutStrategy { + if in == nil { + return nil + } + out := new(RolloutStrategy) + in.DeepCopyInto(out) + return out +} diff --git a/internal/apis/core/exp/addons/v1alpha3/clusterresourceset_types.go b/internal/apis/core/exp/addons/v1alpha3/clusterresourceset_types.go new file mode 100644 index 000000000000..81d270eeb204 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/clusterresourceset_types.go @@ -0,0 +1,143 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +const ( + // ClusterResourceSetSecretType is the only accepted type of secret in resources. + ClusterResourceSetSecretType corev1.SecretType = "addons.cluster.x-k8s.io/resource-set" //nolint:gosec + + // ClusterResourceSetFinalizer is added to the ClusterResourceSet object for additional cleanup logic on deletion. + ClusterResourceSetFinalizer = "addons.cluster.x-k8s.io" +) + +// ANCHOR: ClusterResourceSetSpec + +// ClusterResourceSetSpec defines the desired state of ClusterResourceSet. +type ClusterResourceSetSpec struct { + // Label selector for Clusters. The Clusters that are + // selected by this will be the ones affected by this ClusterResourceSet. + // It must match the Cluster labels. This field is immutable. + ClusterSelector metav1.LabelSelector `json:"clusterSelector"` + + // Resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters. + Resources []ResourceRef `json:"resources,omitempty"` + + // Strategy is the strategy to be used during applying resources. Defaults to ApplyOnce. This field is immutable. + // +kubebuilder:validation:Enum=ApplyOnce + // +optional + Strategy string `json:"strategy,omitempty"` +} + +// ANCHOR_END: ClusterResourceSetSpec + +// ClusterResourceSetResourceKind is a string representation of a ClusterResourceSet resource kind. +type ClusterResourceSetResourceKind string + +// Define the ClusterResourceSetResourceKind constants. +const ( + SecretClusterResourceSetResourceKind ClusterResourceSetResourceKind = "Secret" + ConfigMapClusterResourceSetResourceKind ClusterResourceSetResourceKind = "ConfigMap" +) + +// ResourceRef specifies a resource. +type ResourceRef struct { + // Name of the resource that is in the same namespace with ClusterResourceSet object. + // +kubebuilder:validation:MinLength=1 + Name string `json:"name"` + + // Kind of the resource. Supported kinds are: Secrets and ConfigMaps. + // +kubebuilder:validation:Enum=Secret;ConfigMap + Kind string `json:"kind"` +} + +// ClusterResourceSetStrategy is a string representation of a ClusterResourceSet Strategy. +type ClusterResourceSetStrategy string + +const ( + // ClusterResourceSetStrategyApplyOnce is the default strategy a ClusterResourceSet strategy is assigned by + // ClusterResourceSet controller after being created if not specified by user. + ClusterResourceSetStrategyApplyOnce ClusterResourceSetStrategy = "ApplyOnce" +) + +// SetTypedStrategy sets the Strategy field to the string representation of ClusterResourceSetStrategy. +func (c *ClusterResourceSetSpec) SetTypedStrategy(p ClusterResourceSetStrategy) { + c.Strategy = string(p) +} + +// ANCHOR: ClusterResourceSetStatus + +// ClusterResourceSetStatus defines the observed state of ClusterResourceSet. +type ClusterResourceSetStatus struct { + // ObservedGeneration reflects the generation of the most recently observed ClusterResourceSet. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions defines current state of the ClusterResourceSet. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// ANCHOR_END: ClusterResourceSetStatus + +// GetConditions returns the set of conditions for this object. +func (m *ClusterResourceSet) GetConditions() clusterv1alpha3.Conditions { + return m.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (m *ClusterResourceSet) SetConditions(conditions clusterv1alpha3.Conditions) { + m.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=clusterresourcesets,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status + +// ClusterResourceSet is the Schema for the clusterresourcesets API. +// +// Deprecated: This type will be removed in one of the next releases. +type ClusterResourceSet struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterResourceSetSpec `json:"spec,omitempty"` + Status ClusterResourceSetStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ClusterResourceSetList contains a list of ClusterResourceSet. +// +// Deprecated: This type will be removed in one of the next releases. +type ClusterResourceSetList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterResourceSet `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterResourceSet{}, &ClusterResourceSetList{}) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types.go b/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types.go new file mode 100644 index 000000000000..101c2cf11893 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types.go @@ -0,0 +1,141 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "reflect" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ANCHOR: ResourceBinding + +// ResourceBinding shows the status of a resource that belongs to a ClusterResourceSet matched by the owner cluster of the ClusterResourceSetBinding object. +type ResourceBinding struct { + // ResourceRef specifies a resource. + ResourceRef `json:",inline"` + + // Hash is the hash of a resource's data. This can be used to decide if a resource is changed. + // For "ApplyOnce" ClusterResourceSet.spec.strategy, this is no-op as that strategy does not act on change. + Hash string `json:"hash,omitempty"` + + // LastAppliedTime identifies when this resource was last applied to the cluster. + // +optional + LastAppliedTime *metav1.Time `json:"lastAppliedTime,omitempty"` + + // Applied is to track if a resource is applied to the cluster or not. + Applied bool `json:"applied"` +} + +// ANCHOR_END: ResourceBinding + +// ResourceSetBinding keeps info on all of the resources in a ClusterResourceSet. +type ResourceSetBinding struct { + // ClusterResourceSetName is the name of the ClusterResourceSet that is applied to the owner cluster of the binding. + ClusterResourceSetName string `json:"clusterResourceSetName"` + + // Resources is a list of resources that the ClusterResourceSet has. + Resources []ResourceBinding `json:"resources,omitempty"` +} + +// IsApplied returns true if the resource is applied to the cluster by checking the cluster's binding. +func (r *ResourceSetBinding) IsApplied(resourceRef ResourceRef) bool { + for _, resource := range r.Resources { + if reflect.DeepEqual(resource.ResourceRef, resourceRef) { + if resource.Applied { + return true + } + } + } + return false +} + +// SetBinding sets resourceBinding for a resource in resourceSetbinding either by updating the existing one or +// creating a new one. +func (r *ResourceSetBinding) SetBinding(resourceBinding ResourceBinding) { + for i := range r.Resources { + if reflect.DeepEqual(r.Resources[i].ResourceRef, resourceBinding.ResourceRef) { + r.Resources[i] = resourceBinding + return + } + } + r.Resources = append(r.Resources, resourceBinding) +} + +// GetOrCreateBinding returns the ResourceSetBinding for a given ClusterResourceSet if exists, +// otherwise creates one and updates ClusterResourceSet with it. +func (c *ClusterResourceSetBinding) GetOrCreateBinding(clusterResourceSet *ClusterResourceSet) *ResourceSetBinding { + for _, binding := range c.Spec.Bindings { + if binding.ClusterResourceSetName == clusterResourceSet.Name { + return binding + } + } + binding := &ResourceSetBinding{ClusterResourceSetName: clusterResourceSet.Name, Resources: []ResourceBinding{}} + c.Spec.Bindings = append(c.Spec.Bindings, binding) + return binding +} + +// DeleteBinding removes the ClusterResourceSet from the ClusterResourceSetBinding Bindings list. +func (c *ClusterResourceSetBinding) DeleteBinding(clusterResourceSet *ClusterResourceSet) { + for i, binding := range c.Spec.Bindings { + if binding.ClusterResourceSetName == clusterResourceSet.Name { + copy(c.Spec.Bindings[i:], c.Spec.Bindings[i+1:]) + c.Spec.Bindings = c.Spec.Bindings[:len(c.Spec.Bindings)-1] + break + } + } +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=clusterresourcesetbindings,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status + +// ClusterResourceSetBinding lists all matching ClusterResourceSets with the cluster it belongs to. +// +// Deprecated: This type will be removed in one of the next releases. +type ClusterResourceSetBinding struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + Spec ClusterResourceSetBindingSpec `json:"spec,omitempty"` +} + +// ANCHOR: ClusterResourceSetBindingSpec + +// ClusterResourceSetBindingSpec defines the desired state of ClusterResourceSetBinding. +type ClusterResourceSetBindingSpec struct { + // Bindings is a list of ClusterResourceSets and their resources. + Bindings []*ResourceSetBinding `json:"bindings,omitempty"` +} + +// ANCHOR_END: ClusterResourceSetBindingSpec + +// +kubebuilder:object:root=true + +// ClusterResourceSetBindingList contains a list of ClusterResourceSetBinding. +// +// Deprecated: This type will be removed in one of the next releases. +type ClusterResourceSetBindingList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterResourceSetBinding `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterResourceSetBinding{}, &ClusterResourceSetBindingList{}) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types_test.go b/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types_test.go new file mode 100644 index 000000000000..64f2afa96d13 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/clusterresourcesetbinding_types_test.go @@ -0,0 +1,158 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "reflect" + "testing" + "time" + + . "github.com/onsi/gomega" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestIsResourceApplied(t *testing.T) { + resourceRefApplyFailed := ResourceRef{ + Name: "applyFailed", + Kind: "Secret", + } + resourceRefApplySucceeded := ResourceRef{ + Name: "ApplySucceeded", + Kind: "Secret", + } + resourceRefNotExist := ResourceRef{ + Name: "notExist", + Kind: "Secret", + } + CRSBinding := &ResourceSetBinding{ + ClusterResourceSetName: "test-clusterResourceSet", + Resources: []ResourceBinding{ + { + ResourceRef: resourceRefApplySucceeded, + Applied: true, + Hash: "xyz", + LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, + }, + { + ResourceRef: resourceRefApplyFailed, + Applied: false, + Hash: "", + LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, + }, + }, + } + + tests := []struct { + name string + resourceSetBinding *ResourceSetBinding + resourceRef ResourceRef + isApplied bool + }{ + { + name: "should return true if the resource is applied successfully", + resourceSetBinding: CRSBinding, + resourceRef: resourceRefApplySucceeded, + isApplied: true, + }, + { + name: "should return false if the resource apply failed", + resourceSetBinding: CRSBinding, + resourceRef: resourceRefApplyFailed, + isApplied: false, + }, + { + name: "should return false if the resource does not exist", + resourceSetBinding: CRSBinding, + resourceRef: resourceRefNotExist, + isApplied: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gs := NewWithT(t) + gs.Expect(tt.resourceSetBinding.IsApplied(tt.resourceRef)).To(BeEquivalentTo(tt.isApplied)) + }) + } +} + +func TestSetResourceBinding(t *testing.T) { + resourceRefApplyFailed := ResourceRef{ + Name: "applyFailed", + Kind: "Secret", + } + + CRSBinding := &ResourceSetBinding{ + ClusterResourceSetName: "test-clusterResourceSet", + Resources: []ResourceBinding{ + { + ResourceRef: resourceRefApplyFailed, + Applied: false, + Hash: "", + LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, + }, + }, + } + updateFailedResourceBinding := ResourceBinding{ + ResourceRef: resourceRefApplyFailed, + Applied: true, + Hash: "xyz", + LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, + } + + newResourceBinding := ResourceBinding{ + ResourceRef: ResourceRef{ + Name: "newBinding", + Kind: "Secret", + }, + Applied: false, + Hash: "xyz", + LastAppliedTime: &metav1.Time{Time: time.Now().UTC()}, + } + + tests := []struct { + name string + resourceSetBinding *ResourceSetBinding + resourceBinding ResourceBinding + }{ + { + name: "should update resourceSetBinding with new resource binding if not exist", + resourceSetBinding: CRSBinding, + resourceBinding: newResourceBinding, + }, + { + name: "should update Applied if resource failed before", + resourceSetBinding: CRSBinding, + resourceBinding: updateFailedResourceBinding, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gs := NewWithT(t) + tt.resourceSetBinding.SetBinding(tt.resourceBinding) + exist := false + for _, b := range tt.resourceSetBinding.Resources { + if reflect.DeepEqual(b.ResourceRef, tt.resourceBinding.ResourceRef) { + gs.Expect(tt.resourceBinding.Applied).To(BeEquivalentTo(b.Applied)) + exist = true + } + } + gs.Expect(exist).To(BeTrue()) + }) + } +} diff --git a/internal/apis/core/exp/addons/v1alpha3/condition_consts.go b/internal/apis/core/exp/addons/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..b2dcd63aad65 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/condition_consts.go @@ -0,0 +1,42 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + +// Conditions and condition Reasons for the ClusterResourceSet object. + +const ( + // ResourcesAppliedCondition documents that all resources in the ClusterResourceSet object are applied to + // all matching clusters. This indicates all resources exist, and no errors during applying them to all clusters. + ResourcesAppliedCondition clusterv1alpha3.ConditionType = "ResourcesApplied" + + // RemoteClusterClientFailedReason (Severity=Error) documents failure during getting the remote cluster client. + RemoteClusterClientFailedReason = "RemoteClusterClientFailed" + + // ClusterMatchFailedReason (Severity=Warning) documents failure getting clusters that match the clusterSelector. + ClusterMatchFailedReason = "ClusterMatchFailed" + + // ApplyFailedReason (Severity=Warning) documents applying at least one of the resources to one of the matching clusters is failed. + ApplyFailedReason = "ApplyFailed" + + // RetrievingResourceFailedReason (Severity=Warning) documents at least one of the resources are not successfully retrieved. + RetrievingResourceFailedReason = "RetrievingResourceFailed" + + // WrongSecretTypeReason (Severity=Warning) documents at least one of the Secret's type in the resource list is not supported. + WrongSecretTypeReason = "WrongSecretType" +) diff --git a/internal/apis/core/exp/addons/v1alpha3/conversion.go b/internal/apis/core/exp/addons/v1alpha3/conversion.go new file mode 100644 index 000000000000..e7c38ca772c6 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/conversion.go @@ -0,0 +1,97 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *ClusterResourceSet) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*addonsv1.ClusterResourceSet) + + return Convert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(src, dst, nil) +} + +func (dst *ClusterResourceSet) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*addonsv1.ClusterResourceSet) + + return Convert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(src, dst, nil) +} + +func (src *ClusterResourceSetList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*addonsv1.ClusterResourceSetList) + + return Convert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList(src, dst, nil) +} + +func (dst *ClusterResourceSetList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*addonsv1.ClusterResourceSetList) + + return Convert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList(src, dst, nil) +} + +func (src *ClusterResourceSetBinding) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*addonsv1.ClusterResourceSetBinding) + + if err := Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(src, dst, nil); err != nil { + return err + } + // Manually restore data. + restored := &addonsv1.ClusterResourceSetBinding{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + dst.Spec.ClusterName = restored.Spec.ClusterName + return nil +} + +func (dst *ClusterResourceSetBinding) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*addonsv1.ClusterResourceSetBinding) + + if err := Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *ClusterResourceSetBindingList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*addonsv1.ClusterResourceSetBindingList) + + return Convert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList(src, dst, nil) +} + +func (dst *ClusterResourceSetBindingList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*addonsv1.ClusterResourceSetBindingList) + + return Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(src, dst, nil) +} + +// Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec is a conversion function. +func Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(in *addonsv1.ClusterResourceSetBindingSpec, out *ClusterResourceSetBindingSpec, s apiconversion.Scope) error { + // Spec.ClusterName does not exist in ClusterResourceSetBinding v1alpha3 API. + return autoConvert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(in, out, s) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/conversion_test.go b/internal/apis/core/exp/addons/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..50cf6d755d5b --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/conversion_test.go @@ -0,0 +1,35 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + addonsv1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for ClusterResourceSet", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &addonsv1.ClusterResourceSet{}, + Spoke: &ClusterResourceSet{}, + })) + t.Run("for ClusterResourceSetBinding", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &addonsv1.ClusterResourceSetBinding{}, + Spoke: &ClusterResourceSetBinding{}, + })) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/doc.go b/internal/apis/core/exp/addons/v1alpha3/doc.go new file mode 100644 index 000000000000..c64db3e120dc --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/exp/addons/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/internal/apis/core/exp/addons/v1alpha3/groupversion_info.go b/internal/apis/core/exp/addons/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..a2d338024e2b --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the addons v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=addons.cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "addons.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/internal/apis/core/exp/addons/v1alpha3/suite_test.go b/internal/apis/core/exp/addons/v1alpha3/suite_test.go new file mode 100644 index 000000000000..1bff9a48c8b3 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/suite_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "os" + "testing" + + // +kubebuilder:scaffold:imports + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/cluster-api/internal/test/envtest" +) + +var ( + env *envtest.Environment + ctx = ctrl.SetupSignalHandler() +) + +func TestMain(m *testing.M) { + utilruntime.Must(AddToScheme(scheme.Scheme)) + + os.Exit(envtest.Run(ctx, envtest.RunInput{ + M: m, + SetupEnv: func(e *envtest.Environment) { env = e }, + })) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/zz_generated.conversion.go b/internal/apis/core/exp/addons/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..5af0bae47341 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,441 @@ +//go:build !ignore_autogenerated_core_exp +// +build !ignore_autogenerated_core_exp + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + v1beta1 "sigs.k8s.io/cluster-api/exp/addons/api/v1beta1" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*ClusterResourceSet)(nil), (*v1beta1.ClusterResourceSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(a.(*ClusterResourceSet), b.(*v1beta1.ClusterResourceSet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSet)(nil), (*ClusterResourceSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(a.(*v1beta1.ClusterResourceSet), b.(*ClusterResourceSet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetBinding)(nil), (*v1beta1.ClusterResourceSetBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(a.(*ClusterResourceSetBinding), b.(*v1beta1.ClusterResourceSetBinding), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSetBinding)(nil), (*ClusterResourceSetBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(a.(*v1beta1.ClusterResourceSetBinding), b.(*ClusterResourceSetBinding), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetBindingList)(nil), (*v1beta1.ClusterResourceSetBindingList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList(a.(*ClusterResourceSetBindingList), b.(*v1beta1.ClusterResourceSetBindingList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSetBindingList)(nil), (*ClusterResourceSetBindingList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(a.(*v1beta1.ClusterResourceSetBindingList), b.(*ClusterResourceSetBindingList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetBindingSpec)(nil), (*v1beta1.ClusterResourceSetBindingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec(a.(*ClusterResourceSetBindingSpec), b.(*v1beta1.ClusterResourceSetBindingSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetList)(nil), (*v1beta1.ClusterResourceSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList(a.(*ClusterResourceSetList), b.(*v1beta1.ClusterResourceSetList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSetList)(nil), (*ClusterResourceSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList(a.(*v1beta1.ClusterResourceSetList), b.(*ClusterResourceSetList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetSpec)(nil), (*v1beta1.ClusterResourceSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec(a.(*ClusterResourceSetSpec), b.(*v1beta1.ClusterResourceSetSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSetSpec)(nil), (*ClusterResourceSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec(a.(*v1beta1.ClusterResourceSetSpec), b.(*ClusterResourceSetSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterResourceSetStatus)(nil), (*v1beta1.ClusterResourceSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus(a.(*ClusterResourceSetStatus), b.(*v1beta1.ClusterResourceSetStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterResourceSetStatus)(nil), (*ClusterResourceSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus(a.(*v1beta1.ClusterResourceSetStatus), b.(*ClusterResourceSetStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ResourceBinding)(nil), (*v1beta1.ResourceBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ResourceBinding_To_v1beta1_ResourceBinding(a.(*ResourceBinding), b.(*v1beta1.ResourceBinding), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ResourceBinding)(nil), (*ResourceBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ResourceBinding_To_v1alpha3_ResourceBinding(a.(*v1beta1.ResourceBinding), b.(*ResourceBinding), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ResourceRef)(nil), (*v1beta1.ResourceRef)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef(a.(*ResourceRef), b.(*v1beta1.ResourceRef), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ResourceRef)(nil), (*ResourceRef)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef(a.(*v1beta1.ResourceRef), b.(*ResourceRef), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ResourceSetBinding)(nil), (*v1beta1.ResourceSetBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ResourceSetBinding_To_v1beta1_ResourceSetBinding(a.(*ResourceSetBinding), b.(*v1beta1.ResourceSetBinding), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ResourceSetBinding)(nil), (*ResourceSetBinding)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ResourceSetBinding_To_v1alpha3_ResourceSetBinding(a.(*v1beta1.ResourceSetBinding), b.(*ResourceSetBinding), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.ClusterResourceSetBindingSpec)(nil), (*ClusterResourceSetBindingSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(a.(*v1beta1.ClusterResourceSetBindingSpec), b.(*ClusterResourceSetBindingSpec), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(in *ClusterResourceSet, out *v1beta1.ClusterResourceSet, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(in *ClusterResourceSet, out *v1beta1.ClusterResourceSet, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(in *v1beta1.ClusterResourceSet, out *ClusterResourceSet, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(in *v1beta1.ClusterResourceSet, out *ClusterResourceSet, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(in, out, s) +} + +func autoConvert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(in *ClusterResourceSetBinding, out *v1beta1.ClusterResourceSetBinding, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(in *ClusterResourceSetBinding, out *v1beta1.ClusterResourceSetBinding, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(in *v1beta1.ClusterResourceSetBinding, out *ClusterResourceSetBinding, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(in *v1beta1.ClusterResourceSetBinding, out *ClusterResourceSetBinding, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(in, out, s) +} + +func autoConvert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList(in *ClusterResourceSetBindingList, out *v1beta1.ClusterResourceSetBindingList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.ClusterResourceSetBinding, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_ClusterResourceSetBinding_To_v1beta1_ClusterResourceSetBinding(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList(in *ClusterResourceSetBindingList, out *v1beta1.ClusterResourceSetBindingList, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetBindingList_To_v1beta1_ClusterResourceSetBindingList(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(in *v1beta1.ClusterResourceSetBindingList, out *ClusterResourceSetBindingList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterResourceSetBinding, len(*in)) + for i := range *in { + if err := Convert_v1beta1_ClusterResourceSetBinding_To_v1alpha3_ClusterResourceSetBinding(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(in *v1beta1.ClusterResourceSetBindingList, out *ClusterResourceSetBindingList, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSetBindingList_To_v1alpha3_ClusterResourceSetBindingList(in, out, s) +} + +func autoConvert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec(in *ClusterResourceSetBindingSpec, out *v1beta1.ClusterResourceSetBindingSpec, s conversion.Scope) error { + out.Bindings = *(*[]*v1beta1.ResourceSetBinding)(unsafe.Pointer(&in.Bindings)) + return nil +} + +// Convert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec(in *ClusterResourceSetBindingSpec, out *v1beta1.ClusterResourceSetBindingSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetBindingSpec_To_v1beta1_ClusterResourceSetBindingSpec(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetBindingSpec_To_v1alpha3_ClusterResourceSetBindingSpec(in *v1beta1.ClusterResourceSetBindingSpec, out *ClusterResourceSetBindingSpec, s conversion.Scope) error { + out.Bindings = *(*[]*ResourceSetBinding)(unsafe.Pointer(&in.Bindings)) + // WARNING: in.ClusterName requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList(in *ClusterResourceSetList, out *v1beta1.ClusterResourceSetList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.ClusterResourceSet, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_ClusterResourceSet_To_v1beta1_ClusterResourceSet(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList(in *ClusterResourceSetList, out *v1beta1.ClusterResourceSetList, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetList_To_v1beta1_ClusterResourceSetList(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList(in *v1beta1.ClusterResourceSetList, out *ClusterResourceSetList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterResourceSet, len(*in)) + for i := range *in { + if err := Convert_v1beta1_ClusterResourceSet_To_v1alpha3_ClusterResourceSet(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList(in *v1beta1.ClusterResourceSetList, out *ClusterResourceSetList, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSetList_To_v1alpha3_ClusterResourceSetList(in, out, s) +} + +func autoConvert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec(in *ClusterResourceSetSpec, out *v1beta1.ClusterResourceSetSpec, s conversion.Scope) error { + out.ClusterSelector = in.ClusterSelector + out.Resources = *(*[]v1beta1.ResourceRef)(unsafe.Pointer(&in.Resources)) + out.Strategy = in.Strategy + return nil +} + +// Convert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec(in *ClusterResourceSetSpec, out *v1beta1.ClusterResourceSetSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetSpec_To_v1beta1_ClusterResourceSetSpec(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec(in *v1beta1.ClusterResourceSetSpec, out *ClusterResourceSetSpec, s conversion.Scope) error { + out.ClusterSelector = in.ClusterSelector + out.Resources = *(*[]ResourceRef)(unsafe.Pointer(&in.Resources)) + out.Strategy = in.Strategy + return nil +} + +// Convert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec(in *v1beta1.ClusterResourceSetSpec, out *ClusterResourceSetSpec, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSetSpec_To_v1alpha3_ClusterResourceSetSpec(in, out, s) +} + +func autoConvert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus(in *ClusterResourceSetStatus, out *v1beta1.ClusterResourceSetStatus, s conversion.Scope) error { + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus is an autogenerated conversion function. +func Convert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus(in *ClusterResourceSetStatus, out *v1beta1.ClusterResourceSetStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterResourceSetStatus_To_v1beta1_ClusterResourceSetStatus(in, out, s) +} + +func autoConvert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus(in *v1beta1.ClusterResourceSetStatus, out *ClusterResourceSetStatus, s conversion.Scope) error { + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus is an autogenerated conversion function. +func Convert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus(in *v1beta1.ClusterResourceSetStatus, out *ClusterResourceSetStatus, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterResourceSetStatus_To_v1alpha3_ClusterResourceSetStatus(in, out, s) +} + +func autoConvert_v1alpha3_ResourceBinding_To_v1beta1_ResourceBinding(in *ResourceBinding, out *v1beta1.ResourceBinding, s conversion.Scope) error { + if err := Convert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef(&in.ResourceRef, &out.ResourceRef, s); err != nil { + return err + } + out.Hash = in.Hash + out.LastAppliedTime = (*v1.Time)(unsafe.Pointer(in.LastAppliedTime)) + out.Applied = in.Applied + return nil +} + +// Convert_v1alpha3_ResourceBinding_To_v1beta1_ResourceBinding is an autogenerated conversion function. +func Convert_v1alpha3_ResourceBinding_To_v1beta1_ResourceBinding(in *ResourceBinding, out *v1beta1.ResourceBinding, s conversion.Scope) error { + return autoConvert_v1alpha3_ResourceBinding_To_v1beta1_ResourceBinding(in, out, s) +} + +func autoConvert_v1beta1_ResourceBinding_To_v1alpha3_ResourceBinding(in *v1beta1.ResourceBinding, out *ResourceBinding, s conversion.Scope) error { + if err := Convert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef(&in.ResourceRef, &out.ResourceRef, s); err != nil { + return err + } + out.Hash = in.Hash + out.LastAppliedTime = (*v1.Time)(unsafe.Pointer(in.LastAppliedTime)) + out.Applied = in.Applied + return nil +} + +// Convert_v1beta1_ResourceBinding_To_v1alpha3_ResourceBinding is an autogenerated conversion function. +func Convert_v1beta1_ResourceBinding_To_v1alpha3_ResourceBinding(in *v1beta1.ResourceBinding, out *ResourceBinding, s conversion.Scope) error { + return autoConvert_v1beta1_ResourceBinding_To_v1alpha3_ResourceBinding(in, out, s) +} + +func autoConvert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef(in *ResourceRef, out *v1beta1.ResourceRef, s conversion.Scope) error { + out.Name = in.Name + out.Kind = in.Kind + return nil +} + +// Convert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef is an autogenerated conversion function. +func Convert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef(in *ResourceRef, out *v1beta1.ResourceRef, s conversion.Scope) error { + return autoConvert_v1alpha3_ResourceRef_To_v1beta1_ResourceRef(in, out, s) +} + +func autoConvert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef(in *v1beta1.ResourceRef, out *ResourceRef, s conversion.Scope) error { + out.Name = in.Name + out.Kind = in.Kind + return nil +} + +// Convert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef is an autogenerated conversion function. +func Convert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef(in *v1beta1.ResourceRef, out *ResourceRef, s conversion.Scope) error { + return autoConvert_v1beta1_ResourceRef_To_v1alpha3_ResourceRef(in, out, s) +} + +func autoConvert_v1alpha3_ResourceSetBinding_To_v1beta1_ResourceSetBinding(in *ResourceSetBinding, out *v1beta1.ResourceSetBinding, s conversion.Scope) error { + out.ClusterResourceSetName = in.ClusterResourceSetName + out.Resources = *(*[]v1beta1.ResourceBinding)(unsafe.Pointer(&in.Resources)) + return nil +} + +// Convert_v1alpha3_ResourceSetBinding_To_v1beta1_ResourceSetBinding is an autogenerated conversion function. +func Convert_v1alpha3_ResourceSetBinding_To_v1beta1_ResourceSetBinding(in *ResourceSetBinding, out *v1beta1.ResourceSetBinding, s conversion.Scope) error { + return autoConvert_v1alpha3_ResourceSetBinding_To_v1beta1_ResourceSetBinding(in, out, s) +} + +func autoConvert_v1beta1_ResourceSetBinding_To_v1alpha3_ResourceSetBinding(in *v1beta1.ResourceSetBinding, out *ResourceSetBinding, s conversion.Scope) error { + out.ClusterResourceSetName = in.ClusterResourceSetName + out.Resources = *(*[]ResourceBinding)(unsafe.Pointer(&in.Resources)) + return nil +} + +// Convert_v1beta1_ResourceSetBinding_To_v1alpha3_ResourceSetBinding is an autogenerated conversion function. +func Convert_v1beta1_ResourceSetBinding_To_v1alpha3_ResourceSetBinding(in *v1beta1.ResourceSetBinding, out *ResourceSetBinding, s conversion.Scope) error { + return autoConvert_v1beta1_ResourceSetBinding_To_v1alpha3_ResourceSetBinding(in, out, s) +} diff --git a/internal/apis/core/exp/addons/v1alpha3/zz_generated.deepcopy.go b/internal/apis/core/exp/addons/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..399550914539 --- /dev/null +++ b/internal/apis/core/exp/addons/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,269 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSet) DeepCopyInto(out *ClusterResourceSet) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSet. +func (in *ClusterResourceSet) DeepCopy() *ClusterResourceSet { + if in == nil { + return nil + } + out := new(ClusterResourceSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterResourceSet) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetBinding) DeepCopyInto(out *ClusterResourceSetBinding) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetBinding. +func (in *ClusterResourceSetBinding) DeepCopy() *ClusterResourceSetBinding { + if in == nil { + return nil + } + out := new(ClusterResourceSetBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterResourceSetBinding) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetBindingList) DeepCopyInto(out *ClusterResourceSetBindingList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterResourceSetBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetBindingList. +func (in *ClusterResourceSetBindingList) DeepCopy() *ClusterResourceSetBindingList { + if in == nil { + return nil + } + out := new(ClusterResourceSetBindingList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterResourceSetBindingList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetBindingSpec) DeepCopyInto(out *ClusterResourceSetBindingSpec) { + *out = *in + if in.Bindings != nil { + in, out := &in.Bindings, &out.Bindings + *out = make([]*ResourceSetBinding, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ResourceSetBinding) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetBindingSpec. +func (in *ClusterResourceSetBindingSpec) DeepCopy() *ClusterResourceSetBindingSpec { + if in == nil { + return nil + } + out := new(ClusterResourceSetBindingSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetList) DeepCopyInto(out *ClusterResourceSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterResourceSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetList. +func (in *ClusterResourceSetList) DeepCopy() *ClusterResourceSetList { + if in == nil { + return nil + } + out := new(ClusterResourceSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterResourceSetList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetSpec) DeepCopyInto(out *ClusterResourceSetSpec) { + *out = *in + in.ClusterSelector.DeepCopyInto(&out.ClusterSelector) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]ResourceRef, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetSpec. +func (in *ClusterResourceSetSpec) DeepCopy() *ClusterResourceSetSpec { + if in == nil { + return nil + } + out := new(ClusterResourceSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterResourceSetStatus) DeepCopyInto(out *ClusterResourceSetStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterResourceSetStatus. +func (in *ClusterResourceSetStatus) DeepCopy() *ClusterResourceSetStatus { + if in == nil { + return nil + } + out := new(ClusterResourceSetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceBinding) DeepCopyInto(out *ResourceBinding) { + *out = *in + out.ResourceRef = in.ResourceRef + if in.LastAppliedTime != nil { + in, out := &in.LastAppliedTime, &out.LastAppliedTime + *out = (*in).DeepCopy() + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceBinding. +func (in *ResourceBinding) DeepCopy() *ResourceBinding { + if in == nil { + return nil + } + out := new(ResourceBinding) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceRef) DeepCopyInto(out *ResourceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceRef. +func (in *ResourceRef) DeepCopy() *ResourceRef { + if in == nil { + return nil + } + out := new(ResourceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ResourceSetBinding) DeepCopyInto(out *ResourceSetBinding) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = make([]ResourceBinding, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSetBinding. +func (in *ResourceSetBinding) DeepCopy() *ResourceSetBinding { + if in == nil { + return nil + } + out := new(ResourceSetBinding) + in.DeepCopyInto(out) + return out +} diff --git a/internal/apis/core/exp/v1alpha3/condition_consts.go b/internal/apis/core/exp/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..839771c271b3 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/condition_consts.go @@ -0,0 +1,30 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + +// Conditions and condition Reasons for the MachinePool object. + +const ( + // ReplicasReadyCondition reports an aggregate of current status of the replicas controlled by the MachinePool. + ReplicasReadyCondition clusterv1alpha3.ConditionType = "ReplicasReady" + + // WaitingForReplicasReadyReason (Severity=Info) documents a machinepool waiting for the required replicas + // to be ready. + WaitingForReplicasReadyReason = "WaitingForReplicasReady" +) diff --git a/internal/apis/core/exp/v1alpha3/conversion.go b/internal/apis/core/exp/v1alpha3/conversion.go new file mode 100644 index 000000000000..6978b3668890 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/conversion.go @@ -0,0 +1,98 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apimachineryconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +// Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in *MachinePoolSpec, out *expv1.MachinePoolSpec, s apimachineryconversion.Scope) error { + return autoConvert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in, out, s) +} + +func Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(in *MachinePool, out *expv1.MachinePool, s apimachineryconversion.Scope) error { + if err := autoConvert_v1alpha3_MachinePool_To_v1beta1_MachinePool(in, out, s); err != nil { + return err + } + + // Replace v1alpha3 finalizer to allow old MachinePools to get deleted. + if controllerutil.ContainsFinalizer(out, MachinePoolFinalizer) { + controllerutil.RemoveFinalizer(out, MachinePoolFinalizer) + controllerutil.AddFinalizer(out, expv1.MachinePoolFinalizer) + } + + return nil +} + +func Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(in *expv1.MachinePool, out *MachinePool, s apimachineryconversion.Scope) error { + if err := autoConvert_v1beta1_MachinePool_To_v1alpha3_MachinePool(in, out, s); err != nil { + return err + } + + // Replace v1beta1 finalizer to allow old MachinePools to get deleted. + if controllerutil.ContainsFinalizer(out, expv1.MachinePoolFinalizer) { + controllerutil.RemoveFinalizer(out, expv1.MachinePoolFinalizer) + controllerutil.AddFinalizer(out, MachinePoolFinalizer) + } + + return nil +} + +func (src *MachinePool) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*expv1.MachinePool) + + if err := Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &expv1.MachinePool{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + dst.Spec.Template.Spec.NodeDeletionTimeout = restored.Spec.Template.Spec.NodeDeletionTimeout + dst.Spec.Template.Spec.NodeVolumeDetachTimeout = restored.Spec.Template.Spec.NodeVolumeDetachTimeout + return nil +} + +func (dst *MachinePool) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*expv1.MachinePool) + + if err := Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(src, dst, nil); err != nil { + return err + } + + return utilconversion.MarshalData(src, dst) +} + +func (src *MachinePoolList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*expv1.MachinePoolList) + + return Convert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(src, dst, nil) +} + +func (dst *MachinePoolList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*expv1.MachinePoolList) + + return Convert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(src, dst, nil) +} diff --git a/internal/apis/core/exp/v1alpha3/conversion_test.go b/internal/apis/core/exp/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..6df28a82fba7 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/conversion_test.go @@ -0,0 +1,71 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + fuzz "github.com/google/gofuzz" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + + expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for MachinePool", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &expv1.MachinePool{}, + Spoke: &MachinePool{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{fuzzFuncs}, + })) +} + +func fuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + BootstrapFuzzer, + MachinePoolSpecFuzzer, + ObjectMetaFuzzer, + } +} + +func BootstrapFuzzer(in *clusterv1alpha3.Bootstrap, c fuzz.Continue) { + c.FuzzNoCustom(in) + + // Bootstrap.Data has been removed in v1alpha4, so setting it to nil in order to avoid v1alpha3 --> --> v1alpha3 round trip errors. + in.Data = nil +} + +func ObjectMetaFuzzer(in *clusterv1alpha3.ObjectMeta, c fuzz.Continue) { + c.FuzzNoCustom(in) + + // These fields have been removed in v1beta1 + // data is going to be lost, so we're forcing zero values here. + in.Name = "" + in.GenerateName = "" + in.Namespace = "" + in.OwnerReferences = nil +} + +func MachinePoolSpecFuzzer(in *MachinePoolSpec, c fuzz.Continue) { + c.Fuzz(in) + + // These fields have been removed in v1beta1 + // data is going to be lost, so we're forcing zero values here. + in.Strategy = nil +} diff --git a/internal/apis/core/exp/v1alpha3/doc.go b/internal/apis/core/exp/v1alpha3/doc.go new file mode 100644 index 000000000000..e302fce51a69 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/exp/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/internal/apis/core/exp/v1alpha3/groupversion_info.go b/internal/apis/core/exp/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..74d169021329 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the exp v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/internal/apis/core/exp/v1alpha3/machinepool_types.go b/internal/apis/core/exp/v1alpha3/machinepool_types.go new file mode 100644 index 000000000000..42ad1ac8952d --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/machinepool_types.go @@ -0,0 +1,251 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + capierrors "sigs.k8s.io/cluster-api/errors" + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +const ( + // MachinePoolFinalizer is used to ensure deletion of dependencies (nodes, infra). + MachinePoolFinalizer = "machinepool.exp.cluster.x-k8s.io" +) + +// ANCHOR: MachinePoolSpec + +// MachinePoolSpec defines the desired state of MachinePool. +type MachinePoolSpec struct { + // ClusterName is the name of the Cluster this object belongs to. + // +kubebuilder:validation:MinLength=1 + ClusterName string `json:"clusterName"` + + // Number of desired machines. Defaults to 1. + // This is a pointer to distinguish between explicit zero and not specified. + Replicas *int32 `json:"replicas,omitempty"` + + // Template describes the machines that will be created. + Template clusterv1alpha3.MachineTemplateSpec `json:"template"` + + // The deployment strategy to use to replace existing machine instances with + // new ones. + // +optional + Strategy *clusterv1alpha3.MachineDeploymentStrategy `json:"strategy,omitempty"` + + // Minimum number of seconds for which a newly created machine instances should + // be ready. + // Defaults to 0 (machine instance will be considered available as soon as it + // is ready) + // +optional + MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` + + // ProviderIDList are the identification IDs of machine instances provided by the provider. + // This field must match the provider IDs as seen on the node objects corresponding to a machine pool's machine instances. + // +optional + ProviderIDList []string `json:"providerIDList,omitempty"` + + // FailureDomains is the list of failure domains this MachinePool should be attached to. + FailureDomains []string `json:"failureDomains,omitempty"` +} + +// ANCHOR_END: MachinePoolSpec + +// ANCHOR: MachinePoolStatus + +// MachinePoolStatus defines the observed state of MachinePool. +type MachinePoolStatus struct { + // NodeRefs will point to the corresponding Nodes if it they exist. + // +optional + NodeRefs []corev1.ObjectReference `json:"nodeRefs,omitempty"` + + // Replicas is the most recently observed number of replicas. + // +optional + Replicas int32 `json:"replicas"` + + // The number of ready replicas for this MachinePool. A machine is considered ready when the node has been created and is "Ready". + // +optional + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // The number of available replicas (ready for at least minReadySeconds) for this MachinePool. + // +optional + AvailableReplicas int32 `json:"availableReplicas,omitempty"` + + // Total number of unavailable machine instances targeted by this machine pool. + // This is the total number of machine instances that are still required for + // the machine pool to have 100% available capacity. They may either + // be machine instances that are running but not yet available or machine instances + // that still have not been created. + // +optional + UnavailableReplicas int32 `json:"unavailableReplicas,omitempty"` + + // FailureReason indicates that there is a problem reconciling the state, and + // will be set to a token value suitable for programmatic interpretation. + // +optional + FailureReason *capierrors.MachinePoolStatusFailure `json:"failureReason,omitempty"` + + // FailureMessage indicates that there is a problem reconciling the state, + // and will be set to a descriptive error message. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + // Phase represents the current phase of cluster actuation. + // E.g. Pending, Running, Terminating, Failed etc. + // +optional + Phase string `json:"phase,omitempty"` + + // BootstrapReady is the state of the bootstrap provider. + // +optional + BootstrapReady bool `json:"bootstrapReady"` + + // InfrastructureReady is the state of the infrastructure provider. + // +optional + InfrastructureReady bool `json:"infrastructureReady"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions define the current service state of the MachinePool. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// ANCHOR_END: MachinePoolStatus + +// MachinePoolPhase is a string representation of a MachinePool Phase. +// +// This type is a high-level indicator of the status of the MachinePool as it is provisioned, +// from the API user’s perspective. +// +// The value should not be interpreted by any software components as a reliable indication +// of the actual state of the MachinePool, and controllers should not use the MachinePool Phase field +// value when making decisions about what action to take. +// +// Controllers should always look at the actual state of the MachinePool’s fields to make those decisions. +type MachinePoolPhase string + +const ( + // MachinePoolPhasePending is the first state a MachinePool is assigned by + // Cluster API MachinePool controller after being created. + MachinePoolPhasePending = MachinePoolPhase("Pending") + + // MachinePoolPhaseProvisioning is the state when the + // MachinePool infrastructure is being created or updated. + MachinePoolPhaseProvisioning = MachinePoolPhase("Provisioning") + + // MachinePoolPhaseProvisioned is the state when its + // infrastructure has been created and configured. + MachinePoolPhaseProvisioned = MachinePoolPhase("Provisioned") + + // MachinePoolPhaseRunning is the MachinePool state when its instances + // have become Kubernetes Nodes in the Ready state. + MachinePoolPhaseRunning = MachinePoolPhase("Running") + + // MachinePoolPhaseScalingUp is the MachinePool state when the + // MachinePool infrastructure is scaling up. + MachinePoolPhaseScalingUp = MachinePoolPhase("ScalingUp") + + // MachinePoolPhaseScalingDown is the MachinePool state when the + // MachinePool infrastructure is scaling down. + MachinePoolPhaseScalingDown = MachinePoolPhase("ScalingDown") + + // MachinePoolPhaseDeleting is the MachinePool state when a delete + // request has been sent to the API Server, + // but its infrastructure has not yet been fully deleted. + MachinePoolPhaseDeleting = MachinePoolPhase("Deleting") + + // MachinePoolPhaseFailed is the MachinePool state when the system + // might require user intervention. + MachinePoolPhaseFailed = MachinePoolPhase("Failed") + + // MachinePoolPhaseUnknown is returned if the MachinePool state cannot be determined. + MachinePoolPhaseUnknown = MachinePoolPhase("Unknown") +) + +// SetTypedPhase sets the Phase field to the string representation of MachinePoolPhase. +func (m *MachinePoolStatus) SetTypedPhase(p MachinePoolPhase) { + m.Phase = string(p) +} + +// GetTypedPhase attempts to parse the Phase field and return +// the typed MachinePoolPhase representation as described in `machinepool_phase_types.go`. +func (m *MachinePoolStatus) GetTypedPhase() MachinePoolPhase { + switch phase := MachinePoolPhase(m.Phase); phase { + case + MachinePoolPhasePending, + MachinePoolPhaseProvisioning, + MachinePoolPhaseProvisioned, + MachinePoolPhaseRunning, + MachinePoolPhaseScalingUp, + MachinePoolPhaseScalingDown, + MachinePoolPhaseDeleting, + MachinePoolPhaseFailed: + return phase + default: + return MachinePoolPhaseUnknown + } +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=machinepools,shortName=mp,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas +// +kubebuilder:printcolumn:name="Replicas",type="string",JSONPath=".status.replicas",description="MachinePool replicas count" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="MachinePool status such as Terminating/Pending/Provisioning/Running/Failed etc" +// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.template.spec.version",description="Kubernetes version associated with this MachinePool" +// +k8s:conversion-gen=false + +// MachinePool is the Schema for the machinepools API. +// +// Deprecated: This type will be removed in one of the next releases. +type MachinePool struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec MachinePoolSpec `json:"spec,omitempty"` + Status MachinePoolStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (m *MachinePool) GetConditions() clusterv1alpha3.Conditions { + return m.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (m *MachinePool) SetConditions(conditions clusterv1alpha3.Conditions) { + m.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// MachinePoolList contains a list of MachinePool. +// +// Deprecated: This type will be removed in one of the next releases. +type MachinePoolList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachinePool `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MachinePool{}, &MachinePoolList{}) +} diff --git a/internal/apis/core/exp/v1alpha3/suite_test.go b/internal/apis/core/exp/v1alpha3/suite_test.go new file mode 100644 index 000000000000..1bff9a48c8b3 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/suite_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "os" + "testing" + + // +kubebuilder:scaffold:imports + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/cluster-api/internal/test/envtest" +) + +var ( + env *envtest.Environment + ctx = ctrl.SetupSignalHandler() +) + +func TestMain(m *testing.M) { + utilruntime.Must(AddToScheme(scheme.Scheme)) + + os.Exit(envtest.Run(ctx, envtest.RunInput{ + M: m, + SetupEnv: func(e *envtest.Environment) { env = e }, + })) +} diff --git a/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go b/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..d4609e258090 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,240 @@ +//go:build !ignore_autogenerated_core_exp +// +build !ignore_autogenerated_core_exp + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + v1 "k8s.io/api/core/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + errors "sigs.k8s.io/cluster-api/errors" + v1beta1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*MachinePoolList)(nil), (*v1beta1.MachinePoolList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(a.(*MachinePoolList), b.(*v1beta1.MachinePoolList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachinePoolList)(nil), (*MachinePoolList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(a.(*v1beta1.MachinePoolList), b.(*MachinePoolList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachinePoolSpec)(nil), (*MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(a.(*v1beta1.MachinePoolSpec), b.(*MachinePoolSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachinePoolStatus)(nil), (*v1beta1.MachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus(a.(*MachinePoolStatus), b.(*v1beta1.MachinePoolStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachinePoolStatus)(nil), (*MachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus(a.(*v1beta1.MachinePoolStatus), b.(*MachinePoolStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*MachinePoolSpec)(nil), (*v1beta1.MachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(a.(*MachinePoolSpec), b.(*v1beta1.MachinePoolSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*MachinePool)(nil), (*v1beta1.MachinePool)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(a.(*MachinePool), b.(*v1beta1.MachinePool), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachinePool)(nil), (*MachinePool)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(a.(*v1beta1.MachinePool), b.(*MachinePool), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_MachinePool_To_v1beta1_MachinePool(in *MachinePool, out *v1beta1.MachinePool, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1beta1_MachinePool_To_v1alpha3_MachinePool(in *v1beta1.MachinePool, out *MachinePool, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(in *MachinePoolList, out *v1beta1.MachinePoolList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.MachinePool, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_MachinePool_To_v1beta1_MachinePool(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList is an autogenerated conversion function. +func Convert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(in *MachinePoolList, out *v1beta1.MachinePoolList, s conversion.Scope) error { + return autoConvert_v1alpha3_MachinePoolList_To_v1beta1_MachinePoolList(in, out, s) +} + +func autoConvert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(in *v1beta1.MachinePoolList, out *MachinePoolList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachinePool, len(*in)) + for i := range *in { + if err := Convert_v1beta1_MachinePool_To_v1alpha3_MachinePool(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList is an autogenerated conversion function. +func Convert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(in *v1beta1.MachinePoolList, out *MachinePoolList, s conversion.Scope) error { + return autoConvert_v1beta1_MachinePoolList_To_v1alpha3_MachinePoolList(in, out, s) +} + +func autoConvert_v1alpha3_MachinePoolSpec_To_v1beta1_MachinePoolSpec(in *MachinePoolSpec, out *v1beta1.MachinePoolSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + if err := corev1alpha3.Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + // WARNING: in.Strategy requires manual conversion: does not exist in peer-type + out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) + out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) + return nil +} + +func autoConvert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(in *v1beta1.MachinePoolSpec, out *MachinePoolSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + if err := corev1alpha3.Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) + out.FailureDomains = *(*[]string)(unsafe.Pointer(&in.FailureDomains)) + return nil +} + +// Convert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec is an autogenerated conversion function. +func Convert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(in *v1beta1.MachinePoolSpec, out *MachinePoolSpec, s conversion.Scope) error { + return autoConvert_v1beta1_MachinePoolSpec_To_v1alpha3_MachinePoolSpec(in, out, s) +} + +func autoConvert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus(in *MachinePoolStatus, out *v1beta1.MachinePoolStatus, s conversion.Scope) error { + out.NodeRefs = *(*[]v1.ObjectReference)(unsafe.Pointer(&in.NodeRefs)) + out.Replicas = in.Replicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.FailureReason = (*errors.MachinePoolStatusFailure)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Phase = in.Phase + out.BootstrapReady = in.BootstrapReady + out.InfrastructureReady = in.InfrastructureReady + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus is an autogenerated conversion function. +func Convert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus(in *MachinePoolStatus, out *v1beta1.MachinePoolStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_MachinePoolStatus_To_v1beta1_MachinePoolStatus(in, out, s) +} + +func autoConvert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus(in *v1beta1.MachinePoolStatus, out *MachinePoolStatus, s conversion.Scope) error { + out.NodeRefs = *(*[]v1.ObjectReference)(unsafe.Pointer(&in.NodeRefs)) + out.Replicas = in.Replicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.FailureReason = (*errors.MachinePoolStatusFailure)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Phase = in.Phase + out.BootstrapReady = in.BootstrapReady + out.InfrastructureReady = in.InfrastructureReady + out.ObservedGeneration = in.ObservedGeneration + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus is an autogenerated conversion function. +func Convert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus(in *v1beta1.MachinePoolStatus, out *MachinePoolStatus, s conversion.Scope) error { + return autoConvert_v1beta1_MachinePoolStatus_To_v1alpha3_MachinePoolStatus(in, out, s) +} diff --git a/internal/apis/core/exp/v1alpha3/zz_generated.deepcopy.go b/internal/apis/core/exp/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..bbcfc6d76752 --- /dev/null +++ b/internal/apis/core/exp/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,165 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + "sigs.k8s.io/cluster-api/errors" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePool) DeepCopyInto(out *MachinePool) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePool. +func (in *MachinePool) DeepCopy() *MachinePool { + if in == nil { + return nil + } + out := new(MachinePool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachinePool) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolList) DeepCopyInto(out *MachinePoolList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachinePool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolList. +func (in *MachinePoolList) DeepCopy() *MachinePoolList { + if in == nil { + return nil + } + out := new(MachinePoolList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachinePoolList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolSpec) DeepCopyInto(out *MachinePoolSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Template.DeepCopyInto(&out.Template) + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(apiv1alpha3.MachineDeploymentStrategy) + (*in).DeepCopyInto(*out) + } + if in.MinReadySeconds != nil { + in, out := &in.MinReadySeconds, &out.MinReadySeconds + *out = new(int32) + **out = **in + } + if in.ProviderIDList != nil { + in, out := &in.ProviderIDList, &out.ProviderIDList + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolSpec. +func (in *MachinePoolSpec) DeepCopy() *MachinePoolSpec { + if in == nil { + return nil + } + out := new(MachinePoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachinePoolStatus) DeepCopyInto(out *MachinePoolStatus) { + *out = *in + if in.NodeRefs != nil { + in, out := &in.NodeRefs, &out.NodeRefs + *out = make([]v1.ObjectReference, len(*in)) + copy(*out, *in) + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachinePoolStatusFailure) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachinePoolStatus. +func (in *MachinePoolStatus) DeepCopy() *MachinePoolStatus { + if in == nil { + return nil + } + out := new(MachinePoolStatus) + in.DeepCopyInto(out) + return out +} diff --git a/internal/apis/core/v1alpha3/cluster_phase_types.go b/internal/apis/core/v1alpha3/cluster_phase_types.go new file mode 100644 index 000000000000..d79a4b1a1e5b --- /dev/null +++ b/internal/apis/core/v1alpha3/cluster_phase_types.go @@ -0,0 +1,55 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +// ClusterPhase is a string representation of a Cluster Phase. +// +// This type is a high-level indicator of the status of the Cluster as it is provisioned, +// from the API user’s perspective. +// +// The value should not be interpreted by any software components as a reliable indication +// of the actual state of the Cluster, and controllers should not use the Cluster Phase field +// value when making decisions about what action to take. +// +// Controllers should always look at the actual state of the Cluster’s fields to make those decisions. +type ClusterPhase string + +const ( + // ClusterPhasePending is the first state a Cluster is assigned by + // Cluster API Cluster controller after being created. + ClusterPhasePending = ClusterPhase("Pending") + + // ClusterPhaseProvisioning is the state when the Cluster has a provider infrastructure + // object associated and can start provisioning. + ClusterPhaseProvisioning = ClusterPhase("Provisioning") + + // ClusterPhaseProvisioned is the state when its + // infrastructure has been created and configured. + ClusterPhaseProvisioned = ClusterPhase("Provisioned") + + // ClusterPhaseDeleting is the Cluster state when a delete + // request has been sent to the API Server, + // but its infrastructure has not yet been fully deleted. + ClusterPhaseDeleting = ClusterPhase("Deleting") + + // ClusterPhaseFailed is the Cluster state when the system + // might require user intervention. + ClusterPhaseFailed = ClusterPhase("Failed") + + // ClusterPhaseUnknown is returned if the Cluster state cannot be determined. + ClusterPhaseUnknown = ClusterPhase("Unknown") +) diff --git a/internal/apis/core/v1alpha3/cluster_types.go b/internal/apis/core/v1alpha3/cluster_types.go new file mode 100644 index 000000000000..2421a2796242 --- /dev/null +++ b/internal/apis/core/v1alpha3/cluster_types.go @@ -0,0 +1,275 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "fmt" + "net" + "strings" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" + + capierrors "sigs.k8s.io/cluster-api/errors" +) + +const ( + // ClusterFinalizer is the finalizer used by the cluster controller to + // cleanup the cluster resources when a Cluster is being deleted. + ClusterFinalizer = "cluster.cluster.x-k8s.io" +) + +// ANCHOR: ClusterSpec + +// ClusterSpec defines the desired state of Cluster. +type ClusterSpec struct { + // Paused can be used to prevent controllers from processing the Cluster and all its associated objects. + // +optional + Paused bool `json:"paused,omitempty"` + + // Cluster network configuration. + // +optional + ClusterNetwork *ClusterNetwork `json:"clusterNetwork,omitempty"` + + // ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + // +optional + ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"` + + // ControlPlaneRef is an optional reference to a provider-specific resource that holds + // the details for provisioning the Control Plane for a Cluster. + // +optional + ControlPlaneRef *corev1.ObjectReference `json:"controlPlaneRef,omitempty"` + + // InfrastructureRef is a reference to a provider-specific resource that holds the details + // for provisioning infrastructure for a cluster in said provider. + // +optional + InfrastructureRef *corev1.ObjectReference `json:"infrastructureRef,omitempty"` +} + +// ANCHOR_END: ClusterSpec + +// ANCHOR: ClusterNetwork + +// ClusterNetwork specifies the different networking +// parameters for a cluster. +type ClusterNetwork struct { + // APIServerPort specifies the port the API Server should bind to. + // Defaults to 6443. + // +optional + APIServerPort *int32 `json:"apiServerPort,omitempty"` + + // The network ranges from which service VIPs are allocated. + // +optional + Services *NetworkRanges `json:"services,omitempty"` + + // The network ranges from which Pod networks are allocated. + // +optional + Pods *NetworkRanges `json:"pods,omitempty"` + + // Domain name for services. + // +optional + ServiceDomain string `json:"serviceDomain,omitempty"` +} + +// ANCHOR_END: ClusterNetwork + +// ANCHOR: NetworkRanges + +// NetworkRanges represents ranges of network addresses. +type NetworkRanges struct { + CIDRBlocks []string `json:"cidrBlocks"` +} + +func (n *NetworkRanges) String() string { + if n == nil { + return "" + } + return strings.Join(n.CIDRBlocks, ",") +} + +// ANCHOR_END: NetworkRanges + +// ANCHOR: ClusterStatus + +// ClusterStatus defines the observed state of Cluster. +type ClusterStatus struct { + // FailureDomains is a slice of failure domain objects synced from the infrastructure provider. + FailureDomains FailureDomains `json:"failureDomains,omitempty"` + + // FailureReason indicates that there is a fatal problem reconciling the + // state, and will be set to a token value suitable for + // programmatic interpretation. + // +optional + FailureReason *capierrors.ClusterStatusError `json:"failureReason,omitempty"` + + // FailureMessage indicates that there is a fatal problem reconciling the + // state, and will be set to a descriptive error message. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + // Phase represents the current phase of cluster actuation. + // E.g. Pending, Running, Terminating, Failed etc. + // +optional + Phase string `json:"phase,omitempty"` + + // InfrastructureReady is the state of the infrastructure provider. + // +optional + InfrastructureReady bool `json:"infrastructureReady"` + + // ControlPlaneInitialized defines if the control plane has been initialized. + // +optional + ControlPlaneInitialized bool `json:"controlPlaneInitialized"` + + // ControlPlaneReady defines if the control plane is ready. + // +optional + ControlPlaneReady bool `json:"controlPlaneReady,omitempty"` + + // Conditions defines current service state of the cluster. + // +optional + Conditions Conditions `json:"conditions,omitempty"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` +} + +// ANCHOR_END: ClusterStatus + +// SetTypedPhase sets the Phase field to the string representation of ClusterPhase. +func (c *ClusterStatus) SetTypedPhase(p ClusterPhase) { + c.Phase = string(p) +} + +// GetTypedPhase attempts to parse the Phase field and return +// the typed ClusterPhase representation as described in `machine_phase_types.go`. +func (c *ClusterStatus) GetTypedPhase() ClusterPhase { + switch phase := ClusterPhase(c.Phase); phase { + case + ClusterPhasePending, + ClusterPhaseProvisioning, + ClusterPhaseProvisioned, + ClusterPhaseDeleting, + ClusterPhaseFailed: + return phase + default: + return ClusterPhaseUnknown + } +} + +// ANCHOR: APIEndpoint + +// APIEndpoint represents a reachable Kubernetes API endpoint. +type APIEndpoint struct { + // The hostname on which the API server is serving. + Host string `json:"host"` + + // The port on which the API server is serving. + Port int32 `json:"port"` +} + +// IsZero returns true if both host and port are zero values. +func (v APIEndpoint) IsZero() bool { + return v.Host == "" && v.Port == 0 +} + +// IsValid returns true if both host and port are non-zero values. +func (v APIEndpoint) IsValid() bool { + return v.Host != "" && v.Port != 0 +} + +// String returns a formatted version HOST:PORT of this APIEndpoint. +func (v APIEndpoint) String() string { + return net.JoinHostPort(v.Host, fmt.Sprintf("%d", v.Port)) +} + +// ANCHOR_END: APIEndpoint + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=clusters,shortName=cl,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Cluster status such as Pending/Provisioning/Provisioned/Deleting/Failed" + +// Cluster is the Schema for the clusters API. +type Cluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterSpec `json:"spec,omitempty"` + Status ClusterStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (c *Cluster) GetConditions() Conditions { + return c.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (c *Cluster) SetConditions(conditions Conditions) { + c.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// ClusterList contains a list of Cluster. +type ClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Cluster `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Cluster{}, &ClusterList{}) +} + +// FailureDomains is a slice of FailureDomains. +type FailureDomains map[string]FailureDomainSpec + +// FilterControlPlane returns a FailureDomain slice containing only the domains suitable to be used +// for control plane nodes. +func (in FailureDomains) FilterControlPlane() FailureDomains { + res := make(FailureDomains) + for id, spec := range in { + if spec.ControlPlane { + res[id] = spec + } + } + return res +} + +// GetIDs returns a slice containing the ids for failure domains. +func (in FailureDomains) GetIDs() []*string { + ids := make([]*string, 0, len(in)) + for id := range in { + ids = append(ids, pointer.String(id)) + } + return ids +} + +// FailureDomainSpec is the Schema for Cluster API failure domains. +// It allows controllers to understand how many failure domains a cluster can optionally span across. +type FailureDomainSpec struct { + // ControlPlane determines if this failure domain is suitable for use by control plane machines. + // +optional + ControlPlane bool `json:"controlPlane"` + + // Attributes is a free form map of attributes an infrastructure provider might use or require. + // +optional + Attributes map[string]string `json:"attributes,omitempty"` +} diff --git a/internal/apis/core/v1alpha3/common_types.go b/internal/apis/core/v1alpha3/common_types.go new file mode 100644 index 000000000000..58ef4a74e2cf --- /dev/null +++ b/internal/apis/core/v1alpha3/common_types.go @@ -0,0 +1,194 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + // ClusterLabelName is the label set on machines linked to a cluster and + // external objects(bootstrap and infrastructure providers). + ClusterLabelName = "cluster.x-k8s.io/cluster-name" + + // ProviderLabelName is the label set on components in the provider manifest. + // This label allows to easily identify all the components belonging to a provider; the clusterctl + // tool uses this label for implementing provider's lifecycle operations. + ProviderLabelName = "cluster.x-k8s.io/provider" + + // ClusterNameAnnotation is the annotation set on nodes identifying the name of the cluster the node belongs to. + ClusterNameAnnotation = "cluster.x-k8s.io/cluster-name" + + // ClusterNamespaceAnnotation is the annotation set on nodes identifying the namespace of the cluster the node belongs to. + ClusterNamespaceAnnotation = "cluster.x-k8s.io/cluster-namespace" + + // MachineAnnotation is the annotation set on nodes identifying the machine the node belongs to. + MachineAnnotation = "cluster.x-k8s.io/machine" + + // OwnerKindAnnotation is the annotation set on nodes identifying the owner kind. + OwnerKindAnnotation = "cluster.x-k8s.io/owner-kind" + + // OwnerNameAnnotation is the annotation set on nodes identifying the owner name. + OwnerNameAnnotation = "cluster.x-k8s.io/owner-name" + + // PausedAnnotation is an annotation that can be applied to any Cluster API + // object to prevent a controller from processing a resource. + // + // Controllers working with Cluster API objects must check the existence of this annotation + // on the reconciled object. + PausedAnnotation = "cluster.x-k8s.io/paused" + + // DeleteMachineAnnotation marks control plane and worker nodes that will be given priority for deletion + // when KCP or a machineset scales down. This annotation is given top priority on all delete policies. + DeleteMachineAnnotation = "cluster.x-k8s.io/delete-machine" + + // TemplateClonedFromNameAnnotation is the infrastructure machine annotation that stores the name of the infrastructure template resource + // that was cloned for the machine. This annotation is set only during cloning a template. Older/adopted machines will not have this annotation. + TemplateClonedFromNameAnnotation = "cluster.x-k8s.io/cloned-from-name" + + // TemplateClonedFromGroupKindAnnotation is the infrastructure machine annotation that stores the group-kind of the infrastructure template resource + // that was cloned for the machine. This annotation is set only during cloning a template. Older/adopted machines will not have this annotation. + TemplateClonedFromGroupKindAnnotation = "cluster.x-k8s.io/cloned-from-groupkind" + + // MachineSkipRemediationAnnotation is the annotation used to mark the machines that should not be considered for remediation by MachineHealthCheck reconciler. + MachineSkipRemediationAnnotation = "cluster.x-k8s.io/skip-remediation" + + // ClusterSecretType defines the type of secret created by core components. + ClusterSecretType corev1.SecretType = "cluster.x-k8s.io/secret" //nolint:gosec +) + +// MachineAddressType describes a valid MachineAddress type. +type MachineAddressType string + +// Define all the constants related to MachineAddressType. +const ( + MachineHostName MachineAddressType = "Hostname" + MachineExternalIP MachineAddressType = "ExternalIP" + MachineInternalIP MachineAddressType = "InternalIP" + MachineExternalDNS MachineAddressType = "ExternalDNS" + MachineInternalDNS MachineAddressType = "InternalDNS" +) + +const ( + // MachineNodeNameIndex is used by the Machine Controller to index Machines by Node name, and add a watch on Nodes. + MachineNodeNameIndex = "status.nodeRef.name" +) + +// MachineAddress contains information for the node's address. +type MachineAddress struct { + // Machine address type, one of Hostname, ExternalIP or InternalIP. + Type MachineAddressType `json:"type"` + + // The machine address. + Address string `json:"address"` +} + +// MachineAddresses is a slice of MachineAddress items to be used by infrastructure providers. +type MachineAddresses []MachineAddress + +// ObjectMeta is metadata that all persisted resources must have, which includes all objects +// users must create. This is a copy of customizable fields from metav1.ObjectMeta. +// +// ObjectMeta is embedded in `Machine.Spec`, `MachineDeployment.Template` and `MachineSet.Template`, +// which are not top-level Kubernetes objects. Given that metav1.ObjectMeta has lots of special cases +// and read-only fields which end up in the generated CRD validation, having it as a subset simplifies +// the API and some issues that can impact user experience. +// +// During the [upgrade to controller-tools@v2](https://github.com/kubernetes-sigs/cluster-api/pull/1054) +// for v1alpha2, we noticed a failure would occur running Cluster API test suite against the new CRDs, +// specifically `spec.metadata.creationTimestamp in body must be of type string: "null"`. +// The investigation showed that `controller-tools@v2` behaves differently than its previous version +// when handling types from [metav1](k8s.io/apimachinery/pkg/apis/meta/v1) package. +// +// In more details, we found that embedded (non-top level) types that embedded `metav1.ObjectMeta` +// had validation properties, including for `creationTimestamp` (metav1.Time). +// The `metav1.Time` type specifies a custom json marshaller that, when IsZero() is true, returns `null` +// which breaks validation because the field isn't marked as nullable. +// +// In future versions, controller-tools@v2 might allow overriding the type and validation for embedded +// types. When that happens, this hack should be revisited. +type ObjectMeta struct { + // Name must be unique within a namespace. Is required when creating resources, although + // some resources may allow a client to request the generation of an appropriate name + // automatically. Name is primarily intended for creation idempotence and configuration + // definition. + // Cannot be updated. + // More info: http://kubernetes.io/docs/user-guide/identifiers#names + // +optional + // + // Deprecated: This field has no function and is going to be removed in a next release. + Name string `json:"name,omitempty"` + + // GenerateName is an optional prefix, used by the server, to generate a unique + // name ONLY IF the Name field has not been provided. + // If this field is used, the name returned to the client will be different + // than the name passed. This value will also be combined with a unique suffix. + // The provided value has the same validation rules as the Name field, + // and may be truncated by the length of the suffix required to make the value + // unique on the server. + // + // If this field is specified and the generated name exists, the server will + // NOT return a 409 - instead, it will either return 201 Created or 500 with Reason + // ServerTimeout indicating a unique name could not be found in the time allotted, and the client + // should retry (optionally after the time indicated in the Retry-After header). + // + // Applied only if Name is not specified. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency + // +optional + // + // Deprecated: This field has no function and is going to be removed in a next release. + GenerateName string `json:"generateName,omitempty"` + + // Namespace defines the space within each name must be unique. An empty namespace is + // equivalent to the "default" namespace, but "default" is the canonical representation. + // Not all objects are required to be scoped to a namespace - the value of this field for + // those objects will be empty. + // + // Must be a DNS_LABEL. + // Cannot be updated. + // More info: http://kubernetes.io/docs/user-guide/namespaces + // +optional + // + // Deprecated: This field has no function and is going to be removed in a next release. + Namespace string `json:"namespace,omitempty"` + + // Map of string keys and values that can be used to organize and categorize + // (scope and select) objects. May match selectors of replication controllers + // and services. + // More info: http://kubernetes.io/docs/user-guide/labels + // +optional + Labels map[string]string `json:"labels,omitempty"` + + // Annotations is an unstructured key value map stored with a resource that may be + // set by external tools to store and retrieve arbitrary metadata. They are not + // queryable and should be preserved when modifying objects. + // More info: http://kubernetes.io/docs/user-guide/annotations + // +optional + Annotations map[string]string `json:"annotations,omitempty"` + + // List of objects depended by this object. If ALL objects in the list have + // been deleted, this object will be garbage collected. If this object is managed by a controller, + // then an entry in this list will point to this controller, with the controller field set to true. + // There cannot be more than one managing controller. + // +optional + // +patchMergeKey=uid + // +patchStrategy=merge + // + // Deprecated: This field has no function and is going to be removed in a next release. + OwnerReferences []metav1.OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid"` +} diff --git a/internal/apis/core/v1alpha3/condition_consts.go b/internal/apis/core/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..3c0b6195e510 --- /dev/null +++ b/internal/apis/core/v1alpha3/condition_consts.go @@ -0,0 +1,186 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +// ANCHOR: CommonConditions + +// Common ConditionTypes used by Cluster API objects. +const ( + // ReadyCondition defines the Ready condition type that summarizes the operational state of a Cluster API object. + ReadyCondition ConditionType = "Ready" +) + +// Common ConditionReason used by Cluster API objects. +const ( + // DeletingReason (Severity=Info) documents an condition not in Status=True because the underlying object it is currently being deleted. + DeletingReason = "Deleting" + + // DeletionFailedReason (Severity=Warning) documents an condition not in Status=True because the underlying object + // encountered problems during deletion. This is a warning because the reconciler will retry deletion. + DeletionFailedReason = "DeletionFailed" + + // DeletedReason (Severity=Info) documents an condition not in Status=True because the underlying object was deleted. + DeletedReason = "Deleted" +) + +const ( + // InfrastructureReadyCondition reports a summary of current status of the infrastructure object defined for this cluster/machine/machinepool. + // This condition is mirrored from the Ready condition in the infrastructure ref object, and + // the absence of this condition might signal problems in the reconcile external loops or the fact that + // the infrastructure provider does not implement the Ready condition yet. + InfrastructureReadyCondition ConditionType = "InfrastructureReady" + + // WaitingForInfrastructureFallbackReason (Severity=Info) documents a cluster/machine/machinepool waiting for the underlying infrastructure + // to be available. + // NOTE: This reason is used only as a fallback when the infrastructure object is not reporting its own ready condition. + WaitingForInfrastructureFallbackReason = "WaitingForInfrastructure" +) + +// ANCHOR_END: CommonConditions + +// Conditions and condition Reasons for the Cluster object. + +const ( + // ControlPlaneReadyCondition reports the ready condition from the control plane object defined for this cluster. + // This condition is mirrored from the Ready condition in the control plane ref object, and + // the absence of this condition might signal problems in the reconcile external loops or the fact that + // the control plane provider does not implement the Ready condition yet. + ControlPlaneReadyCondition ConditionType = "ControlPlaneReady" + + // WaitingForControlPlaneFallbackReason (Severity=Info) documents a cluster waiting for the control plane + // to be available. + // NOTE: This reason is used only as a fallback when the control plane object is not reporting its own ready condition. + WaitingForControlPlaneFallbackReason = "WaitingForControlPlane" + + // WaitingForControlPlaneAvailableReason (Severity=Info) documents a Cluster API object + // waiting for the control plane machine to be available. + // + // NOTE: Having the control plane machine available is a pre-condition for joining additional control planes + // or workers nodes. + WaitingForControlPlaneAvailableReason = "WaitingForControlPlaneAvailable" +) + +// Conditions and condition Reasons for the Machine object. + +const ( + // BootstrapReadyCondition reports a summary of current status of the bootstrap object defined for this machine. + // This condition is mirrored from the Ready condition in the bootstrap ref object, and + // the absence of this condition might signal problems in the reconcile external loops or the fact that + // the bootstrap provider does not implement the Ready condition yet. + BootstrapReadyCondition ConditionType = "BootstrapReady" + + // WaitingForDataSecretFallbackReason (Severity=Info) documents a machine waiting for the bootstrap data secret + // to be available. + // NOTE: This reason is used only as a fallback when the bootstrap object is not reporting its own ready condition. + WaitingForDataSecretFallbackReason = "WaitingForDataSecret" + + // DrainingSucceededCondition provide evidence of the status of the node drain operation which happens during the machine + // deletion process. + DrainingSucceededCondition ConditionType = "DrainingSucceeded" + + // DrainingReason (Severity=Info) documents a machine node being drained. + DrainingReason = "Draining" + + // DrainingFailedReason (Severity=Warning) documents a machine node drain operation failed. + DrainingFailedReason = "DrainingFailed" + + // PreDrainDeleteHookSucceededCondition reports a machine waiting for a PreDrainDeleteHook before being delete. + PreDrainDeleteHookSucceededCondition ConditionType = "PreDrainDeleteHookSucceeded" + + // PreTerminateDeleteHookSucceededCondition reports a machine waiting for a PreDrainDeleteHook before being delete. + PreTerminateDeleteHookSucceededCondition ConditionType = "PreTerminateDeleteHookSucceeded" + + // WaitingExternalHookReason (Severity=Info) provide evidence that we are waiting for an external hook to complete. + WaitingExternalHookReason = "WaitingExternalHook" +) + +const ( + // MachineHealthCheckSuccededCondition is set on machines that have passed a healthcheck by the MachineHealthCheck controller. + // In the event that the health check fails it will be set to False. + MachineHealthCheckSuccededCondition ConditionType = "HealthCheckSucceeded" + + // MachineHasFailureReason is the reason used when a machine has either a FailureReason or a FailureMessage set on its status. + MachineHasFailureReason = "MachineHasFailure" + + // NodeStartupTimeoutReason is the reason used when a machine's node does not appear within the specified timeout. + NodeStartupTimeoutReason = "NodeStartupTimeout" + + // UnhealthyNodeConditionReason is the reason used when a machine's node has one of the MachineHealthCheck's unhealthy conditions. + UnhealthyNodeConditionReason = "UnhealthyNode" +) + +const ( + // MachineOwnerRemediatedCondition is set on machines that have failed a healthcheck by the MachineHealthCheck controller. + // MachineOwnerRemediatedCondition is set to False after a health check fails, but should be changed to True by the owning controller after remediation succeeds. + MachineOwnerRemediatedCondition ConditionType = "OwnerRemediated" + + // WaitingForRemediationReason is the reason used when a machine fails a health check and remediation is needed. + WaitingForRemediationReason = "WaitingForRemediation" + + // RemediationFailedReason is the reason used when a remediation owner fails to remediate an unhealthy machine. + RemediationFailedReason = "RemediationFailed" + + // RemediationInProgressReason is the reason used when an unhealthy machine is being remediated by the remediation owner. + RemediationInProgressReason = "RemediationInProgress" + + // ExternalRemediationTemplateAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation. + // ExternalRemediationTemplateAvailable is set to false if external remediation template is not found. + ExternalRemediationTemplateAvailable ConditionType = "ExternalRemediationTemplateAvailable" + + // ExternalRemediationTemplateNotFound is the reason used when a machine health check fails to find external remediation template. + ExternalRemediationTemplateNotFound = "ExternalRemediationTemplateNotFound" + + // ExternalRemediationRequestAvailable is set on machinehealthchecks when MachineHealthCheck controller uses external remediation. + // ExternalRemediationRequestAvailable is set to false if creating external remediation request fails. + ExternalRemediationRequestAvailable ConditionType = "ExternalRemediationRequestAvailable" + + // ExternalRemediationRequestCreationFailed is the reason used when a machine health check fails to create external remediation request. + ExternalRemediationRequestCreationFailed = "ExternalRemediationRequestCreationFailed" +) + +// Conditions and condition Reasons for the Machine's Node object. +const ( + // MachineNodeHealthyCondition provides info about the operational state of the Kubernetes node hosted on the machine by summarizing node conditions. + // If the conditions defined in a Kubernetes node (i.e., NodeReady, NodeMemoryPressure, NodeDiskPressure, NodePIDPressure, and NodeNetworkUnavailable) are in a healthy state, it will be set to True. + MachineNodeHealthyCondition ConditionType = "NodeHealthy" + + // WaitingForNodeRefReason (Severity=Info) documents a machine.spec.providerId is not assigned yet. + WaitingForNodeRefReason = "WaitingForNodeRef" + + // NodeProvisioningReason (Severity=Info) documents machine in the process of provisioning a node. + // NB. provisioning --> NodeRef == "". + NodeProvisioningReason = "NodeProvisioning" + + // NodeNotFoundReason (Severity=Error) documents a machine's node has previously been observed but is now gone. + // NB. provisioned --> NodeRef != "". + NodeNotFoundReason = "NodeNotFound" + + // NodeConditionsFailedReason (Severity=Warning) documents a node is not in a healthy state due to the failed state of at least 1 Kubelet condition. + NodeConditionsFailedReason = "NodeConditionsFailed" +) + +// Conditions and condition Reasons for the MachineHealthCheck object. + +const ( + // RemediationAllowedCondition is set on MachineHealthChecks to show the status of whether the MachineHealthCheck is + // allowed to remediate any Machines or whether it is blocked from remediating any further. + RemediationAllowedCondition ConditionType = "RemediationAllowed" + + // TooManyUnhealthyReason is the reason used when too many Machines are unhealthy and the MachineHealthCheck is blocked + // from making any further remediations. + TooManyUnhealthyReason = "TooManyUnhealthy" +) diff --git a/internal/apis/core/v1alpha3/condition_types.go b/internal/apis/core/v1alpha3/condition_types.go new file mode 100644 index 000000000000..51a67f6edff8 --- /dev/null +++ b/internal/apis/core/v1alpha3/condition_types.go @@ -0,0 +1,97 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ANCHOR: ConditionSeverity + +// ConditionSeverity expresses the severity of a Condition Type failing. +type ConditionSeverity string + +const ( + // ConditionSeverityError specifies that a condition with `Status=False` is an error. + ConditionSeverityError ConditionSeverity = "Error" + + // ConditionSeverityWarning specifies that a condition with `Status=False` is a warning. + ConditionSeverityWarning ConditionSeverity = "Warning" + + // ConditionSeverityInfo specifies that a condition with `Status=False` is informative. + ConditionSeverityInfo ConditionSeverity = "Info" + + // ConditionSeverityNone should apply only to conditions with `Status=True`. + ConditionSeverityNone ConditionSeverity = "" +) + +// ANCHOR_END: ConditionSeverity + +// ANCHOR: ConditionType + +// ConditionType is a valid value for Condition.Type. +type ConditionType string + +// ANCHOR_END: ConditionType + +// ANCHOR: Condition + +// Condition defines an observation of a Cluster API resource operational state. +type Condition struct { + // Type of condition in CamelCase or in foo.example.com/CamelCase. + // Many .condition.type values are consistent across resources like Available, but because arbitrary conditions + // can be useful (see .node.status.conditions), the ability to deconflict is important. + // +required + Type ConditionType `json:"type"` + + // Status of the condition, one of True, False, Unknown. + // +required + Status corev1.ConditionStatus `json:"status"` + + // Severity provides an explicit classification of Reason code, so the users or machines can immediately + // understand the current situation and act accordingly. + // The Severity field MUST be set only when Status=False. + // +optional + Severity ConditionSeverity `json:"severity,omitempty"` + + // Last time the condition transitioned from one status to another. + // This should be when the underlying condition changed. If that is not known, then using the time when + // the API field changed is acceptable. + // +required + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + + // The reason for the condition's last transition in CamelCase. + // The specific API may choose whether or not this field is considered a guaranteed API. + // This field may not be empty. + // +optional + Reason string `json:"reason,omitempty"` + + // A human readable message indicating details about the transition. + // This field may be empty. + // +optional + Message string `json:"message,omitempty"` +} + +// ANCHOR_END: Condition + +// ANCHOR: Conditions + +// Conditions provide observations of the operational state of a Cluster API resource. +type Conditions []Condition + +// ANCHOR_END: Conditions diff --git a/internal/apis/core/v1alpha3/conversion.go b/internal/apis/core/v1alpha3/conversion.go new file mode 100644 index 000000000000..9352eb4de3af --- /dev/null +++ b/internal/apis/core/v1alpha3/conversion.go @@ -0,0 +1,332 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/cluster-api/util/conditions" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *Cluster) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.Cluster) + + if err := Convert_v1alpha3_Cluster_To_v1beta1_Cluster(src, dst, nil); err != nil { + return err + } + + // Given this is a bool and there is no timestamp associated with it, when this condition is set, its timestamp + // will be "now". See https://github.com/kubernetes-sigs/cluster-api/issues/3798#issuecomment-708619826 for more + // discussion. + if src.Status.ControlPlaneInitialized { + conditions.MarkTrue(dst, clusterv1.ControlPlaneInitializedCondition) + } + + // Manually restore data. + restored := &clusterv1.Cluster{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.Topology != nil { + dst.Spec.Topology = restored.Spec.Topology + } + + return nil +} + +func (dst *Cluster) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.Cluster) + + if err := Convert_v1beta1_Cluster_To_v1alpha3_Cluster(src, dst, nil); err != nil { + return err + } + + // Set the v1alpha3 boolean status field if the v1alpha4 condition was true + if conditions.IsTrue(src, clusterv1.ControlPlaneInitializedCondition) { + dst.Status.ControlPlaneInitialized = true + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *ClusterList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.ClusterList) + + return Convert_v1alpha3_ClusterList_To_v1beta1_ClusterList(src, dst, nil) +} + +func (dst *ClusterList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.ClusterList) + + return Convert_v1beta1_ClusterList_To_v1alpha3_ClusterList(src, dst, nil) +} + +func (src *Machine) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.Machine) + + if err := Convert_v1alpha3_Machine_To_v1beta1_Machine(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &clusterv1.Machine{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.NodeDeletionTimeout = restored.Spec.NodeDeletionTimeout + dst.Spec.NodeVolumeDetachTimeout = restored.Spec.NodeVolumeDetachTimeout + dst.Status.NodeInfo = restored.Status.NodeInfo + dst.Status.CertificatesExpiryDate = restored.Status.CertificatesExpiryDate + return nil +} + +func (dst *Machine) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.Machine) + + if err := Convert_v1beta1_Machine_To_v1alpha3_Machine(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *MachineList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineList) + + return Convert_v1alpha3_MachineList_To_v1beta1_MachineList(src, dst, nil) +} + +func (dst *MachineList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineList) + + return Convert_v1beta1_MachineList_To_v1alpha3_MachineList(src, dst, nil) +} + +func (src *MachineSet) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineSet) + + if err := Convert_v1alpha3_MachineSet_To_v1beta1_MachineSet(src, dst, nil); err != nil { + return err + } + // Manually restore data. + restored := &clusterv1.MachineSet{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + dst.Spec.Template.Spec.NodeDeletionTimeout = restored.Spec.Template.Spec.NodeDeletionTimeout + dst.Spec.Template.Spec.NodeVolumeDetachTimeout = restored.Spec.Template.Spec.NodeVolumeDetachTimeout + dst.Status.Conditions = restored.Status.Conditions + return nil +} + +func (dst *MachineSet) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineSet) + + if err := Convert_v1beta1_MachineSet_To_v1alpha3_MachineSet(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + return nil +} + +func (src *MachineSetList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineSetList) + + return Convert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList(src, dst, nil) +} + +func (dst *MachineSetList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineSetList) + + return Convert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList(src, dst, nil) +} + +func (src *MachineDeployment) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineDeployment) + + if err := Convert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &clusterv1.MachineDeployment{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.Strategy != nil && restored.Spec.Strategy.RollingUpdate != nil { + if dst.Spec.Strategy == nil { + dst.Spec.Strategy = &clusterv1.MachineDeploymentStrategy{} + } + if dst.Spec.Strategy.RollingUpdate == nil { + dst.Spec.Strategy.RollingUpdate = &clusterv1.MachineRollingUpdateDeployment{} + } + dst.Spec.Strategy.RollingUpdate.DeletePolicy = restored.Spec.Strategy.RollingUpdate.DeletePolicy + } + + dst.Spec.Template.Spec.NodeDeletionTimeout = restored.Spec.Template.Spec.NodeDeletionTimeout + dst.Spec.Template.Spec.NodeVolumeDetachTimeout = restored.Spec.Template.Spec.NodeVolumeDetachTimeout + dst.Spec.RolloutAfter = restored.Spec.RolloutAfter + dst.Status.Conditions = restored.Status.Conditions + return nil +} + +func (dst *MachineDeployment) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineDeployment) + + if err := Convert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *MachineDeploymentList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineDeploymentList) + + return Convert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList(src, dst, nil) +} + +func (dst *MachineDeploymentList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineDeploymentList) + + return Convert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList(src, dst, nil) +} + +func (src *MachineHealthCheck) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineHealthCheck) + + if err := Convert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &clusterv1.MachineHealthCheck{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.UnhealthyRange != nil { + dst.Spec.UnhealthyRange = restored.Spec.UnhealthyRange + } + + return nil +} + +func (dst *MachineHealthCheck) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineHealthCheck) + + if err := Convert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *MachineHealthCheckList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*clusterv1.MachineHealthCheckList) + + return Convert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList(src, dst, nil) +} + +func (dst *MachineHealthCheckList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*clusterv1.MachineHealthCheckList) + + return Convert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList(src, dst, nil) +} + +func Convert_v1beta1_MachineSetStatus_To_v1alpha3_MachineSetStatus(in *clusterv1.MachineSetStatus, out *MachineSetStatus, _ apiconversion.Scope) error { + // Status.Conditions was introduced in v1alpha4, thus requiring a custom conversion function; the values is going to be preserved in an annotation thus allowing roundtrip without loosing informations + return autoConvert_v1beta1_MachineSetStatus_To_v1alpha3_MachineSetStatus(in, out, nil) +} + +func Convert_v1beta1_ClusterSpec_To_v1alpha3_ClusterSpec(in *clusterv1.ClusterSpec, out *ClusterSpec, s apiconversion.Scope) error { + // NOTE: custom conversion func is required because spec.Topology does not exist in v1alpha3 + return autoConvert_v1beta1_ClusterSpec_To_v1alpha3_ClusterSpec(in, out, s) +} + +func Convert_v1alpha3_Bootstrap_To_v1beta1_Bootstrap(in *Bootstrap, out *clusterv1.Bootstrap, s apiconversion.Scope) error { + return autoConvert_v1alpha3_Bootstrap_To_v1beta1_Bootstrap(in, out, s) +} + +func Convert_v1beta1_MachineRollingUpdateDeployment_To_v1alpha3_MachineRollingUpdateDeployment(in *clusterv1.MachineRollingUpdateDeployment, out *MachineRollingUpdateDeployment, s apiconversion.Scope) error { + return autoConvert_v1beta1_MachineRollingUpdateDeployment_To_v1alpha3_MachineRollingUpdateDeployment(in, out, s) +} + +func Convert_v1beta1_MachineHealthCheckSpec_To_v1alpha3_MachineHealthCheckSpec(in *clusterv1.MachineHealthCheckSpec, out *MachineHealthCheckSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_MachineHealthCheckSpec_To_v1alpha3_MachineHealthCheckSpec(in, out, s) +} + +func Convert_v1alpha3_ClusterStatus_To_v1beta1_ClusterStatus(in *ClusterStatus, out *clusterv1.ClusterStatus, s apiconversion.Scope) error { + return autoConvert_v1alpha3_ClusterStatus_To_v1beta1_ClusterStatus(in, out, s) +} + +func Convert_v1alpha3_ObjectMeta_To_v1beta1_ObjectMeta(in *ObjectMeta, out *clusterv1.ObjectMeta, s apiconversion.Scope) error { + return autoConvert_v1alpha3_ObjectMeta_To_v1beta1_ObjectMeta(in, out, s) +} + +func Convert_v1beta1_MachineStatus_To_v1alpha3_MachineStatus(in *clusterv1.MachineStatus, out *MachineStatus, s apiconversion.Scope) error { + return autoConvert_v1beta1_MachineStatus_To_v1alpha3_MachineStatus(in, out, s) +} + +func Convert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(in *clusterv1.MachineSpec, out *MachineSpec, s apiconversion.Scope) error { + // spec.nodeDeletionTimeout has been added with v1beta1. + return autoConvert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(in, out, s) +} + +func Convert_v1beta1_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec(in *clusterv1.MachineDeploymentSpec, out *MachineDeploymentSpec, s apiconversion.Scope) error { + return autoConvert_v1beta1_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec(in, out, s) +} + +func Convert_v1beta1_MachineDeploymentStatus_To_v1alpha3_MachineDeploymentStatus(in *clusterv1.MachineDeploymentStatus, out *MachineDeploymentStatus, s apiconversion.Scope) error { + // Status.Conditions was introduced in v1alpha4, thus requiring a custom conversion function; the values is going to be preserved in an annotation thus allowing roundtrip without loosing informations + return autoConvert_v1beta1_MachineDeploymentStatus_To_v1alpha3_MachineDeploymentStatus(in, out, s) +} + +func Convert_v1alpha3_MachineStatus_To_v1beta1_MachineStatus(in *MachineStatus, out *clusterv1.MachineStatus, s apiconversion.Scope) error { + // Status.version has been removed in v1beta1, thus requiring custom conversion function. the information will be dropped. + return autoConvert_v1alpha3_MachineStatus_To_v1beta1_MachineStatus(in, out, s) +} diff --git a/internal/apis/core/v1alpha3/conversion_test.go b/internal/apis/core/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..f685a42566dd --- /dev/null +++ b/internal/apis/core/v1alpha3/conversion_test.go @@ -0,0 +1,141 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + fuzz "github.com/google/gofuzz" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" + runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for Cluster", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &clusterv1.Cluster{}, + Spoke: &Cluster{}, + SpokeAfterMutation: clusterSpokeAfterMutation, + FuzzerFuncs: []fuzzer.FuzzerFuncs{ClusterJSONFuzzFuncs}, + })) + + t.Run("for Machine", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &clusterv1.Machine{}, + Spoke: &Machine{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{BootstrapFuzzFuncs, MachineStatusFuzzFunc}, + })) + + t.Run("for MachineSet", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &clusterv1.MachineSet{}, + Spoke: &MachineSet{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{BootstrapFuzzFuncs, CustomObjectMetaFuzzFunc}, + })) + + t.Run("for MachineDeployment", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &clusterv1.MachineDeployment{}, + Spoke: &MachineDeployment{}, + FuzzerFuncs: []fuzzer.FuzzerFuncs{BootstrapFuzzFuncs, CustomObjectMetaFuzzFunc}, + })) + + t.Run("for MachineHealthCheck", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &clusterv1.MachineHealthCheck{}, + Spoke: &MachineHealthCheck{}, + })) +} + +func MachineStatusFuzzFunc(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + MachineStatusFuzzer, + } +} + +func MachineStatusFuzzer(in *MachineStatus, c fuzz.Continue) { + c.FuzzNoCustom(in) + + // These fields have been removed in v1beta1 + // data is going to be lost, so we're forcing zero values to avoid round trip errors. + in.Version = nil +} + +func CustomObjectMetaFuzzFunc(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + CustomObjectMetaFuzzer, + } +} + +func CustomObjectMetaFuzzer(in *ObjectMeta, c fuzz.Continue) { + c.FuzzNoCustom(in) + + // These fields have been removed in v1alpha4 + // data is going to be lost, so we're forcing zero values here. + in.Name = "" + in.GenerateName = "" + in.Namespace = "" + in.OwnerReferences = nil +} + +func BootstrapFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + BootstrapFuzzer, + } +} + +func BootstrapFuzzer(obj *Bootstrap, c fuzz.Continue) { + c.FuzzNoCustom(obj) + + // Bootstrap.Data has been removed in v1alpha4, so setting it to nil in order to avoid v1alpha3 --> --> v1alpha3 round trip errors. + obj.Data = nil +} + +// clusterSpokeAfterMutation modifies the spoke version of the Cluster such that it can pass an equality test in the +// spoke-hub-spoke conversion scenario. +func clusterSpokeAfterMutation(c conversion.Convertible) { + cluster := c.(*Cluster) + + // Create a temporary 0-length slice using the same underlying array as cluster.Status.Conditions to avoid + // allocations. + tmp := cluster.Status.Conditions[:0] + + for i := range cluster.Status.Conditions { + condition := cluster.Status.Conditions[i] + + // Keep everything that is not ControlPlaneInitializedCondition + if condition.Type != ConditionType(clusterv1.ControlPlaneInitializedCondition) { + tmp = append(tmp, condition) + } + } + + // Point cluster.Status.Conditions and our slice that does not have ControlPlaneInitializedCondition + cluster.Status.Conditions = tmp +} + +func ClusterJSONFuzzFuncs(_ runtimeserializer.CodecFactory) []interface{} { + return []interface{}{ + ClusterVariableFuzzer, + } +} + +func ClusterVariableFuzzer(in *clusterv1.ClusterVariable, c fuzz.Continue) { + c.FuzzNoCustom(in) + + // Not every random byte array is valid JSON, e.g. a string without `""`,so we're setting a valid value. + in.Value = apiextensionsv1.JSON{Raw: []byte("\"test-string\"")} +} diff --git a/internal/apis/core/v1alpha3/doc.go b/internal/apis/core/v1alpha3/doc.go new file mode 100644 index 000000000000..6f187ea21760 --- /dev/null +++ b/internal/apis/core/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/internal/apis/core/v1alpha3/groupversion_info.go b/internal/apis/core/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..cbaaba921645 --- /dev/null +++ b/internal/apis/core/v1alpha3/groupversion_info.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the cluster v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=cluster.x-k8s.io +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme + + localSchemeBuilder = SchemeBuilder.SchemeBuilder +) diff --git a/internal/apis/core/v1alpha3/machine_phase_types.go b/internal/apis/core/v1alpha3/machine_phase_types.go new file mode 100644 index 000000000000..6614436d1534 --- /dev/null +++ b/internal/apis/core/v1alpha3/machine_phase_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +// MachinePhase is a string representation of a Machine Phase. +// +// This type is a high-level indicator of the status of the Machine as it is provisioned, +// from the API user’s perspective. +// +// The value should not be interpreted by any software components as a reliable indication +// of the actual state of the Machine, and controllers should not use the Machine Phase field +// value when making decisions about what action to take. +// +// Controllers should always look at the actual state of the Machine’s fields to make those decisions. +type MachinePhase string + +const ( + // MachinePhasePending is the first state a Machine is assigned by + // Cluster API Machine controller after being created. + MachinePhasePending = MachinePhase("Pending") + + // MachinePhaseProvisioning is the state when the + // Machine infrastructure is being created. + MachinePhaseProvisioning = MachinePhase("Provisioning") + + // MachinePhaseProvisioned is the state when its + // infrastructure has been created and configured. + MachinePhaseProvisioned = MachinePhase("Provisioned") + + // MachinePhaseRunning is the Machine state when it has + // become a Kubernetes Node in a Ready state. + MachinePhaseRunning = MachinePhase("Running") + + // MachinePhaseDeleting is the Machine state when a delete + // request has been sent to the API Server, + // but its infrastructure has not yet been fully deleted. + MachinePhaseDeleting = MachinePhase("Deleting") + + // MachinePhaseDeleted is the Machine state when the object + // and the related infrastructure is deleted and + // ready to be garbage collected by the API Server. + MachinePhaseDeleted = MachinePhase("Deleted") + + // MachinePhaseFailed is the Machine state when the system + // might require user intervention. + MachinePhaseFailed = MachinePhase("Failed") + + // MachinePhaseUnknown is returned if the Machine state cannot be determined. + MachinePhaseUnknown = MachinePhase("Unknown") +) diff --git a/internal/apis/core/v1alpha3/machine_types.go b/internal/apis/core/v1alpha3/machine_types.go new file mode 100644 index 000000000000..69b0e1b3053a --- /dev/null +++ b/internal/apis/core/v1alpha3/machine_types.go @@ -0,0 +1,283 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + capierrors "sigs.k8s.io/cluster-api/errors" +) + +const ( + // MachineFinalizer is set on PrepareForCreate callback. + MachineFinalizer = "machine.cluster.x-k8s.io" + + // MachineControlPlaneLabelName is the label set on machines or related objects that are part of a control plane. + MachineControlPlaneLabelName = "cluster.x-k8s.io/control-plane" + + // ExcludeNodeDrainingAnnotation annotation explicitly skips node draining if set. + ExcludeNodeDrainingAnnotation = "machine.cluster.x-k8s.io/exclude-node-draining" + + // MachineSetLabelName is the label set on machines if they're controlled by MachineSet. + MachineSetLabelName = "cluster.x-k8s.io/set-name" + + // MachineDeploymentLabelName is the label set on machines if they're controlled by MachineDeployment. + MachineDeploymentLabelName = "cluster.x-k8s.io/deployment-name" + + // PreDrainDeleteHookAnnotationPrefix annotation specifies the prefix we + // search each annotation for during the pre-drain.delete lifecycle hook + // to pause reconciliation of deletion. These hooks will prevent removal of + // draining the associated node until all are removed. + PreDrainDeleteHookAnnotationPrefix = "pre-drain.delete.hook.machine.cluster.x-k8s.io" + + // PreTerminateDeleteHookAnnotationPrefix annotation specifies the prefix we + // search each annotation for during the pre-terminate.delete lifecycle hook + // to pause reconciliation of deletion. These hooks will prevent removal of + // an instance from an infrastructure provider until all are removed. + PreTerminateDeleteHookAnnotationPrefix = "pre-terminate.delete.hook.machine.cluster.x-k8s.io" +) + +// ANCHOR: MachineSpec + +// MachineSpec defines the desired state of Machine. +type MachineSpec struct { + // ClusterName is the name of the Cluster this object belongs to. + // +kubebuilder:validation:MinLength=1 + ClusterName string `json:"clusterName"` + + // Bootstrap is a reference to a local struct which encapsulates + // fields to configure the Machine’s bootstrapping mechanism. + Bootstrap Bootstrap `json:"bootstrap"` + + // InfrastructureRef is a required reference to a custom resource + // offered by an infrastructure provider. + InfrastructureRef corev1.ObjectReference `json:"infrastructureRef"` + + // Version defines the desired Kubernetes version. + // This field is meant to be optionally used by bootstrap providers. + // +optional + Version *string `json:"version,omitempty"` + + // ProviderID is the identification ID of the machine provided by the provider. + // This field must match the provider ID as seen on the node object corresponding to this machine. + // This field is required by higher level consumers of cluster-api. Example use case is cluster autoscaler + // with cluster-api as provider. Clean-up logic in the autoscaler compares machines to nodes to find out + // machines at provider which could not get registered as Kubernetes nodes. With cluster-api as a + // generic out-of-tree provider for autoscaler, this field is required by autoscaler to be + // able to have a provider view of the list of machines. Another list of nodes is queried from the k8s apiserver + // and then a comparison is done to find out unregistered machines and are marked for delete. + // This field will be set by the actuators and consumed by higher level entities like autoscaler that will + // be interfacing with cluster-api as generic provider. + // +optional + ProviderID *string `json:"providerID,omitempty"` + + // FailureDomain is the failure domain the machine will be created in. + // Must match a key in the FailureDomains map stored on the cluster object. + // +optional + FailureDomain *string `json:"failureDomain,omitempty"` + + // NodeDrainTimeout is the total amount of time that the controller will spend on draining a node. + // The default value is 0, meaning that the node can be drained without any time limitations. + // NOTE: NodeDrainTimeout is different from `kubectl drain --timeout` + // +optional + NodeDrainTimeout *metav1.Duration `json:"nodeDrainTimeout,omitempty"` +} + +// ANCHOR_END: MachineSpec + +// ANCHOR: MachineStatus + +// MachineStatus defines the observed state of Machine. +type MachineStatus struct { + // NodeRef will point to the corresponding Node if it exists. + // +optional + NodeRef *corev1.ObjectReference `json:"nodeRef,omitempty"` + + // LastUpdated identifies when the phase of the Machine last transitioned. + // +optional + LastUpdated *metav1.Time `json:"lastUpdated,omitempty"` + + // Version specifies the current version of Kubernetes running + // on the corresponding Node. This is meant to be a means of bubbling + // up status from the Node to the Machine. + // It is entirely optional, but useful for end-user UX if it’s present. + // +optional + Version *string `json:"version,omitempty"` + + // FailureReason will be set in the event that there is a terminal problem + // reconciling the Machine and will contain a succinct value suitable + // for machine interpretation. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the Machine's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the Machine object and/or logged in the + // controller's output. + // +optional + FailureReason *capierrors.MachineStatusError `json:"failureReason,omitempty"` + + // FailureMessage will be set in the event that there is a terminal problem + // reconciling the Machine and will contain a more verbose string suitable + // for logging and human consumption. + // + // This field should not be set for transitive errors that a controller + // faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the Machine's spec or the configuration of + // the controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the controller, or the + // responsible controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the Machine object and/or logged in the + // controller's output. + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` + + // Addresses is a list of addresses assigned to the machine. + // This field is copied from the infrastructure provider reference. + // +optional + Addresses MachineAddresses `json:"addresses,omitempty"` + + // Phase represents the current phase of machine actuation. + // E.g. Pending, Running, Terminating, Failed etc. + // +optional + Phase string `json:"phase,omitempty"` + + // BootstrapReady is the state of the bootstrap provider. + // +optional + BootstrapReady bool `json:"bootstrapReady"` + + // InfrastructureReady is the state of the infrastructure provider. + // +optional + InfrastructureReady bool `json:"infrastructureReady"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Conditions defines current service state of the Machine. + // +optional + Conditions Conditions `json:"conditions,omitempty"` +} + +// ANCHOR_END: MachineStatus + +// SetTypedPhase sets the Phase field to the string representation of MachinePhase. +func (m *MachineStatus) SetTypedPhase(p MachinePhase) { + m.Phase = string(p) +} + +// GetTypedPhase attempts to parse the Phase field and return +// the typed MachinePhase representation as described in `machine_phase_types.go`. +func (m *MachineStatus) GetTypedPhase() MachinePhase { + switch phase := MachinePhase(m.Phase); phase { + case + MachinePhasePending, + MachinePhaseProvisioning, + MachinePhaseProvisioned, + MachinePhaseRunning, + MachinePhaseDeleting, + MachinePhaseDeleted, + MachinePhaseFailed: + return phase + default: + return MachinePhaseUnknown + } +} + +// ANCHOR: Bootstrap + +// Bootstrap capsulates fields to configure the Machine’s bootstrapping mechanism. +type Bootstrap struct { + // ConfigRef is a reference to a bootstrap provider-specific resource + // that holds configuration details. The reference is optional to + // allow users/operators to specify Bootstrap.Data without + // the need of a controller. + // +optional + ConfigRef *corev1.ObjectReference `json:"configRef,omitempty"` + + // Data contains the bootstrap data, such as cloud-init details scripts. + // If nil, the Machine should remain in the Pending state. + // + // Deprecated: Switch to DataSecretName. + // + // +optional + Data *string `json:"data,omitempty"` + + // DataSecretName is the name of the secret that stores the bootstrap data script. + // If nil, the Machine should remain in the Pending state. + // +optional + DataSecretName *string `json:"dataSecretName,omitempty"` +} + +// ANCHOR_END: Bootstrap + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=machines,shortName=ma,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="ProviderID",type="string",JSONPath=".spec.providerID",description="Provider ID" +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="Machine status such as Terminating/Pending/Running/Failed etc" +// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="Kubernetes version associated with this Machine" +// +kubebuilder:printcolumn:name="NodeName",type="string",JSONPath=".status.nodeRef.name",description="Node name associated with this machine",priority=1 + +// Machine is the Schema for the machines API. +// +// Deprecated: This type will be removed in one of the next releases. +type Machine struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec MachineSpec `json:"spec,omitempty"` + Status MachineStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (m *Machine) GetConditions() Conditions { + return m.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (m *Machine) SetConditions(conditions Conditions) { + m.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// MachineList contains a list of Machine. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Machine `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Machine{}, &MachineList{}) +} diff --git a/internal/apis/core/v1alpha3/machinedeployment_types.go b/internal/apis/core/v1alpha3/machinedeployment_types.go new file mode 100644 index 000000000000..4aa959c8d6b0 --- /dev/null +++ b/internal/apis/core/v1alpha3/machinedeployment_types.go @@ -0,0 +1,279 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// MachineDeploymentStrategyType defines the type of MachineDeployment rollout strategies. +type MachineDeploymentStrategyType string + +const ( + // RollingUpdateMachineDeploymentStrategyType replaces the old MachineSet by new one using rolling update + // i.e. gradually scale down the old MachineSet and scale up the new one. + RollingUpdateMachineDeploymentStrategyType MachineDeploymentStrategyType = "RollingUpdate" + + // RevisionAnnotation is the revision annotation of a machine deployment's machine sets which records its rollout sequence. + RevisionAnnotation = "machinedeployment.clusters.x-k8s.io/revision" + // RevisionHistoryAnnotation maintains the history of all old revisions that a machine set has served for a machine deployment. + RevisionHistoryAnnotation = "machinedeployment.clusters.x-k8s.io/revision-history" + // DesiredReplicasAnnotation is the desired replicas for a machine deployment recorded as an annotation + // in its machine sets. Helps in separating scaling events from the rollout process and for + // determining if the new machine set for a deployment is really saturated. + DesiredReplicasAnnotation = "machinedeployment.clusters.x-k8s.io/desired-replicas" + // MaxReplicasAnnotation is the maximum replicas a deployment can have at a given point, which + // is machinedeployment.spec.replicas + maxSurge. Used by the underlying machine sets to estimate their + // proportions in case the deployment has surge replicas. + MaxReplicasAnnotation = "machinedeployment.clusters.x-k8s.io/max-replicas" +) + +// ANCHOR: MachineDeploymentSpec + +// MachineDeploymentSpec defines the desired state of MachineDeployment. +type MachineDeploymentSpec struct { + // ClusterName is the name of the Cluster this object belongs to. + // +kubebuilder:validation:MinLength=1 + ClusterName string `json:"clusterName"` + + // Number of desired machines. Defaults to 1. + // This is a pointer to distinguish between explicit zero and not specified. + Replicas *int32 `json:"replicas,omitempty"` + + // Label selector for machines. Existing MachineSets whose machines are + // selected by this will be the ones affected by this deployment. + // It must match the machine template's labels. + Selector metav1.LabelSelector `json:"selector"` + + // Template describes the machines that will be created. + Template MachineTemplateSpec `json:"template"` + + // The deployment strategy to use to replace existing machines with + // new ones. + // +optional + Strategy *MachineDeploymentStrategy `json:"strategy,omitempty"` + + // Minimum number of seconds for which a newly created machine should + // be ready. + // Defaults to 0 (machine will be considered available as soon as it + // is ready) + // +optional + MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` + + // The number of old MachineSets to retain to allow rollback. + // This is a pointer to distinguish between explicit zero and not specified. + // Defaults to 1. + // +optional + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` + + // Indicates that the deployment is paused. + // +optional + Paused bool `json:"paused,omitempty"` + + // The maximum time in seconds for a deployment to make progress before it + // is considered to be failed. The deployment controller will continue to + // process failed deployments and a condition with a ProgressDeadlineExceeded + // reason will be surfaced in the deployment status. Note that progress will + // not be estimated during the time a deployment is paused. Defaults to 600s. + ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"` +} + +// ANCHOR_END: MachineDeploymentSpec + +// ANCHOR: MachineDeploymentStrategy + +// MachineDeploymentStrategy describes how to replace existing machines +// with new ones. +type MachineDeploymentStrategy struct { + // Type of deployment. Currently the only supported strategy is + // "RollingUpdate". + // Default is RollingUpdate. + // +optional + Type MachineDeploymentStrategyType `json:"type,omitempty"` + + // Rolling update config params. Present only if + // MachineDeploymentStrategyType = RollingUpdate. + // +optional + RollingUpdate *MachineRollingUpdateDeployment `json:"rollingUpdate,omitempty"` +} + +// ANCHOR_END: MachineDeploymentStrategy + +// ANCHOR: MachineRollingUpdateDeployment + +// MachineRollingUpdateDeployment is used to control the desired behavior of rolling update. +type MachineRollingUpdateDeployment struct { + // The maximum number of machines that can be unavailable during the update. + // Value can be an absolute number (ex: 5) or a percentage of desired + // machines (ex: 10%). + // Absolute number is calculated from percentage by rounding down. + // This can not be 0 if MaxSurge is 0. + // Defaults to 0. + // Example: when this is set to 30%, the old MachineSet can be scaled + // down to 70% of desired machines immediately when the rolling update + // starts. Once new machines are ready, old MachineSet can be scaled + // down further, followed by scaling up the new MachineSet, ensuring + // that the total number of machines available at all times + // during the update is at least 70% of desired machines. + // +optional + MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"` + + // The maximum number of machines that can be scheduled above the + // desired number of machines. + // Value can be an absolute number (ex: 5) or a percentage of + // desired machines (ex: 10%). + // This can not be 0 if MaxUnavailable is 0. + // Absolute number is calculated from percentage by rounding up. + // Defaults to 1. + // Example: when this is set to 30%, the new MachineSet can be scaled + // up immediately when the rolling update starts, such that the total + // number of old and new machines do not exceed 130% of desired + // machines. Once old machines have been killed, new MachineSet can + // be scaled up further, ensuring that total number of machines running + // at any time during the update is at most 130% of desired machines. + // +optional + MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"` +} + +// ANCHOR_END: MachineRollingUpdateDeployment + +// ANCHOR: MachineDeploymentStatus + +// MachineDeploymentStatus defines the observed state of MachineDeployment. +type MachineDeploymentStatus struct { + // The generation observed by the deployment controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Selector is the same as the label selector but in the string format to avoid introspection + // by clients. The string will be in the same format as the query-param syntax. + // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // +optional + Selector string `json:"selector,omitempty"` + + // Total number of non-terminated machines targeted by this deployment + // (their labels match the selector). + // +optional + Replicas int32 `json:"replicas,omitempty"` + + // Total number of non-terminated machines targeted by this deployment + // that have the desired template spec. + // +optional + UpdatedReplicas int32 `json:"updatedReplicas,omitempty"` + + // Total number of ready machines targeted by this deployment. + // +optional + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // Total number of available machines (ready for at least minReadySeconds) + // targeted by this deployment. + // +optional + AvailableReplicas int32 `json:"availableReplicas,omitempty"` + + // Total number of unavailable machines targeted by this deployment. + // This is the total number of machines that are still required for + // the deployment to have 100% available capacity. They may either + // be machines that are running but not yet available or machines + // that still have not been created. + // +optional + UnavailableReplicas int32 `json:"unavailableReplicas,omitempty"` + + // Phase represents the current phase of a MachineDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + // +optional + Phase string `json:"phase,omitempty"` +} + +// ANCHOR_END: MachineDeploymentStatus + +// MachineDeploymentPhase indicates the progress of the machine deployment. +type MachineDeploymentPhase string + +const ( + // MachineDeploymentPhaseScalingUp indicates the MachineDeployment is scaling up. + MachineDeploymentPhaseScalingUp = MachineDeploymentPhase("ScalingUp") + + // MachineDeploymentPhaseScalingDown indicates the MachineDeployment is scaling down. + MachineDeploymentPhaseScalingDown = MachineDeploymentPhase("ScalingDown") + + // MachineDeploymentPhaseRunning indicates scaling has completed and all Machines are running. + MachineDeploymentPhaseRunning = MachineDeploymentPhase("Running") + + // MachineDeploymentPhaseFailed indicates there was a problem scaling and user intervention might be required. + MachineDeploymentPhaseFailed = MachineDeploymentPhase("Failed") + + // MachineDeploymentPhaseUnknown indicates the state of the MachineDeployment cannot be determined. + MachineDeploymentPhaseUnknown = MachineDeploymentPhase("Unknown") +) + +// SetTypedPhase sets the Phase field to the string representation of MachineDeploymentPhase. +func (md *MachineDeploymentStatus) SetTypedPhase(p MachineDeploymentPhase) { + md.Phase = string(p) +} + +// GetTypedPhase attempts to parse the Phase field and return +// the typed MachineDeploymentPhase representation. +func (md *MachineDeploymentStatus) GetTypedPhase() MachineDeploymentPhase { + switch phase := MachineDeploymentPhase(md.Phase); phase { + case + MachineDeploymentPhaseScalingDown, + MachineDeploymentPhaseScalingUp, + MachineDeploymentPhaseRunning, + MachineDeploymentPhaseFailed: + return phase + default: + return MachineDeploymentPhaseUnknown + } +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=machinedeployments,shortName=md,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector +// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase",description="MachineDeployment status such as ScalingUp/ScalingDown/Running/Failed/Unknown" +// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this MachineDeployment" +// +kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas",description="Total number of ready machines targeted by this MachineDeployment" +// +kubebuilder:printcolumn:name="Updated",type=integer,JSONPath=".status.updatedReplicas",description="Total number of non-terminated machines targeted by this deployment that have the desired template spec" +// +kubebuilder:printcolumn:name="Unavailable",type=integer,JSONPath=".status.unavailableReplicas",description="Total number of unavailable machines targeted by this MachineDeployment" + +// MachineDeployment is the Schema for the machinedeployments API. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineDeployment struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec MachineDeploymentSpec `json:"spec,omitempty"` + Status MachineDeploymentStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// MachineDeploymentList contains a list of MachineDeployment. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineDeploymentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineDeployment `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MachineDeployment{}, &MachineDeploymentList{}) +} diff --git a/internal/apis/core/v1alpha3/machinehealthcheck_types.go b/internal/apis/core/v1alpha3/machinehealthcheck_types.go new file mode 100644 index 000000000000..00aba45ab68e --- /dev/null +++ b/internal/apis/core/v1alpha3/machinehealthcheck_types.go @@ -0,0 +1,162 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// ANCHOR: MachineHealthCheckSpec + +// MachineHealthCheckSpec defines the desired state of MachineHealthCheck. +type MachineHealthCheckSpec struct { + // ClusterName is the name of the Cluster this object belongs to. + // +kubebuilder:validation:MinLength=1 + ClusterName string `json:"clusterName"` + + // Label selector to match machines whose health will be exercised + Selector metav1.LabelSelector `json:"selector"` + + // UnhealthyConditions contains a list of the conditions that determine + // whether a node is considered unhealthy. The conditions are combined in a + // logical OR, i.e. if any of the conditions is met, the node is unhealthy. + // + // +kubebuilder:validation:MinItems=1 + UnhealthyConditions []UnhealthyCondition `json:"unhealthyConditions"` + + // Any further remediation is only allowed if at most "MaxUnhealthy" machines selected by + // "selector" are not healthy. + // +optional + MaxUnhealthy *intstr.IntOrString `json:"maxUnhealthy,omitempty"` + + // Machines older than this duration without a node will be considered to have + // failed and will be remediated. + // +optional + NodeStartupTimeout *metav1.Duration `json:"nodeStartupTimeout,omitempty"` + + // RemediationTemplate is a reference to a remediation template + // provided by an infrastructure provider. + // + // This field is completely optional, when filled, the MachineHealthCheck controller + // creates a new object from the template referenced and hands off remediation of the machine to + // a controller that lives outside of Cluster API. + // +optional + RemediationTemplate *corev1.ObjectReference `json:"remediationTemplate,omitempty"` +} + +// ANCHOR_END: MachineHealthCHeckSpec + +// ANCHOR: UnhealthyCondition + +// UnhealthyCondition represents a Node condition type and value with a timeout +// specified as a duration. When the named condition has been in the given +// status for at least the timeout value, a node is considered unhealthy. +type UnhealthyCondition struct { + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:MinLength=1 + Type corev1.NodeConditionType `json:"type"` + + // +kubebuilder:validation:Type=string + // +kubebuilder:validation:MinLength=1 + Status corev1.ConditionStatus `json:"status"` + + Timeout metav1.Duration `json:"timeout"` +} + +// ANCHOR_END: UnhealthyCondition + +// ANCHOR: MachineHealthCheckStatus + +// MachineHealthCheckStatus defines the observed state of MachineHealthCheck. +type MachineHealthCheckStatus struct { + // total number of machines counted by this machine health check + // +kubebuilder:validation:Minimum=0 + ExpectedMachines int32 `json:"expectedMachines,omitempty"` + + // total number of healthy machines counted by this machine health check + // +kubebuilder:validation:Minimum=0 + CurrentHealthy int32 `json:"currentHealthy,omitempty"` + + // RemediationsAllowed is the number of further remediations allowed by this machine health check before + // maxUnhealthy short circuiting will be applied + // +kubebuilder:validation:Minimum=0 + RemediationsAllowed int32 `json:"remediationsAllowed,omitempty"` + + // ObservedGeneration is the latest generation observed by the controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Targets shows the current list of machines the machine health check is watching + // +optional + Targets []string `json:"targets,omitempty"` + + // Conditions defines current service state of the MachineHealthCheck. + // +optional + Conditions Conditions `json:"conditions,omitempty"` +} + +// ANCHOR_END: MachineHealthCheckStatus + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=machinehealthchecks,shortName=mhc;mhcs,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="MaxUnhealthy",type="string",JSONPath=".spec.maxUnhealthy",description="Maximum number of unhealthy machines allowed" +// +kubebuilder:printcolumn:name="ExpectedMachines",type="integer",JSONPath=".status.expectedMachines",description="Number of machines currently monitored" +// +kubebuilder:printcolumn:name="CurrentHealthy",type="integer",JSONPath=".status.currentHealthy",description="Current observed healthy machines" + +// MachineHealthCheck is the Schema for the machinehealthchecks API. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineHealthCheck struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Specification of machine health check policy + Spec MachineHealthCheckSpec `json:"spec,omitempty"` + + // Most recently observed status of MachineHealthCheck resource + Status MachineHealthCheckStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (m *MachineHealthCheck) GetConditions() Conditions { + return m.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (m *MachineHealthCheck) SetConditions(conditions Conditions) { + m.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// MachineHealthCheckList contains a list of MachineHealthCheck. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineHealthCheckList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineHealthCheck `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MachineHealthCheck{}, &MachineHealthCheckList{}) +} diff --git a/internal/apis/core/v1alpha3/machineset_types.go b/internal/apis/core/v1alpha3/machineset_types.go new file mode 100644 index 000000000000..6ce31ca0ec95 --- /dev/null +++ b/internal/apis/core/v1alpha3/machineset_types.go @@ -0,0 +1,221 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/validation/field" + + capierrors "sigs.k8s.io/cluster-api/errors" +) + +// ANCHOR: MachineSetSpec + +// MachineSetSpec defines the desired state of MachineSet. +type MachineSetSpec struct { + // ClusterName is the name of the Cluster this object belongs to. + // +kubebuilder:validation:MinLength=1 + ClusterName string `json:"clusterName"` + + // Replicas is the number of desired replicas. + // This is a pointer to distinguish between explicit zero and unspecified. + // Defaults to 1. + // +optional + Replicas *int32 `json:"replicas,omitempty"` + + // MinReadySeconds is the minimum number of seconds for which a newly created machine should be ready. + // Defaults to 0 (machine will be considered available as soon as it is ready) + // +optional + MinReadySeconds int32 `json:"minReadySeconds,omitempty"` + + // DeletePolicy defines the policy used to identify nodes to delete when downscaling. + // Defaults to "Random". Valid values are "Random, "Newest", "Oldest" + // +kubebuilder:validation:Enum=Random;Newest;Oldest + DeletePolicy string `json:"deletePolicy,omitempty"` + + // Selector is a label query over machines that should match the replica count. + // Label keys and values that must match in order to be controlled by this MachineSet. + // It must match the machine template's labels. + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + Selector metav1.LabelSelector `json:"selector"` + + // Template is the object that describes the machine that will be created if + // insufficient replicas are detected. + // Object references to custom resources are treated as templates. + // +optional + Template MachineTemplateSpec `json:"template,omitempty"` +} + +// ANCHOR_END: MachineSetSpec + +// ANCHOR: MachineTemplateSpec + +// MachineTemplateSpec describes the data needed to create a Machine from a template. +type MachineTemplateSpec struct { + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + // +optional + ObjectMeta `json:"metadata,omitempty"` + + // Specification of the desired behavior of the machine. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status + // +optional + Spec MachineSpec `json:"spec,omitempty"` +} + +// ANCHOR_END: MachineTemplateSpec + +// MachineSetDeletePolicy defines how priority is assigned to nodes to delete when +// downscaling a MachineSet. Defaults to "Random". +type MachineSetDeletePolicy string + +const ( + // RandomMachineSetDeletePolicy prioritizes both Machines that have the annotation + // "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy + // (Status.FailureReason or Status.FailureMessage are set to a non-empty value). + // Finally, it picks Machines at random to delete. + RandomMachineSetDeletePolicy MachineSetDeletePolicy = "Random" + + // NewestMachineSetDeletePolicy prioritizes both Machines that have the annotation + // "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy + // (Status.FailureReason or Status.FailureMessage are set to a non-empty value). + // It then prioritizes the newest Machines for deletion based on the Machine's CreationTimestamp. + NewestMachineSetDeletePolicy MachineSetDeletePolicy = "Newest" + + // OldestMachineSetDeletePolicy prioritizes both Machines that have the annotation + // "cluster.x-k8s.io/delete-machine=yes" and Machines that are unhealthy + // (Status.FailureReason or Status.FailureMessage are set to a non-empty value). + // It then prioritizes the oldest Machines for deletion based on the Machine's CreationTimestamp. + OldestMachineSetDeletePolicy MachineSetDeletePolicy = "Oldest" +) + +// ANCHOR: MachineSetStatus + +// MachineSetStatus defines the observed state of MachineSet. +type MachineSetStatus struct { + // Selector is the same as the label selector but in the string format to avoid introspection + // by clients. The string will be in the same format as the query-param syntax. + // More info about label selectors: http://kubernetes.io/docs/user-guide/labels#label-selectors + // +optional + Selector string `json:"selector,omitempty"` + + // Replicas is the most recently observed number of replicas. + // +optional + Replicas int32 `json:"replicas,omitempty"` + + // The number of replicas that have labels matching the labels of the machine template of the MachineSet. + // +optional + FullyLabeledReplicas int32 `json:"fullyLabeledReplicas,omitempty"` + + // The number of ready replicas for this MachineSet. A machine is considered ready when the node has been created and is "Ready". + // +optional + ReadyReplicas int32 `json:"readyReplicas,omitempty"` + + // The number of available replicas (ready for at least minReadySeconds) for this MachineSet. + // +optional + AvailableReplicas int32 `json:"availableReplicas,omitempty"` + + // ObservedGeneration reflects the generation of the most recently observed MachineSet. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // In the event that there is a terminal problem reconciling the + // replicas, both FailureReason and FailureMessage will be set. FailureReason + // will be populated with a succinct value suitable for machine + // interpretation, while FailureMessage will contain a more verbose + // string suitable for logging and human consumption. + // + // These fields should not be set for transitive errors that a + // controller faces that are expected to be fixed automatically over + // time (like service outages), but instead indicate that something is + // fundamentally wrong with the MachineTemplate's spec or the configuration of + // the machine controller, and that manual intervention is required. Examples + // of terminal errors would be invalid combinations of settings in the + // spec, values that are unsupported by the machine controller, or the + // responsible machine controller itself being critically misconfigured. + // + // Any transient errors that occur during the reconciliation of Machines + // can be added as events to the MachineSet object and/or logged in the + // controller's output. + // +optional + FailureReason *capierrors.MachineSetStatusError `json:"failureReason,omitempty"` + // +optional + FailureMessage *string `json:"failureMessage,omitempty"` +} + +// ANCHOR_END: MachineSetStatus + +// Validate validates the MachineSet fields. +func (m *MachineSet) Validate() field.ErrorList { + errors := field.ErrorList{} + + // validate spec.selector and spec.template.labels + fldPath := field.NewPath("spec") + errors = append(errors, metav1validation.ValidateLabelSelector(&m.Spec.Selector, metav1validation.LabelSelectorValidationOptions{}, fldPath.Child("selector"))...) + if len(m.Spec.Selector.MatchLabels)+len(m.Spec.Selector.MatchExpressions) == 0 { + errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "empty selector is not valid for MachineSet.")) + } + selector, err := metav1.LabelSelectorAsSelector(&m.Spec.Selector) + if err != nil { + errors = append(errors, field.Invalid(fldPath.Child("selector"), m.Spec.Selector, "invalid label selector.")) + } else { + labels := labels.Set(m.Spec.Template.Labels) + if !selector.Matches(labels) { + errors = append(errors, field.Invalid(fldPath.Child("template", "metadata", "labels"), m.Spec.Template.Labels, "`selector` does not match template `labels`")) + } + } + + return errors +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=machinesets,shortName=ms,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.selector +// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".status.replicas",description="Total number of non-terminated machines targeted by this machineset" +// +kubebuilder:printcolumn:name="Available",type="integer",JSONPath=".status.availableReplicas",description="Total number of available machines (ready for at least minReadySeconds)" +// +kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas",description="Total number of ready machines targeted by this machineset." + +// MachineSet is the Schema for the machinesets API. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineSet struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec MachineSetSpec `json:"spec,omitempty"` + Status MachineSetStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// MachineSetList contains a list of MachineSet. +// +// Deprecated: This type will be removed in one of the next releases. +type MachineSetList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []MachineSet `json:"items"` +} + +func init() { + SchemeBuilder.Register(&MachineSet{}, &MachineSetList{}) +} diff --git a/internal/apis/core/v1alpha3/suite_test.go b/internal/apis/core/v1alpha3/suite_test.go new file mode 100644 index 000000000000..1bff9a48c8b3 --- /dev/null +++ b/internal/apis/core/v1alpha3/suite_test.go @@ -0,0 +1,43 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "os" + "testing" + + // +kubebuilder:scaffold:imports + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + + "sigs.k8s.io/cluster-api/internal/test/envtest" +) + +var ( + env *envtest.Environment + ctx = ctrl.SetupSignalHandler() +) + +func TestMain(m *testing.M) { + utilruntime.Must(AddToScheme(scheme.Scheme)) + + os.Exit(envtest.Run(ctx, envtest.RunInput{ + M: m, + SetupEnv: func(e *envtest.Environment) { env = e }, + })) +} diff --git a/internal/apis/core/v1alpha3/zz_generated.conversion.go b/internal/apis/core/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..c7ea14ba3e55 --- /dev/null +++ b/internal/apis/core/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,1349 @@ +//go:build !ignore_autogenerated_core +// +build !ignore_autogenerated_core + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + intstr "k8s.io/apimachinery/pkg/util/intstr" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + errors "sigs.k8s.io/cluster-api/errors" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*APIEndpoint)(nil), (*v1beta1.APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(a.(*APIEndpoint), b.(*v1beta1.APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.APIEndpoint)(nil), (*APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(a.(*v1beta1.APIEndpoint), b.(*APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Bootstrap)(nil), (*Bootstrap)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap(a.(*v1beta1.Bootstrap), b.(*Bootstrap), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Cluster)(nil), (*v1beta1.Cluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Cluster_To_v1beta1_Cluster(a.(*Cluster), b.(*v1beta1.Cluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Cluster)(nil), (*Cluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Cluster_To_v1alpha3_Cluster(a.(*v1beta1.Cluster), b.(*Cluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterList)(nil), (*v1beta1.ClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterList_To_v1beta1_ClusterList(a.(*ClusterList), b.(*v1beta1.ClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterList)(nil), (*ClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterList_To_v1alpha3_ClusterList(a.(*v1beta1.ClusterList), b.(*ClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterNetwork)(nil), (*v1beta1.ClusterNetwork)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterNetwork_To_v1beta1_ClusterNetwork(a.(*ClusterNetwork), b.(*v1beta1.ClusterNetwork), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterNetwork)(nil), (*ClusterNetwork)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterNetwork_To_v1alpha3_ClusterNetwork(a.(*v1beta1.ClusterNetwork), b.(*ClusterNetwork), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ClusterSpec)(nil), (*v1beta1.ClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec(a.(*ClusterSpec), b.(*v1beta1.ClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ClusterStatus)(nil), (*ClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus(a.(*v1beta1.ClusterStatus), b.(*ClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Condition)(nil), (*v1beta1.Condition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Condition_To_v1beta1_Condition(a.(*Condition), b.(*v1beta1.Condition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Condition)(nil), (*Condition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Condition_To_v1alpha3_Condition(a.(*v1beta1.Condition), b.(*Condition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*FailureDomainSpec)(nil), (*v1beta1.FailureDomainSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(a.(*FailureDomainSpec), b.(*v1beta1.FailureDomainSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.FailureDomainSpec)(nil), (*FailureDomainSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(a.(*v1beta1.FailureDomainSpec), b.(*FailureDomainSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Machine)(nil), (*v1beta1.Machine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Machine_To_v1beta1_Machine(a.(*Machine), b.(*v1beta1.Machine), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Machine)(nil), (*Machine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Machine_To_v1alpha3_Machine(a.(*v1beta1.Machine), b.(*Machine), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineAddress)(nil), (*v1beta1.MachineAddress)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(a.(*MachineAddress), b.(*v1beta1.MachineAddress), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineAddress)(nil), (*MachineAddress)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(a.(*v1beta1.MachineAddress), b.(*MachineAddress), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineDeployment)(nil), (*v1beta1.MachineDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(a.(*MachineDeployment), b.(*v1beta1.MachineDeployment), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineDeployment)(nil), (*MachineDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(a.(*v1beta1.MachineDeployment), b.(*MachineDeployment), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineDeploymentList)(nil), (*v1beta1.MachineDeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList(a.(*MachineDeploymentList), b.(*v1beta1.MachineDeploymentList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineDeploymentList)(nil), (*MachineDeploymentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList(a.(*v1beta1.MachineDeploymentList), b.(*MachineDeploymentList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineDeploymentSpec)(nil), (*v1beta1.MachineDeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec(a.(*MachineDeploymentSpec), b.(*v1beta1.MachineDeploymentSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineDeploymentStatus)(nil), (*v1beta1.MachineDeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus(a.(*MachineDeploymentStatus), b.(*v1beta1.MachineDeploymentStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineDeploymentStrategy)(nil), (*v1beta1.MachineDeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy(a.(*MachineDeploymentStrategy), b.(*v1beta1.MachineDeploymentStrategy), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineDeploymentStrategy)(nil), (*MachineDeploymentStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy(a.(*v1beta1.MachineDeploymentStrategy), b.(*MachineDeploymentStrategy), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineHealthCheck)(nil), (*v1beta1.MachineHealthCheck)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(a.(*MachineHealthCheck), b.(*v1beta1.MachineHealthCheck), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineHealthCheck)(nil), (*MachineHealthCheck)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(a.(*v1beta1.MachineHealthCheck), b.(*MachineHealthCheck), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineHealthCheckList)(nil), (*v1beta1.MachineHealthCheckList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList(a.(*MachineHealthCheckList), b.(*v1beta1.MachineHealthCheckList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineHealthCheckList)(nil), (*MachineHealthCheckList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList(a.(*v1beta1.MachineHealthCheckList), b.(*MachineHealthCheckList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineHealthCheckSpec)(nil), (*v1beta1.MachineHealthCheckSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec(a.(*MachineHealthCheckSpec), b.(*v1beta1.MachineHealthCheckSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineHealthCheckStatus)(nil), (*v1beta1.MachineHealthCheckStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus(a.(*MachineHealthCheckStatus), b.(*v1beta1.MachineHealthCheckStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineHealthCheckStatus)(nil), (*MachineHealthCheckStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus(a.(*v1beta1.MachineHealthCheckStatus), b.(*MachineHealthCheckStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineList)(nil), (*v1beta1.MachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineList_To_v1beta1_MachineList(a.(*MachineList), b.(*v1beta1.MachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineList)(nil), (*MachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineList_To_v1alpha3_MachineList(a.(*v1beta1.MachineList), b.(*MachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineRollingUpdateDeployment)(nil), (*v1beta1.MachineRollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment(a.(*MachineRollingUpdateDeployment), b.(*v1beta1.MachineRollingUpdateDeployment), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineSet)(nil), (*v1beta1.MachineSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSet_To_v1beta1_MachineSet(a.(*MachineSet), b.(*v1beta1.MachineSet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineSet)(nil), (*MachineSet)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSet_To_v1alpha3_MachineSet(a.(*v1beta1.MachineSet), b.(*MachineSet), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineSetList)(nil), (*v1beta1.MachineSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList(a.(*MachineSetList), b.(*v1beta1.MachineSetList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineSetList)(nil), (*MachineSetList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList(a.(*v1beta1.MachineSetList), b.(*MachineSetList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineSetSpec)(nil), (*v1beta1.MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec(a.(*MachineSetSpec), b.(*v1beta1.MachineSetSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineSetSpec)(nil), (*MachineSetSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec(a.(*v1beta1.MachineSetSpec), b.(*MachineSetSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineSetStatus)(nil), (*v1beta1.MachineSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus(a.(*MachineSetStatus), b.(*v1beta1.MachineSetStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineSpec)(nil), (*v1beta1.MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(a.(*MachineSpec), b.(*v1beta1.MachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*MachineTemplateSpec)(nil), (*v1beta1.MachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(a.(*MachineTemplateSpec), b.(*v1beta1.MachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.MachineTemplateSpec)(nil), (*MachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(a.(*v1beta1.MachineTemplateSpec), b.(*MachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*NetworkRanges)(nil), (*v1beta1.NetworkRanges)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_NetworkRanges_To_v1beta1_NetworkRanges(a.(*NetworkRanges), b.(*v1beta1.NetworkRanges), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.NetworkRanges)(nil), (*NetworkRanges)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_NetworkRanges_To_v1alpha3_NetworkRanges(a.(*v1beta1.NetworkRanges), b.(*NetworkRanges), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.ObjectMeta)(nil), (*ObjectMeta)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta(a.(*v1beta1.ObjectMeta), b.(*ObjectMeta), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*UnhealthyCondition)(nil), (*v1beta1.UnhealthyCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_UnhealthyCondition_To_v1beta1_UnhealthyCondition(a.(*UnhealthyCondition), b.(*v1beta1.UnhealthyCondition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.UnhealthyCondition)(nil), (*UnhealthyCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_UnhealthyCondition_To_v1alpha3_UnhealthyCondition(a.(*v1beta1.UnhealthyCondition), b.(*UnhealthyCondition), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*Bootstrap)(nil), (*v1beta1.Bootstrap)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Bootstrap_To_v1beta1_Bootstrap(a.(*Bootstrap), b.(*v1beta1.Bootstrap), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ClusterStatus)(nil), (*v1beta1.ClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ClusterStatus_To_v1beta1_ClusterStatus(a.(*ClusterStatus), b.(*v1beta1.ClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*MachineStatus)(nil), (*v1beta1.MachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_MachineStatus_To_v1beta1_MachineStatus(a.(*MachineStatus), b.(*v1beta1.MachineStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ObjectMeta)(nil), (*v1beta1.ObjectMeta)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_ObjectMeta_To_v1beta1_ObjectMeta(a.(*ObjectMeta), b.(*v1beta1.ObjectMeta), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.ClusterSpec)(nil), (*ClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ClusterSpec_To_v1alpha3_ClusterSpec(a.(*v1beta1.ClusterSpec), b.(*ClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineDeploymentSpec)(nil), (*MachineDeploymentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec(a.(*v1beta1.MachineDeploymentSpec), b.(*MachineDeploymentSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineDeploymentStatus)(nil), (*MachineDeploymentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineDeploymentStatus_To_v1alpha3_MachineDeploymentStatus(a.(*v1beta1.MachineDeploymentStatus), b.(*MachineDeploymentStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineHealthCheckSpec)(nil), (*MachineHealthCheckSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineHealthCheckSpec_To_v1alpha3_MachineHealthCheckSpec(a.(*v1beta1.MachineHealthCheckSpec), b.(*MachineHealthCheckSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineRollingUpdateDeployment)(nil), (*MachineRollingUpdateDeployment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineRollingUpdateDeployment_To_v1alpha3_MachineRollingUpdateDeployment(a.(*v1beta1.MachineRollingUpdateDeployment), b.(*MachineRollingUpdateDeployment), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineSetStatus)(nil), (*MachineSetStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSetStatus_To_v1alpha3_MachineSetStatus(a.(*v1beta1.MachineSetStatus), b.(*MachineSetStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineSpec)(nil), (*MachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(a.(*v1beta1.MachineSpec), b.(*MachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.MachineStatus)(nil), (*MachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_MachineStatus_To_v1alpha3_MachineStatus(a.(*v1beta1.MachineStatus), b.(*MachineStatus), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + out.Host = in.Host + out.Port = in.Port + return nil +} + +// Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint is an autogenerated conversion function. +func Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + return autoConvert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in, out, s) +} + +func autoConvert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + out.Host = in.Host + out.Port = in.Port + return nil +} + +// Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint is an autogenerated conversion function. +func Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + return autoConvert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in, out, s) +} + +func autoConvert_v1alpha3_Bootstrap_To_v1beta1_Bootstrap(in *Bootstrap, out *v1beta1.Bootstrap, s conversion.Scope) error { + out.ConfigRef = (*v1.ObjectReference)(unsafe.Pointer(in.ConfigRef)) + // WARNING: in.Data requires manual conversion: does not exist in peer-type + out.DataSecretName = (*string)(unsafe.Pointer(in.DataSecretName)) + return nil +} + +func autoConvert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap(in *v1beta1.Bootstrap, out *Bootstrap, s conversion.Scope) error { + out.ConfigRef = (*v1.ObjectReference)(unsafe.Pointer(in.ConfigRef)) + out.DataSecretName = (*string)(unsafe.Pointer(in.DataSecretName)) + return nil +} + +// Convert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap is an autogenerated conversion function. +func Convert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap(in *v1beta1.Bootstrap, out *Bootstrap, s conversion.Scope) error { + return autoConvert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap(in, out, s) +} + +func autoConvert_v1alpha3_Cluster_To_v1beta1_Cluster(in *Cluster, out *v1beta1.Cluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_ClusterStatus_To_v1beta1_ClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_Cluster_To_v1beta1_Cluster is an autogenerated conversion function. +func Convert_v1alpha3_Cluster_To_v1beta1_Cluster(in *Cluster, out *v1beta1.Cluster, s conversion.Scope) error { + return autoConvert_v1alpha3_Cluster_To_v1beta1_Cluster(in, out, s) +} + +func autoConvert_v1beta1_Cluster_To_v1alpha3_Cluster(in *v1beta1.Cluster, out *Cluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_ClusterSpec_To_v1alpha3_ClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_Cluster_To_v1alpha3_Cluster is an autogenerated conversion function. +func Convert_v1beta1_Cluster_To_v1alpha3_Cluster(in *v1beta1.Cluster, out *Cluster, s conversion.Scope) error { + return autoConvert_v1beta1_Cluster_To_v1alpha3_Cluster(in, out, s) +} + +func autoConvert_v1alpha3_ClusterList_To_v1beta1_ClusterList(in *ClusterList, out *v1beta1.ClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.Cluster, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_Cluster_To_v1beta1_Cluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_ClusterList_To_v1beta1_ClusterList is an autogenerated conversion function. +func Convert_v1alpha3_ClusterList_To_v1beta1_ClusterList(in *ClusterList, out *v1beta1.ClusterList, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterList_To_v1beta1_ClusterList(in, out, s) +} + +func autoConvert_v1beta1_ClusterList_To_v1alpha3_ClusterList(in *v1beta1.ClusterList, out *ClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + if err := Convert_v1beta1_Cluster_To_v1alpha3_Cluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_ClusterList_To_v1alpha3_ClusterList is an autogenerated conversion function. +func Convert_v1beta1_ClusterList_To_v1alpha3_ClusterList(in *v1beta1.ClusterList, out *ClusterList, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterList_To_v1alpha3_ClusterList(in, out, s) +} + +func autoConvert_v1alpha3_ClusterNetwork_To_v1beta1_ClusterNetwork(in *ClusterNetwork, out *v1beta1.ClusterNetwork, s conversion.Scope) error { + out.APIServerPort = (*int32)(unsafe.Pointer(in.APIServerPort)) + out.Services = (*v1beta1.NetworkRanges)(unsafe.Pointer(in.Services)) + out.Pods = (*v1beta1.NetworkRanges)(unsafe.Pointer(in.Pods)) + out.ServiceDomain = in.ServiceDomain + return nil +} + +// Convert_v1alpha3_ClusterNetwork_To_v1beta1_ClusterNetwork is an autogenerated conversion function. +func Convert_v1alpha3_ClusterNetwork_To_v1beta1_ClusterNetwork(in *ClusterNetwork, out *v1beta1.ClusterNetwork, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterNetwork_To_v1beta1_ClusterNetwork(in, out, s) +} + +func autoConvert_v1beta1_ClusterNetwork_To_v1alpha3_ClusterNetwork(in *v1beta1.ClusterNetwork, out *ClusterNetwork, s conversion.Scope) error { + out.APIServerPort = (*int32)(unsafe.Pointer(in.APIServerPort)) + out.Services = (*NetworkRanges)(unsafe.Pointer(in.Services)) + out.Pods = (*NetworkRanges)(unsafe.Pointer(in.Pods)) + out.ServiceDomain = in.ServiceDomain + return nil +} + +// Convert_v1beta1_ClusterNetwork_To_v1alpha3_ClusterNetwork is an autogenerated conversion function. +func Convert_v1beta1_ClusterNetwork_To_v1alpha3_ClusterNetwork(in *v1beta1.ClusterNetwork, out *ClusterNetwork, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterNetwork_To_v1alpha3_ClusterNetwork(in, out, s) +} + +func autoConvert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec(in *ClusterSpec, out *v1beta1.ClusterSpec, s conversion.Scope) error { + out.Paused = in.Paused + out.ClusterNetwork = (*v1beta1.ClusterNetwork)(unsafe.Pointer(in.ClusterNetwork)) + if err := Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(&in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint, s); err != nil { + return err + } + out.ControlPlaneRef = (*v1.ObjectReference)(unsafe.Pointer(in.ControlPlaneRef)) + out.InfrastructureRef = (*v1.ObjectReference)(unsafe.Pointer(in.InfrastructureRef)) + return nil +} + +// Convert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec is an autogenerated conversion function. +func Convert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec(in *ClusterSpec, out *v1beta1.ClusterSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_ClusterSpec_To_v1beta1_ClusterSpec(in, out, s) +} + +func autoConvert_v1beta1_ClusterSpec_To_v1alpha3_ClusterSpec(in *v1beta1.ClusterSpec, out *ClusterSpec, s conversion.Scope) error { + out.Paused = in.Paused + out.ClusterNetwork = (*ClusterNetwork)(unsafe.Pointer(in.ClusterNetwork)) + if err := Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(&in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint, s); err != nil { + return err + } + out.ControlPlaneRef = (*v1.ObjectReference)(unsafe.Pointer(in.ControlPlaneRef)) + out.InfrastructureRef = (*v1.ObjectReference)(unsafe.Pointer(in.InfrastructureRef)) + // WARNING: in.Topology requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_ClusterStatus_To_v1beta1_ClusterStatus(in *ClusterStatus, out *v1beta1.ClusterStatus, s conversion.Scope) error { + out.FailureDomains = *(*v1beta1.FailureDomains)(unsafe.Pointer(&in.FailureDomains)) + out.FailureReason = (*errors.ClusterStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Phase = in.Phase + out.InfrastructureReady = in.InfrastructureReady + // WARNING: in.ControlPlaneInitialized requires manual conversion: does not exist in peer-type + out.ControlPlaneReady = in.ControlPlaneReady + out.Conditions = *(*v1beta1.Conditions)(unsafe.Pointer(&in.Conditions)) + out.ObservedGeneration = in.ObservedGeneration + return nil +} + +func autoConvert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus(in *v1beta1.ClusterStatus, out *ClusterStatus, s conversion.Scope) error { + out.FailureDomains = *(*FailureDomains)(unsafe.Pointer(&in.FailureDomains)) + out.FailureReason = (*errors.ClusterStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Phase = in.Phase + out.InfrastructureReady = in.InfrastructureReady + out.ControlPlaneReady = in.ControlPlaneReady + out.Conditions = *(*Conditions)(unsafe.Pointer(&in.Conditions)) + out.ObservedGeneration = in.ObservedGeneration + return nil +} + +// Convert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus is an autogenerated conversion function. +func Convert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus(in *v1beta1.ClusterStatus, out *ClusterStatus, s conversion.Scope) error { + return autoConvert_v1beta1_ClusterStatus_To_v1alpha3_ClusterStatus(in, out, s) +} + +func autoConvert_v1alpha3_Condition_To_v1beta1_Condition(in *Condition, out *v1beta1.Condition, s conversion.Scope) error { + out.Type = v1beta1.ConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + out.Severity = v1beta1.ConditionSeverity(in.Severity) + out.LastTransitionTime = in.LastTransitionTime + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +// Convert_v1alpha3_Condition_To_v1beta1_Condition is an autogenerated conversion function. +func Convert_v1alpha3_Condition_To_v1beta1_Condition(in *Condition, out *v1beta1.Condition, s conversion.Scope) error { + return autoConvert_v1alpha3_Condition_To_v1beta1_Condition(in, out, s) +} + +func autoConvert_v1beta1_Condition_To_v1alpha3_Condition(in *v1beta1.Condition, out *Condition, s conversion.Scope) error { + out.Type = ConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + out.Severity = ConditionSeverity(in.Severity) + out.LastTransitionTime = in.LastTransitionTime + out.Reason = in.Reason + out.Message = in.Message + return nil +} + +// Convert_v1beta1_Condition_To_v1alpha3_Condition is an autogenerated conversion function. +func Convert_v1beta1_Condition_To_v1alpha3_Condition(in *v1beta1.Condition, out *Condition, s conversion.Scope) error { + return autoConvert_v1beta1_Condition_To_v1alpha3_Condition(in, out, s) +} + +func autoConvert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(in *FailureDomainSpec, out *v1beta1.FailureDomainSpec, s conversion.Scope) error { + out.ControlPlane = in.ControlPlane + out.Attributes = *(*map[string]string)(unsafe.Pointer(&in.Attributes)) + return nil +} + +// Convert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec is an autogenerated conversion function. +func Convert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(in *FailureDomainSpec, out *v1beta1.FailureDomainSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(in, out, s) +} + +func autoConvert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(in *v1beta1.FailureDomainSpec, out *FailureDomainSpec, s conversion.Scope) error { + out.ControlPlane = in.ControlPlane + out.Attributes = *(*map[string]string)(unsafe.Pointer(&in.Attributes)) + return nil +} + +// Convert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec is an autogenerated conversion function. +func Convert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(in *v1beta1.FailureDomainSpec, out *FailureDomainSpec, s conversion.Scope) error { + return autoConvert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(in, out, s) +} + +func autoConvert_v1alpha3_Machine_To_v1beta1_Machine(in *Machine, out *v1beta1.Machine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachineStatus_To_v1beta1_MachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_Machine_To_v1beta1_Machine is an autogenerated conversion function. +func Convert_v1alpha3_Machine_To_v1beta1_Machine(in *Machine, out *v1beta1.Machine, s conversion.Scope) error { + return autoConvert_v1alpha3_Machine_To_v1beta1_Machine(in, out, s) +} + +func autoConvert_v1beta1_Machine_To_v1alpha3_Machine(in *v1beta1.Machine, out *Machine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_MachineStatus_To_v1alpha3_MachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_Machine_To_v1alpha3_Machine is an autogenerated conversion function. +func Convert_v1beta1_Machine_To_v1alpha3_Machine(in *v1beta1.Machine, out *Machine, s conversion.Scope) error { + return autoConvert_v1beta1_Machine_To_v1alpha3_Machine(in, out, s) +} + +func autoConvert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(in *MachineAddress, out *v1beta1.MachineAddress, s conversion.Scope) error { + out.Type = v1beta1.MachineAddressType(in.Type) + out.Address = in.Address + return nil +} + +// Convert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress is an autogenerated conversion function. +func Convert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(in *MachineAddress, out *v1beta1.MachineAddress, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(in, out, s) +} + +func autoConvert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(in *v1beta1.MachineAddress, out *MachineAddress, s conversion.Scope) error { + out.Type = MachineAddressType(in.Type) + out.Address = in.Address + return nil +} + +// Convert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress is an autogenerated conversion function. +func Convert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(in *v1beta1.MachineAddress, out *MachineAddress, s conversion.Scope) error { + return autoConvert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(in, out, s) +} + +func autoConvert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(in *MachineDeployment, out *v1beta1.MachineDeployment, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment is an autogenerated conversion function. +func Convert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(in *MachineDeployment, out *v1beta1.MachineDeployment, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(in, out, s) +} + +func autoConvert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(in *v1beta1.MachineDeployment, out *MachineDeployment, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_MachineDeploymentStatus_To_v1alpha3_MachineDeploymentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment is an autogenerated conversion function. +func Convert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(in *v1beta1.MachineDeployment, out *MachineDeployment, s conversion.Scope) error { + return autoConvert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(in, out, s) +} + +func autoConvert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList(in *MachineDeploymentList, out *v1beta1.MachineDeploymentList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.MachineDeployment, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_MachineDeployment_To_v1beta1_MachineDeployment(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList is an autogenerated conversion function. +func Convert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList(in *MachineDeploymentList, out *v1beta1.MachineDeploymentList, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineDeploymentList_To_v1beta1_MachineDeploymentList(in, out, s) +} + +func autoConvert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList(in *v1beta1.MachineDeploymentList, out *MachineDeploymentList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineDeployment, len(*in)) + for i := range *in { + if err := Convert_v1beta1_MachineDeployment_To_v1alpha3_MachineDeployment(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList is an autogenerated conversion function. +func Convert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList(in *v1beta1.MachineDeploymentList, out *MachineDeploymentList, s conversion.Scope) error { + return autoConvert_v1beta1_MachineDeploymentList_To_v1alpha3_MachineDeploymentList(in, out, s) +} + +func autoConvert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec(in *MachineDeploymentSpec, out *v1beta1.MachineDeploymentSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.Selector = in.Selector + if err := Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(v1beta1.MachineDeploymentStrategy) + if err := Convert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy(*in, *out, s); err != nil { + return err + } + } else { + out.Strategy = nil + } + out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) + out.Paused = in.Paused + out.ProgressDeadlineSeconds = (*int32)(unsafe.Pointer(in.ProgressDeadlineSeconds)) + return nil +} + +// Convert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec(in *MachineDeploymentSpec, out *v1beta1.MachineDeploymentSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineDeploymentSpec_To_v1beta1_MachineDeploymentSpec(in, out, s) +} + +func autoConvert_v1beta1_MachineDeploymentSpec_To_v1alpha3_MachineDeploymentSpec(in *v1beta1.MachineDeploymentSpec, out *MachineDeploymentSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + // WARNING: in.RolloutAfter requires manual conversion: does not exist in peer-type + out.Selector = in.Selector + if err := Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(MachineDeploymentStrategy) + if err := Convert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy(*in, *out, s); err != nil { + return err + } + } else { + out.Strategy = nil + } + out.MinReadySeconds = (*int32)(unsafe.Pointer(in.MinReadySeconds)) + out.RevisionHistoryLimit = (*int32)(unsafe.Pointer(in.RevisionHistoryLimit)) + out.Paused = in.Paused + out.ProgressDeadlineSeconds = (*int32)(unsafe.Pointer(in.ProgressDeadlineSeconds)) + return nil +} + +func autoConvert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus(in *MachineDeploymentStatus, out *v1beta1.MachineDeploymentStatus, s conversion.Scope) error { + out.ObservedGeneration = in.ObservedGeneration + out.Selector = in.Selector + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.Phase = in.Phase + return nil +} + +// Convert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus is an autogenerated conversion function. +func Convert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus(in *MachineDeploymentStatus, out *v1beta1.MachineDeploymentStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineDeploymentStatus_To_v1beta1_MachineDeploymentStatus(in, out, s) +} + +func autoConvert_v1beta1_MachineDeploymentStatus_To_v1alpha3_MachineDeploymentStatus(in *v1beta1.MachineDeploymentStatus, out *MachineDeploymentStatus, s conversion.Scope) error { + out.ObservedGeneration = in.ObservedGeneration + out.Selector = in.Selector + out.Replicas = in.Replicas + out.UpdatedReplicas = in.UpdatedReplicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.UnavailableReplicas = in.UnavailableReplicas + out.Phase = in.Phase + // WARNING: in.Conditions requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy(in *MachineDeploymentStrategy, out *v1beta1.MachineDeploymentStrategy, s conversion.Scope) error { + out.Type = v1beta1.MachineDeploymentStrategyType(in.Type) + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(v1beta1.MachineRollingUpdateDeployment) + if err := Convert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment(*in, *out, s); err != nil { + return err + } + } else { + out.RollingUpdate = nil + } + return nil +} + +// Convert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy is an autogenerated conversion function. +func Convert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy(in *MachineDeploymentStrategy, out *v1beta1.MachineDeploymentStrategy, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineDeploymentStrategy_To_v1beta1_MachineDeploymentStrategy(in, out, s) +} + +func autoConvert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy(in *v1beta1.MachineDeploymentStrategy, out *MachineDeploymentStrategy, s conversion.Scope) error { + out.Type = MachineDeploymentStrategyType(in.Type) + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(MachineRollingUpdateDeployment) + if err := Convert_v1beta1_MachineRollingUpdateDeployment_To_v1alpha3_MachineRollingUpdateDeployment(*in, *out, s); err != nil { + return err + } + } else { + out.RollingUpdate = nil + } + return nil +} + +// Convert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy is an autogenerated conversion function. +func Convert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy(in *v1beta1.MachineDeploymentStrategy, out *MachineDeploymentStrategy, s conversion.Scope) error { + return autoConvert_v1beta1_MachineDeploymentStrategy_To_v1alpha3_MachineDeploymentStrategy(in, out, s) +} + +func autoConvert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(in *MachineHealthCheck, out *v1beta1.MachineHealthCheck, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck is an autogenerated conversion function. +func Convert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(in *MachineHealthCheck, out *v1beta1.MachineHealthCheck, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(in, out, s) +} + +func autoConvert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(in *v1beta1.MachineHealthCheck, out *MachineHealthCheck, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_MachineHealthCheckSpec_To_v1alpha3_MachineHealthCheckSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck is an autogenerated conversion function. +func Convert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(in *v1beta1.MachineHealthCheck, out *MachineHealthCheck, s conversion.Scope) error { + return autoConvert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(in, out, s) +} + +func autoConvert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList(in *MachineHealthCheckList, out *v1beta1.MachineHealthCheckList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.MachineHealthCheck, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_MachineHealthCheck_To_v1beta1_MachineHealthCheck(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList is an autogenerated conversion function. +func Convert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList(in *MachineHealthCheckList, out *v1beta1.MachineHealthCheckList, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineHealthCheckList_To_v1beta1_MachineHealthCheckList(in, out, s) +} + +func autoConvert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList(in *v1beta1.MachineHealthCheckList, out *MachineHealthCheckList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineHealthCheck, len(*in)) + for i := range *in { + if err := Convert_v1beta1_MachineHealthCheck_To_v1alpha3_MachineHealthCheck(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList is an autogenerated conversion function. +func Convert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList(in *v1beta1.MachineHealthCheckList, out *MachineHealthCheckList, s conversion.Scope) error { + return autoConvert_v1beta1_MachineHealthCheckList_To_v1alpha3_MachineHealthCheckList(in, out, s) +} + +func autoConvert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec(in *MachineHealthCheckSpec, out *v1beta1.MachineHealthCheckSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Selector = in.Selector + out.UnhealthyConditions = *(*[]v1beta1.UnhealthyCondition)(unsafe.Pointer(&in.UnhealthyConditions)) + out.MaxUnhealthy = (*intstr.IntOrString)(unsafe.Pointer(in.MaxUnhealthy)) + out.NodeStartupTimeout = (*metav1.Duration)(unsafe.Pointer(in.NodeStartupTimeout)) + out.RemediationTemplate = (*v1.ObjectReference)(unsafe.Pointer(in.RemediationTemplate)) + return nil +} + +// Convert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec(in *MachineHealthCheckSpec, out *v1beta1.MachineHealthCheckSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineHealthCheckSpec_To_v1beta1_MachineHealthCheckSpec(in, out, s) +} + +func autoConvert_v1beta1_MachineHealthCheckSpec_To_v1alpha3_MachineHealthCheckSpec(in *v1beta1.MachineHealthCheckSpec, out *MachineHealthCheckSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Selector = in.Selector + out.UnhealthyConditions = *(*[]UnhealthyCondition)(unsafe.Pointer(&in.UnhealthyConditions)) + out.MaxUnhealthy = (*intstr.IntOrString)(unsafe.Pointer(in.MaxUnhealthy)) + // WARNING: in.UnhealthyRange requires manual conversion: does not exist in peer-type + out.NodeStartupTimeout = (*metav1.Duration)(unsafe.Pointer(in.NodeStartupTimeout)) + out.RemediationTemplate = (*v1.ObjectReference)(unsafe.Pointer(in.RemediationTemplate)) + return nil +} + +func autoConvert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus(in *MachineHealthCheckStatus, out *v1beta1.MachineHealthCheckStatus, s conversion.Scope) error { + out.ExpectedMachines = in.ExpectedMachines + out.CurrentHealthy = in.CurrentHealthy + out.RemediationsAllowed = in.RemediationsAllowed + out.ObservedGeneration = in.ObservedGeneration + out.Targets = *(*[]string)(unsafe.Pointer(&in.Targets)) + out.Conditions = *(*v1beta1.Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus is an autogenerated conversion function. +func Convert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus(in *MachineHealthCheckStatus, out *v1beta1.MachineHealthCheckStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineHealthCheckStatus_To_v1beta1_MachineHealthCheckStatus(in, out, s) +} + +func autoConvert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus(in *v1beta1.MachineHealthCheckStatus, out *MachineHealthCheckStatus, s conversion.Scope) error { + out.ExpectedMachines = in.ExpectedMachines + out.CurrentHealthy = in.CurrentHealthy + out.RemediationsAllowed = in.RemediationsAllowed + out.ObservedGeneration = in.ObservedGeneration + out.Targets = *(*[]string)(unsafe.Pointer(&in.Targets)) + out.Conditions = *(*Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus is an autogenerated conversion function. +func Convert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus(in *v1beta1.MachineHealthCheckStatus, out *MachineHealthCheckStatus, s conversion.Scope) error { + return autoConvert_v1beta1_MachineHealthCheckStatus_To_v1alpha3_MachineHealthCheckStatus(in, out, s) +} + +func autoConvert_v1alpha3_MachineList_To_v1beta1_MachineList(in *MachineList, out *v1beta1.MachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.Machine, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_Machine_To_v1beta1_Machine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_MachineList_To_v1beta1_MachineList is an autogenerated conversion function. +func Convert_v1alpha3_MachineList_To_v1beta1_MachineList(in *MachineList, out *v1beta1.MachineList, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineList_To_v1beta1_MachineList(in, out, s) +} + +func autoConvert_v1beta1_MachineList_To_v1alpha3_MachineList(in *v1beta1.MachineList, out *MachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Machine, len(*in)) + for i := range *in { + if err := Convert_v1beta1_Machine_To_v1alpha3_Machine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_MachineList_To_v1alpha3_MachineList is an autogenerated conversion function. +func Convert_v1beta1_MachineList_To_v1alpha3_MachineList(in *v1beta1.MachineList, out *MachineList, s conversion.Scope) error { + return autoConvert_v1beta1_MachineList_To_v1alpha3_MachineList(in, out, s) +} + +func autoConvert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment(in *MachineRollingUpdateDeployment, out *v1beta1.MachineRollingUpdateDeployment, s conversion.Scope) error { + out.MaxUnavailable = (*intstr.IntOrString)(unsafe.Pointer(in.MaxUnavailable)) + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + return nil +} + +// Convert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment is an autogenerated conversion function. +func Convert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment(in *MachineRollingUpdateDeployment, out *v1beta1.MachineRollingUpdateDeployment, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineRollingUpdateDeployment_To_v1beta1_MachineRollingUpdateDeployment(in, out, s) +} + +func autoConvert_v1beta1_MachineRollingUpdateDeployment_To_v1alpha3_MachineRollingUpdateDeployment(in *v1beta1.MachineRollingUpdateDeployment, out *MachineRollingUpdateDeployment, s conversion.Scope) error { + out.MaxUnavailable = (*intstr.IntOrString)(unsafe.Pointer(in.MaxUnavailable)) + out.MaxSurge = (*intstr.IntOrString)(unsafe.Pointer(in.MaxSurge)) + // WARNING: in.DeletePolicy requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_MachineSet_To_v1beta1_MachineSet(in *MachineSet, out *v1beta1.MachineSet, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_MachineSet_To_v1beta1_MachineSet is an autogenerated conversion function. +func Convert_v1alpha3_MachineSet_To_v1beta1_MachineSet(in *MachineSet, out *v1beta1.MachineSet, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineSet_To_v1beta1_MachineSet(in, out, s) +} + +func autoConvert_v1beta1_MachineSet_To_v1alpha3_MachineSet(in *v1beta1.MachineSet, out *MachineSet, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_MachineSetStatus_To_v1alpha3_MachineSetStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_MachineSet_To_v1alpha3_MachineSet is an autogenerated conversion function. +func Convert_v1beta1_MachineSet_To_v1alpha3_MachineSet(in *v1beta1.MachineSet, out *MachineSet, s conversion.Scope) error { + return autoConvert_v1beta1_MachineSet_To_v1alpha3_MachineSet(in, out, s) +} + +func autoConvert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList(in *MachineSetList, out *v1beta1.MachineSetList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.MachineSet, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_MachineSet_To_v1beta1_MachineSet(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList is an autogenerated conversion function. +func Convert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList(in *MachineSetList, out *v1beta1.MachineSetList, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineSetList_To_v1beta1_MachineSetList(in, out, s) +} + +func autoConvert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList(in *v1beta1.MachineSetList, out *MachineSetList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineSet, len(*in)) + for i := range *in { + if err := Convert_v1beta1_MachineSet_To_v1alpha3_MachineSet(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList is an autogenerated conversion function. +func Convert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList(in *v1beta1.MachineSetList, out *MachineSetList, s conversion.Scope) error { + return autoConvert_v1beta1_MachineSetList_To_v1alpha3_MachineSetList(in, out, s) +} + +func autoConvert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec(in *MachineSetSpec, out *v1beta1.MachineSetSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.MinReadySeconds = in.MinReadySeconds + out.DeletePolicy = in.DeletePolicy + out.Selector = in.Selector + if err := Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec(in *MachineSetSpec, out *v1beta1.MachineSetSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineSetSpec_To_v1beta1_MachineSetSpec(in, out, s) +} + +func autoConvert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec(in *v1beta1.MachineSetSpec, out *MachineSetSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.MinReadySeconds = in.MinReadySeconds + out.DeletePolicy = in.DeletePolicy + out.Selector = in.Selector + if err := Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec is an autogenerated conversion function. +func Convert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec(in *v1beta1.MachineSetSpec, out *MachineSetSpec, s conversion.Scope) error { + return autoConvert_v1beta1_MachineSetSpec_To_v1alpha3_MachineSetSpec(in, out, s) +} + +func autoConvert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus(in *MachineSetStatus, out *v1beta1.MachineSetStatus, s conversion.Scope) error { + out.Selector = in.Selector + out.Replicas = in.Replicas + out.FullyLabeledReplicas = in.FullyLabeledReplicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.ObservedGeneration = in.ObservedGeneration + out.FailureReason = (*errors.MachineSetStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + return nil +} + +// Convert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus is an autogenerated conversion function. +func Convert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus(in *MachineSetStatus, out *v1beta1.MachineSetStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineSetStatus_To_v1beta1_MachineSetStatus(in, out, s) +} + +func autoConvert_v1beta1_MachineSetStatus_To_v1alpha3_MachineSetStatus(in *v1beta1.MachineSetStatus, out *MachineSetStatus, s conversion.Scope) error { + out.Selector = in.Selector + out.Replicas = in.Replicas + out.FullyLabeledReplicas = in.FullyLabeledReplicas + out.ReadyReplicas = in.ReadyReplicas + out.AvailableReplicas = in.AvailableReplicas + out.ObservedGeneration = in.ObservedGeneration + out.FailureReason = (*errors.MachineSetStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + // WARNING: in.Conditions requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(in *MachineSpec, out *v1beta1.MachineSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + if err := Convert_v1alpha3_Bootstrap_To_v1beta1_Bootstrap(&in.Bootstrap, &out.Bootstrap, s); err != nil { + return err + } + out.InfrastructureRef = in.InfrastructureRef + out.Version = (*string)(unsafe.Pointer(in.Version)) + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.FailureDomain = (*string)(unsafe.Pointer(in.FailureDomain)) + out.NodeDrainTimeout = (*metav1.Duration)(unsafe.Pointer(in.NodeDrainTimeout)) + return nil +} + +// Convert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(in *MachineSpec, out *v1beta1.MachineSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(in, out, s) +} + +func autoConvert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(in *v1beta1.MachineSpec, out *MachineSpec, s conversion.Scope) error { + out.ClusterName = in.ClusterName + if err := Convert_v1beta1_Bootstrap_To_v1alpha3_Bootstrap(&in.Bootstrap, &out.Bootstrap, s); err != nil { + return err + } + out.InfrastructureRef = in.InfrastructureRef + out.Version = (*string)(unsafe.Pointer(in.Version)) + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.FailureDomain = (*string)(unsafe.Pointer(in.FailureDomain)) + out.NodeDrainTimeout = (*metav1.Duration)(unsafe.Pointer(in.NodeDrainTimeout)) + // WARNING: in.NodeVolumeDetachTimeout requires manual conversion: does not exist in peer-type + // WARNING: in.NodeDeletionTimeout requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_MachineStatus_To_v1beta1_MachineStatus(in *MachineStatus, out *v1beta1.MachineStatus, s conversion.Scope) error { + out.NodeRef = (*v1.ObjectReference)(unsafe.Pointer(in.NodeRef)) + out.LastUpdated = (*metav1.Time)(unsafe.Pointer(in.LastUpdated)) + // WARNING: in.Version requires manual conversion: does not exist in peer-type + out.FailureReason = (*errors.MachineStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Addresses = *(*v1beta1.MachineAddresses)(unsafe.Pointer(&in.Addresses)) + out.Phase = in.Phase + out.BootstrapReady = in.BootstrapReady + out.InfrastructureReady = in.InfrastructureReady + out.ObservedGeneration = in.ObservedGeneration + out.Conditions = *(*v1beta1.Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +func autoConvert_v1beta1_MachineStatus_To_v1alpha3_MachineStatus(in *v1beta1.MachineStatus, out *MachineStatus, s conversion.Scope) error { + out.NodeRef = (*v1.ObjectReference)(unsafe.Pointer(in.NodeRef)) + // WARNING: in.NodeInfo requires manual conversion: does not exist in peer-type + out.LastUpdated = (*metav1.Time)(unsafe.Pointer(in.LastUpdated)) + out.FailureReason = (*errors.MachineStatusError)(unsafe.Pointer(in.FailureReason)) + out.FailureMessage = (*string)(unsafe.Pointer(in.FailureMessage)) + out.Addresses = *(*MachineAddresses)(unsafe.Pointer(&in.Addresses)) + out.Phase = in.Phase + // WARNING: in.CertificatesExpiryDate requires manual conversion: does not exist in peer-type + out.BootstrapReady = in.BootstrapReady + out.InfrastructureReady = in.InfrastructureReady + out.ObservedGeneration = in.ObservedGeneration + out.Conditions = *(*Conditions)(unsafe.Pointer(&in.Conditions)) + return nil +} + +func autoConvert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(in *MachineTemplateSpec, out *v1beta1.MachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1alpha3_ObjectMeta_To_v1beta1_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := Convert_v1alpha3_MachineSpec_To_v1beta1_MachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec is an autogenerated conversion function. +func Convert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(in *MachineTemplateSpec, out *v1beta1.MachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_MachineTemplateSpec_To_v1beta1_MachineTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(in *v1beta1.MachineTemplateSpec, out *MachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta(&in.ObjectMeta, &out.ObjectMeta, s); err != nil { + return err + } + if err := Convert_v1beta1_MachineSpec_To_v1alpha3_MachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(in *v1beta1.MachineTemplateSpec, out *MachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_MachineTemplateSpec_To_v1alpha3_MachineTemplateSpec(in, out, s) +} + +func autoConvert_v1alpha3_NetworkRanges_To_v1beta1_NetworkRanges(in *NetworkRanges, out *v1beta1.NetworkRanges, s conversion.Scope) error { + out.CIDRBlocks = *(*[]string)(unsafe.Pointer(&in.CIDRBlocks)) + return nil +} + +// Convert_v1alpha3_NetworkRanges_To_v1beta1_NetworkRanges is an autogenerated conversion function. +func Convert_v1alpha3_NetworkRanges_To_v1beta1_NetworkRanges(in *NetworkRanges, out *v1beta1.NetworkRanges, s conversion.Scope) error { + return autoConvert_v1alpha3_NetworkRanges_To_v1beta1_NetworkRanges(in, out, s) +} + +func autoConvert_v1beta1_NetworkRanges_To_v1alpha3_NetworkRanges(in *v1beta1.NetworkRanges, out *NetworkRanges, s conversion.Scope) error { + out.CIDRBlocks = *(*[]string)(unsafe.Pointer(&in.CIDRBlocks)) + return nil +} + +// Convert_v1beta1_NetworkRanges_To_v1alpha3_NetworkRanges is an autogenerated conversion function. +func Convert_v1beta1_NetworkRanges_To_v1alpha3_NetworkRanges(in *v1beta1.NetworkRanges, out *NetworkRanges, s conversion.Scope) error { + return autoConvert_v1beta1_NetworkRanges_To_v1alpha3_NetworkRanges(in, out, s) +} + +func autoConvert_v1alpha3_ObjectMeta_To_v1beta1_ObjectMeta(in *ObjectMeta, out *v1beta1.ObjectMeta, s conversion.Scope) error { + // WARNING: in.Name requires manual conversion: does not exist in peer-type + // WARNING: in.GenerateName requires manual conversion: does not exist in peer-type + // WARNING: in.Namespace requires manual conversion: does not exist in peer-type + out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels)) + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + // WARNING: in.OwnerReferences requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta(in *v1beta1.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { + out.Labels = *(*map[string]string)(unsafe.Pointer(&in.Labels)) + out.Annotations = *(*map[string]string)(unsafe.Pointer(&in.Annotations)) + return nil +} + +// Convert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta is an autogenerated conversion function. +func Convert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta(in *v1beta1.ObjectMeta, out *ObjectMeta, s conversion.Scope) error { + return autoConvert_v1beta1_ObjectMeta_To_v1alpha3_ObjectMeta(in, out, s) +} + +func autoConvert_v1alpha3_UnhealthyCondition_To_v1beta1_UnhealthyCondition(in *UnhealthyCondition, out *v1beta1.UnhealthyCondition, s conversion.Scope) error { + out.Type = v1.NodeConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + out.Timeout = in.Timeout + return nil +} + +// Convert_v1alpha3_UnhealthyCondition_To_v1beta1_UnhealthyCondition is an autogenerated conversion function. +func Convert_v1alpha3_UnhealthyCondition_To_v1beta1_UnhealthyCondition(in *UnhealthyCondition, out *v1beta1.UnhealthyCondition, s conversion.Scope) error { + return autoConvert_v1alpha3_UnhealthyCondition_To_v1beta1_UnhealthyCondition(in, out, s) +} + +func autoConvert_v1beta1_UnhealthyCondition_To_v1alpha3_UnhealthyCondition(in *v1beta1.UnhealthyCondition, out *UnhealthyCondition, s conversion.Scope) error { + out.Type = v1.NodeConditionType(in.Type) + out.Status = v1.ConditionStatus(in.Status) + out.Timeout = in.Timeout + return nil +} + +// Convert_v1beta1_UnhealthyCondition_To_v1alpha3_UnhealthyCondition is an autogenerated conversion function. +func Convert_v1beta1_UnhealthyCondition_To_v1alpha3_UnhealthyCondition(in *v1beta1.UnhealthyCondition, out *UnhealthyCondition, s conversion.Scope) error { + return autoConvert_v1beta1_UnhealthyCondition_To_v1alpha3_UnhealthyCondition(in, out, s) +} diff --git a/internal/apis/core/v1alpha3/zz_generated.deepcopy.go b/internal/apis/core/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..cd302706b1d0 --- /dev/null +++ b/internal/apis/core/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,972 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/cluster-api/errors" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIEndpoint) DeepCopyInto(out *APIEndpoint) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIEndpoint. +func (in *APIEndpoint) DeepCopy() *APIEndpoint { + if in == nil { + return nil + } + out := new(APIEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Bootstrap) DeepCopyInto(out *Bootstrap) { + *out = *in + if in.ConfigRef != nil { + in, out := &in.ConfigRef, &out.ConfigRef + *out = new(v1.ObjectReference) + **out = **in + } + if in.Data != nil { + in, out := &in.Data, &out.Data + *out = new(string) + **out = **in + } + if in.DataSecretName != nil { + in, out := &in.DataSecretName, &out.DataSecretName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bootstrap. +func (in *Bootstrap) DeepCopy() *Bootstrap { + if in == nil { + return nil + } + out := new(Bootstrap) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Cluster) DeepCopyInto(out *Cluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. +func (in *Cluster) DeepCopy() *Cluster { + if in == nil { + return nil + } + out := new(Cluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Cluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterList) DeepCopyInto(out *ClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Cluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList. +func (in *ClusterList) DeepCopy() *ClusterList { + if in == nil { + return nil + } + out := new(ClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterNetwork) DeepCopyInto(out *ClusterNetwork) { + *out = *in + if in.APIServerPort != nil { + in, out := &in.APIServerPort, &out.APIServerPort + *out = new(int32) + **out = **in + } + if in.Services != nil { + in, out := &in.Services, &out.Services + *out = new(NetworkRanges) + (*in).DeepCopyInto(*out) + } + if in.Pods != nil { + in, out := &in.Pods, &out.Pods + *out = new(NetworkRanges) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterNetwork. +func (in *ClusterNetwork) DeepCopy() *ClusterNetwork { + if in == nil { + return nil + } + out := new(ClusterNetwork) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) { + *out = *in + if in.ClusterNetwork != nil { + in, out := &in.ClusterNetwork, &out.ClusterNetwork + *out = new(ClusterNetwork) + (*in).DeepCopyInto(*out) + } + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint + if in.ControlPlaneRef != nil { + in, out := &in.ControlPlaneRef, &out.ControlPlaneRef + *out = new(v1.ObjectReference) + **out = **in + } + if in.InfrastructureRef != nil { + in, out := &in.InfrastructureRef, &out.InfrastructureRef + *out = new(v1.ObjectReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec. +func (in *ClusterSpec) DeepCopy() *ClusterSpec { + if in == nil { + return nil + } + out := new(ClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) { + *out = *in + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(FailureDomains, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.ClusterStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus. +func (in *ClusterStatus) DeepCopy() *ClusterStatus { + if in == nil { + return nil + } + out := new(ClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Conditions) DeepCopyInto(out *Conditions) { + { + in := &in + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Conditions. +func (in Conditions) DeepCopy() Conditions { + if in == nil { + return nil + } + out := new(Conditions) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *FailureDomainSpec) DeepCopyInto(out *FailureDomainSpec) { + *out = *in + if in.Attributes != nil { + in, out := &in.Attributes, &out.Attributes + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailureDomainSpec. +func (in *FailureDomainSpec) DeepCopy() *FailureDomainSpec { + if in == nil { + return nil + } + out := new(FailureDomainSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in FailureDomains) DeepCopyInto(out *FailureDomains) { + { + in := &in + *out = make(FailureDomains, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailureDomains. +func (in FailureDomains) DeepCopy() FailureDomains { + if in == nil { + return nil + } + out := new(FailureDomains) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Machine) DeepCopyInto(out *Machine) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Machine. +func (in *Machine) DeepCopy() *Machine { + if in == nil { + return nil + } + out := new(Machine) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Machine) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineAddress) DeepCopyInto(out *MachineAddress) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineAddress. +func (in *MachineAddress) DeepCopy() *MachineAddress { + if in == nil { + return nil + } + out := new(MachineAddress) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in MachineAddresses) DeepCopyInto(out *MachineAddresses) { + { + in := &in + *out = make(MachineAddresses, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineAddresses. +func (in MachineAddresses) DeepCopy() MachineAddresses { + if in == nil { + return nil + } + out := new(MachineAddresses) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDeployment) DeepCopyInto(out *MachineDeployment) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeployment. +func (in *MachineDeployment) DeepCopy() *MachineDeployment { + if in == nil { + return nil + } + out := new(MachineDeployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineDeployment) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDeploymentList) DeepCopyInto(out *MachineDeploymentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineDeployment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentList. +func (in *MachineDeploymentList) DeepCopy() *MachineDeploymentList { + if in == nil { + return nil + } + out := new(MachineDeploymentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineDeploymentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDeploymentSpec) DeepCopyInto(out *MachineDeploymentSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Selector.DeepCopyInto(&out.Selector) + in.Template.DeepCopyInto(&out.Template) + if in.Strategy != nil { + in, out := &in.Strategy, &out.Strategy + *out = new(MachineDeploymentStrategy) + (*in).DeepCopyInto(*out) + } + if in.MinReadySeconds != nil { + in, out := &in.MinReadySeconds, &out.MinReadySeconds + *out = new(int32) + **out = **in + } + if in.RevisionHistoryLimit != nil { + in, out := &in.RevisionHistoryLimit, &out.RevisionHistoryLimit + *out = new(int32) + **out = **in + } + if in.ProgressDeadlineSeconds != nil { + in, out := &in.ProgressDeadlineSeconds, &out.ProgressDeadlineSeconds + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentSpec. +func (in *MachineDeploymentSpec) DeepCopy() *MachineDeploymentSpec { + if in == nil { + return nil + } + out := new(MachineDeploymentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDeploymentStatus) DeepCopyInto(out *MachineDeploymentStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentStatus. +func (in *MachineDeploymentStatus) DeepCopy() *MachineDeploymentStatus { + if in == nil { + return nil + } + out := new(MachineDeploymentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineDeploymentStrategy) DeepCopyInto(out *MachineDeploymentStrategy) { + *out = *in + if in.RollingUpdate != nil { + in, out := &in.RollingUpdate, &out.RollingUpdate + *out = new(MachineRollingUpdateDeployment) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineDeploymentStrategy. +func (in *MachineDeploymentStrategy) DeepCopy() *MachineDeploymentStrategy { + if in == nil { + return nil + } + out := new(MachineDeploymentStrategy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheck) DeepCopyInto(out *MachineHealthCheck) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheck. +func (in *MachineHealthCheck) DeepCopy() *MachineHealthCheck { + if in == nil { + return nil + } + out := new(MachineHealthCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineHealthCheck) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheckList) DeepCopyInto(out *MachineHealthCheckList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineHealthCheck, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckList. +func (in *MachineHealthCheckList) DeepCopy() *MachineHealthCheckList { + if in == nil { + return nil + } + out := new(MachineHealthCheckList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineHealthCheckList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheckSpec) DeepCopyInto(out *MachineHealthCheckSpec) { + *out = *in + in.Selector.DeepCopyInto(&out.Selector) + if in.UnhealthyConditions != nil { + in, out := &in.UnhealthyConditions, &out.UnhealthyConditions + *out = make([]UnhealthyCondition, len(*in)) + copy(*out, *in) + } + if in.MaxUnhealthy != nil { + in, out := &in.MaxUnhealthy, &out.MaxUnhealthy + *out = new(intstr.IntOrString) + **out = **in + } + if in.NodeStartupTimeout != nil { + in, out := &in.NodeStartupTimeout, &out.NodeStartupTimeout + *out = new(metav1.Duration) + **out = **in + } + if in.RemediationTemplate != nil { + in, out := &in.RemediationTemplate, &out.RemediationTemplate + *out = new(v1.ObjectReference) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckSpec. +func (in *MachineHealthCheckSpec) DeepCopy() *MachineHealthCheckSpec { + if in == nil { + return nil + } + out := new(MachineHealthCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineHealthCheckStatus) DeepCopyInto(out *MachineHealthCheckStatus) { + *out = *in + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineHealthCheckStatus. +func (in *MachineHealthCheckStatus) DeepCopy() *MachineHealthCheckStatus { + if in == nil { + return nil + } + out := new(MachineHealthCheckStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineList) DeepCopyInto(out *MachineList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Machine, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineList. +func (in *MachineList) DeepCopy() *MachineList { + if in == nil { + return nil + } + out := new(MachineList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineRollingUpdateDeployment) DeepCopyInto(out *MachineRollingUpdateDeployment) { + *out = *in + if in.MaxUnavailable != nil { + in, out := &in.MaxUnavailable, &out.MaxUnavailable + *out = new(intstr.IntOrString) + **out = **in + } + if in.MaxSurge != nil { + in, out := &in.MaxSurge, &out.MaxSurge + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineRollingUpdateDeployment. +func (in *MachineRollingUpdateDeployment) DeepCopy() *MachineRollingUpdateDeployment { + if in == nil { + return nil + } + out := new(MachineRollingUpdateDeployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineSet) DeepCopyInto(out *MachineSet) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSet. +func (in *MachineSet) DeepCopy() *MachineSet { + if in == nil { + return nil + } + out := new(MachineSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineSet) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineSetList) DeepCopyInto(out *MachineSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]MachineSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetList. +func (in *MachineSetList) DeepCopy() *MachineSetList { + if in == nil { + return nil + } + out := new(MachineSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *MachineSetList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineSetSpec) DeepCopyInto(out *MachineSetSpec) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Selector.DeepCopyInto(&out.Selector) + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetSpec. +func (in *MachineSetSpec) DeepCopy() *MachineSetSpec { + if in == nil { + return nil + } + out := new(MachineSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineSetStatus) DeepCopyInto(out *MachineSetStatus) { + *out = *in + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachineSetStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSetStatus. +func (in *MachineSetStatus) DeepCopy() *MachineSetStatus { + if in == nil { + return nil + } + out := new(MachineSetStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineSpec) DeepCopyInto(out *MachineSpec) { + *out = *in + in.Bootstrap.DeepCopyInto(&out.Bootstrap) + out.InfrastructureRef = in.InfrastructureRef + if in.Version != nil { + in, out := &in.Version, &out.Version + *out = new(string) + **out = **in + } + if in.ProviderID != nil { + in, out := &in.ProviderID, &out.ProviderID + *out = new(string) + **out = **in + } + if in.FailureDomain != nil { + in, out := &in.FailureDomain, &out.FailureDomain + *out = new(string) + **out = **in + } + if in.NodeDrainTimeout != nil { + in, out := &in.NodeDrainTimeout, &out.NodeDrainTimeout + *out = new(metav1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineSpec. +func (in *MachineSpec) DeepCopy() *MachineSpec { + if in == nil { + return nil + } + out := new(MachineSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineStatus) DeepCopyInto(out *MachineStatus) { + *out = *in + if in.NodeRef != nil { + in, out := &in.NodeRef, &out.NodeRef + *out = new(v1.ObjectReference) + **out = **in + } + if in.LastUpdated != nil { + in, out := &in.LastUpdated, &out.LastUpdated + *out = (*in).DeepCopy() + } + if in.Version != nil { + in, out := &in.Version, &out.Version + *out = new(string) + **out = **in + } + if in.FailureReason != nil { + in, out := &in.FailureReason, &out.FailureReason + *out = new(errors.MachineStatusError) + **out = **in + } + if in.FailureMessage != nil { + in, out := &in.FailureMessage, &out.FailureMessage + *out = new(string) + **out = **in + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make(MachineAddresses, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineStatus. +func (in *MachineStatus) DeepCopy() *MachineStatus { + if in == nil { + return nil + } + out := new(MachineStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MachineTemplateSpec) DeepCopyInto(out *MachineTemplateSpec) { + *out = *in + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineTemplateSpec. +func (in *MachineTemplateSpec) DeepCopy() *MachineTemplateSpec { + if in == nil { + return nil + } + out := new(MachineTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkRanges) DeepCopyInto(out *NetworkRanges) { + *out = *in + if in.CIDRBlocks != nil { + in, out := &in.CIDRBlocks, &out.CIDRBlocks + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkRanges. +func (in *NetworkRanges) DeepCopy() *NetworkRanges { + if in == nil { + return nil + } + out := new(NetworkRanges) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) { + *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.OwnerReferences != nil { + in, out := &in.OwnerReferences, &out.OwnerReferences + *out = make([]metav1.OwnerReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectMeta. +func (in *ObjectMeta) DeepCopy() *ObjectMeta { + if in == nil { + return nil + } + out := new(ObjectMeta) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UnhealthyCondition) DeepCopyInto(out *UnhealthyCondition) { + *out = *in + out.Timeout = in.Timeout +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnhealthyCondition. +func (in *UnhealthyCondition) DeepCopy() *UnhealthyCondition { + if in == nil { + return nil + } + out := new(UnhealthyCondition) + in.DeepCopyInto(out) + return out +} diff --git a/internal/runtime/test/v1alpha1/zz_generated.conversion.go b/internal/runtime/test/v1alpha1/zz_generated.conversion.go index 214fe03aabfd..aef1e44cfd37 100644 --- a/internal/runtime/test/v1alpha1/zz_generated.conversion.go +++ b/internal/runtime/test/v1alpha1/zz_generated.conversion.go @@ -1,5 +1,5 @@ -//go:build !ignore_autogenerated_runtime -// +build !ignore_autogenerated_runtime +//go:build !ignore_autogenerated_core_runtime +// +build !ignore_autogenerated_core_runtime /* Copyright The Kubernetes Authors. diff --git a/main.go b/main.go index 52a661f4f54d..ba99677b0b0e 100644 --- a/main.go +++ b/main.go @@ -65,6 +65,9 @@ import ( runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" expwebhooks "sigs.k8s.io/cluster-api/exp/webhooks" "sigs.k8s.io/cluster-api/feature" + addonsv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/exp/addons/v1alpha3" + expv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/exp/v1alpha3" + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" runtimeclient "sigs.k8s.io/cluster-api/internal/runtime/client" runtimeregistry "sigs.k8s.io/cluster-api/internal/runtime/registry" runtimewebhooks "sigs.k8s.io/cluster-api/internal/webhooks/runtime" @@ -116,12 +119,15 @@ func init() { _ = clientgoscheme.AddToScheme(scheme) _ = apiextensionsv1.AddToScheme(scheme) + _ = clusterv1alpha3.AddToScheme(scheme) _ = clusterv1alpha4.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme) + _ = expv1alpha3.AddToScheme(scheme) _ = expv1alpha4.AddToScheme(scheme) _ = expv1.AddToScheme(scheme) + _ = addonsv1alpha3.AddToScheme(scheme) _ = addonsv1alpha4.AddToScheme(scheme) _ = addonsv1.AddToScheme(scheme) diff --git a/test/e2e/clusterctl_upgrade.go b/test/e2e/clusterctl_upgrade.go index 85f93f751eec..9a3d55ecbeb0 100644 --- a/test/e2e/clusterctl_upgrade.go +++ b/test/e2e/clusterctl_upgrade.go @@ -25,9 +25,11 @@ import ( "path/filepath" "runtime" "strings" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -35,13 +37,11 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/discovery" "k8s.io/klog/v2" "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/yaml" - clusterv1alpha4 "sigs.k8s.io/cluster-api/api/v1alpha4" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/cmd/clusterctl/client/config" "sigs.k8s.io/cluster-api/test/e2e/internal/log" @@ -118,7 +118,23 @@ type ClusterctlUpgradeSpecInput struct { WorkloadFlavor string // WorkloadKubernetesVersion is Kubernetes version used to create the workload cluster, e.g. `v1.25.0` WorkloadKubernetesVersion string - // Custom providers can be specified to upgrade to a pre-release or a custom version instead of upgrading to the latest using contact + + // Upgrades allows to define upgrade sequences. + // If not set, the test will upgrade once to the v1beta1 contract. + // For some examples see clusterctl_upgrade_test.go + Upgrades []ClusterctlUpgradeSpecInputUpgrade +} + +// ClusterctlUpgradeSpecInputUpgrade defines an upgrade. +type ClusterctlUpgradeSpecInputUpgrade struct { + // UpgradeWithBinary can be used to set the clusterctl binary to use for the provider upgrade. The spec will interpolate the + // strings `{OS}` and `{ARCH}` to `runtime.GOOS` and `runtime.GOARCH` respectively, e.g. https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.23/clusterctl-{OS}-{ARCH} + // If not set, the test will use the ApplyUpgrade function of the clusterctl library. + WithBinary string + // Contract defines the contract to upgrade to. + // Either the contract *or* the *Provider fields should be defined + // For some examples see clusterctl_upgrade_test.go + Contract string CoreProvider string BootstrapProviders []string ControlPlaneProviders []string @@ -175,7 +191,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg initContract string initKubernetesVersion string - workLoadClusterName string + workloadClusterName string ) BeforeEach(func() { @@ -212,6 +228,15 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg initKubernetesVersion = input.E2EConfig.GetVariable(initWithKubernetesVersion) } + if len(input.Upgrades) == 0 { + // Upgrade once to v1beta1 if no upgrades are specified. + input.Upgrades = []ClusterctlUpgradeSpecInputUpgrade{ + { + Contract: clusterv1.GroupVersion.Version, + }, + } + } + Expect(input.E2EConfig.Variables).To(HaveKey(KubernetesVersion)) Expect(os.MkdirAll(input.ArtifactFolder, 0750)).To(Succeed(), "Invalid argument. input.ArtifactFolder can't be created for %s spec", specName) @@ -273,17 +298,11 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg // Get a ClusterProxy so we can interact with the workload cluster managementClusterProxy = input.BootstrapClusterProxy.GetWorkloadCluster(ctx, cluster.Namespace, cluster.Name, framework.WithMachineLogCollector(input.BootstrapClusterProxy.GetLogCollector())) - // Download the older clusterctl version to be used for setting up the management cluster to be upgraded - log.Logf("Downloading clusterctl binary from %s", initClusterctlBinaryURL) - clusterctlBinaryPath := downloadToTmpFile(ctx, initClusterctlBinaryURL) + // Download the clusterctl version that should be used to initially set up the management cluster (which is later upgraded). + Byf("Downloading clusterctl binary from %s", initClusterctlBinaryURL) + clusterctlBinaryPath, clusterctlConfigPath := setupClusterctl(ctx, initClusterctlBinaryURL, input.ClusterctlConfigPath) defer os.Remove(clusterctlBinaryPath) // clean up - err := os.Chmod(clusterctlBinaryPath, 0744) //nolint:gosec - Expect(err).ToNot(HaveOccurred(), "failed to chmod temporary file") - - // Adjusts the clusterctlConfigPath in case the clusterctl version <= v1.3 (thus using a config file with only the providers supported in those versions) - clusterctlConfigPath := clusterctl.AdjustConfigPathForBinary(clusterctlBinaryPath, input.ClusterctlConfigPath) - By("Initializing the workload cluster with older versions of providers") if input.PreInit != nil { @@ -335,11 +354,6 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg By("THE MANAGEMENT CLUSTER WITH THE OLDER VERSION OF PROVIDERS IS UP&RUNNING!") - machineCRD := &apiextensionsv1.CustomResourceDefinition{} - if err := managementClusterProxy.GetClient().Get(ctx, client.ObjectKey{Name: "machines.cluster.x-k8s.io"}, machineCRD); err != nil { - Expect(err).ToNot(HaveOccurred(), "failed to retrieve a machine CRD") - } - Byf("Creating a namespace for hosting the %s test workload cluster", specName) testNamespace, testCancelWatches = framework.CreateNamespaceAndWatchEvents(ctx, framework.CreateNamespaceAndWatchEventsInput{ Creator: managementClusterProxy.GetClient(), @@ -354,7 +368,8 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg // In this case ApplyClusterTemplateAndWait can't be used because this helper is linked to the last version of the API; // so we are getting a template using the downloaded version of clusterctl, applying it, and wait for machines to be provisioned. - workLoadClusterName = fmt.Sprintf("%s-%s", specName, util.RandomString(6)) + workloadClusterName = fmt.Sprintf("%s-%s", specName, util.RandomString(6)) + workloadClusterNamespace := testNamespace.Name kubernetesVersion := input.WorkloadKubernetesVersion if kubernetesVersion == "" { kubernetesVersion = input.E2EConfig.GetVariable(KubernetesVersion) @@ -363,7 +378,7 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg workerMachineCount := pointer.Int64(1) log.Logf("Creating the workload cluster with name %q using the %q template (Kubernetes %s, %d control-plane machines, %d worker machines)", - workLoadClusterName, "(default)", kubernetesVersion, *controlPlaneMachineCount, *workerMachineCount) + workloadClusterName, "(default)", kubernetesVersion, *controlPlaneMachineCount, *workerMachineCount) log.Logf("Getting the cluster template yaml") workloadClusterTemplate := clusterctl.ConfigClusterWithBinary(ctx, clusterctlBinaryPath, clusterctl.ConfigClusterInput{ @@ -374,8 +389,8 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg // select template Flavor: input.WorkloadFlavor, // define template variables - Namespace: testNamespace.Name, - ClusterName: workLoadClusterName, + Namespace: workloadClusterNamespace, + ClusterName: workloadClusterName, KubernetesVersion: kubernetesVersion, ControlPlaneMachineCount: controlPlaneMachineCount, WorkerMachineCount: workerMachineCount, @@ -390,33 +405,25 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg if input.PreWaitForCluster != nil { By("Running PreWaitForCluster steps against the management cluster") - input.PreWaitForCluster(managementClusterProxy, testNamespace.Name, workLoadClusterName) - } - - // Build GroupVersionKind for Machine resources - machineListGVK := schema.GroupVersionKind{ - Group: machineCRD.Spec.Group, - Kind: machineCRD.Spec.Names.ListKind, + input.PreWaitForCluster(managementClusterProxy, workloadClusterNamespace, workloadClusterName) } - // Pick the storage version - for _, version := range machineCRD.Spec.Versions { - if version.Storage { - machineListGVK.Version = version.Name - break - } - } + coreCAPIStorageVersion := getCoreCAPIStorageVersion(ctx, managementClusterProxy.GetClient()) By("Waiting for the machines to exist") Eventually(func() (int64, error) { var n int64 machineList := &unstructured.UnstructuredList{} - machineList.SetGroupVersionKind(machineListGVK) + machineList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: clusterv1.GroupVersion.Group, + Version: coreCAPIStorageVersion, + Kind: "MachineList", + }) if err := managementClusterProxy.GetClient().List( ctx, machineList, - client.InNamespace(testNamespace.Name), - client.MatchingLabels{clusterv1.ClusterNameLabel: workLoadClusterName}, + client.InNamespace(workloadClusterNamespace), + client.MatchingLabels{clusterv1.ClusterNameLabel: workloadClusterName}, ); err == nil { for _, m := range machineList.Items { _, found, err := unstructured.NestedMap(m.Object, "status", "nodeRef") @@ -430,112 +437,168 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg By("THE MANAGEMENT CLUSTER WITH OLDER VERSION OF PROVIDERS WORKS!") - if input.PreUpgrade != nil { - By("Running Pre-upgrade steps against the management cluster") - input.PreUpgrade(managementClusterProxy) - } - - // Get the workloadCluster before the management cluster is upgraded to make sure that the upgrade did not trigger - // any unexpected rollouts. - preUpgradeMachineList := &unstructured.UnstructuredList{} - preUpgradeMachineList.SetGroupVersionKind(machineListGVK) - err = managementClusterProxy.GetClient().List( - ctx, - preUpgradeMachineList, - client.InNamespace(testNamespace.Name), - client.MatchingLabels{clusterv1.ClusterNameLabel: workLoadClusterName}, - ) - Expect(err).ToNot(HaveOccurred()) - // Check if the user want a custom upgrade - isCustomUpgrade := input.CoreProvider != "" || - len(input.BootstrapProviders) > 0 || - len(input.ControlPlaneProviders) > 0 || - len(input.InfrastructureProviders) > 0 || - len(input.IPAMProviders) > 0 || - len(input.RuntimeExtensionProviders) > 0 || - len(input.AddonProviders) > 0 - - if isCustomUpgrade { - By("Upgrading providers to custom versions") - clusterctl.UpgradeManagementClusterAndWait(ctx, clusterctl.UpgradeManagementClusterAndWaitInput{ - ClusterctlConfigPath: input.ClusterctlConfigPath, - ClusterctlVariables: input.UpgradeClusterctlVariables, - ClusterProxy: managementClusterProxy, - CoreProvider: input.CoreProvider, - BootstrapProviders: input.BootstrapProviders, - ControlPlaneProviders: input.ControlPlaneProviders, - InfrastructureProviders: input.InfrastructureProviders, - IPAMProviders: input.IPAMProviders, - RuntimeExtensionProviders: input.RuntimeExtensionProviders, - AddonProviders: input.AddonProviders, - LogFolder: filepath.Join(input.ArtifactFolder, "clusters", cluster.Name), - }, input.E2EConfig.GetIntervals(specName, "wait-controllers")...) - } else { - By("Upgrading providers to the latest version available") - clusterctl.UpgradeManagementClusterAndWait(ctx, clusterctl.UpgradeManagementClusterAndWaitInput{ - ClusterctlConfigPath: input.ClusterctlConfigPath, - ClusterctlVariables: input.UpgradeClusterctlVariables, - ClusterProxy: managementClusterProxy, - Contract: clusterv1.GroupVersion.Version, - LogFolder: filepath.Join(input.ArtifactFolder, "clusters", cluster.Name), - }, input.E2EConfig.GetIntervals(specName, "wait-controllers")...) - } - - By("THE MANAGEMENT CLUSTER WAS SUCCESSFULLY UPGRADED!") - - if input.PostUpgrade != nil { - By("Running Post-upgrade steps against the management cluster") - input.PostUpgrade(managementClusterProxy, testNamespace.Name, managementClusterName) - } + for i, upgrade := range input.Upgrades { + Byf("[%d] Starting upgrade", i) + if input.PreUpgrade != nil { + Byf("[%d] Running Pre-upgrade steps against the management cluster", i) + input.PreUpgrade(managementClusterProxy) + } - // After the upgrade check that there were no unexpected rollouts. - log.Logf("Verify there are no unexpected rollouts") - Consistently(func() bool { - postUpgradeMachineList := &unstructured.UnstructuredList{} - postUpgradeMachineList.SetGroupVersionKind(clusterv1.GroupVersion.WithKind("MachineList")) - err = managementClusterProxy.GetClient().List( + // Get the workloadCluster before the management cluster is upgraded to make sure that the upgrade did not trigger + // any unexpected rollouts. + preUpgradeMachineList := &unstructured.UnstructuredList{} + preUpgradeMachineList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: clusterv1.GroupVersion.Group, + Version: coreCAPIStorageVersion, + Kind: "MachineList", + }) + err := managementClusterProxy.GetClient().List( ctx, - postUpgradeMachineList, - client.InNamespace(testNamespace.Name), - client.MatchingLabels{clusterv1.ClusterNameLabel: workLoadClusterName}, + preUpgradeMachineList, + client.InNamespace(workloadClusterNamespace), + client.MatchingLabels{clusterv1.ClusterNameLabel: workloadClusterName}, ) Expect(err).ToNot(HaveOccurred()) - return validateMachineRollout(preUpgradeMachineList, postUpgradeMachineList) - }, "3m", "30s").Should(BeTrue(), "Machines should remain the same after the upgrade") - - // After upgrading we are sure the version is the latest version of the API, - // so it is possible to use the standard helpers - workloadCluster := framework.GetClusterByName(ctx, framework.GetClusterByNameInput{ - Getter: managementClusterProxy.GetClient(), - Namespace: testNamespace.Name, - Name: workLoadClusterName, - }) - if workloadCluster.Spec.Topology != nil { - // Cluster is using ClusterClass, scale up via topology. - framework.ScaleAndWaitMachineDeploymentTopology(ctx, framework.ScaleAndWaitMachineDeploymentTopologyInput{ - ClusterProxy: managementClusterProxy, - Cluster: workloadCluster, - Replicas: 2, - WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), - }) - } else { - // Cluster is not using ClusterClass, scale up via MachineDeployment. - testMachineDeployments := framework.GetMachineDeploymentsByCluster(ctx, framework.GetMachineDeploymentsByClusterInput{ - Lister: managementClusterProxy.GetClient(), - ClusterName: workLoadClusterName, - Namespace: testNamespace.Name, - }) - framework.ScaleAndWaitMachineDeployment(ctx, framework.ScaleAndWaitMachineDeploymentInput{ - ClusterProxy: managementClusterProxy, - Cluster: &clusterv1.Cluster{ObjectMeta: metav1.ObjectMeta{Namespace: testNamespace.Name}}, - MachineDeployment: testMachineDeployments[0], - Replicas: 2, - WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), + clusterctlUpgradeBinaryPath := "" + // TODO: While it is generally fine to use this clusterctl config for upgrades as well, + // it is not ideal because it points to the latest repositories (e.g. _artifacts/repository/cluster-api/latest/components.yaml) + // For example this means if we upgrade to v1.5 the upgrade won't use the metadata.yaml from v1.5 it will use the one from latest. + clusterctlUpgradeConfigPath := input.ClusterctlConfigPath + if upgrade.WithBinary != "" { + // Download the clusterctl version to be used to upgrade the management cluster + upgradeClusterctlBinaryURL := strings.NewReplacer("{OS}", runtime.GOOS, "{ARCH}", runtime.GOARCH).Replace(upgrade.WithBinary) + Byf("[%d] Downloading clusterctl binary from %s", i, upgradeClusterctlBinaryURL) + clusterctlUpgradeBinaryPath, clusterctlUpgradeConfigPath = setupClusterctl(ctx, upgradeClusterctlBinaryURL, input.ClusterctlConfigPath) + defer os.Remove(clusterctlBinaryPath) //nolint:gocritic // Resource leakage is not a concern here. + } + + // Check if the user want a custom upgrade + isCustomUpgrade := upgrade.CoreProvider != "" || + len(upgrade.BootstrapProviders) > 0 || + len(upgrade.ControlPlaneProviders) > 0 || + len(upgrade.InfrastructureProviders) > 0 || + len(upgrade.IPAMProviders) > 0 || + len(upgrade.RuntimeExtensionProviders) > 0 || + len(upgrade.AddonProviders) > 0 + + if isCustomUpgrade { + Byf("[%d] Upgrading providers to custom versions", i) + clusterctl.UpgradeManagementClusterAndWait(ctx, clusterctl.UpgradeManagementClusterAndWaitInput{ + ClusterctlBinaryPath: clusterctlUpgradeBinaryPath, // use specific version of clusterctl to upgrade the management cluster (if set) + ClusterctlConfigPath: clusterctlUpgradeConfigPath, + ClusterctlVariables: input.UpgradeClusterctlVariables, + ClusterProxy: managementClusterProxy, + CoreProvider: upgrade.CoreProvider, + BootstrapProviders: upgrade.BootstrapProviders, + ControlPlaneProviders: upgrade.ControlPlaneProviders, + InfrastructureProviders: upgrade.InfrastructureProviders, + IPAMProviders: upgrade.IPAMProviders, + RuntimeExtensionProviders: upgrade.RuntimeExtensionProviders, + AddonProviders: upgrade.AddonProviders, + LogFolder: filepath.Join(input.ArtifactFolder, "clusters", cluster.Name), + }, input.E2EConfig.GetIntervals(specName, "wait-controllers")...) + } else { + Byf("[%d] Upgrading providers to the latest version available", i) + clusterctl.UpgradeManagementClusterAndWait(ctx, clusterctl.UpgradeManagementClusterAndWaitInput{ + ClusterctlBinaryPath: clusterctlUpgradeBinaryPath, // use specific version of clusterctl to upgrade the management cluster (if set) + ClusterctlConfigPath: clusterctlUpgradeConfigPath, + ClusterctlVariables: input.UpgradeClusterctlVariables, + ClusterProxy: managementClusterProxy, + Contract: upgrade.Contract, + LogFolder: filepath.Join(input.ArtifactFolder, "clusters", cluster.Name), + }, input.E2EConfig.GetIntervals(specName, "wait-controllers")...) + } + + Byf("[%d] THE MANAGEMENT CLUSTER WAS SUCCESSFULLY UPGRADED!", i) + + // We have to get the core CAPI storage version again as the upgrade might have stopped serving v1alpha3/v1alpha4. + coreCAPIStorageVersion = getCoreCAPIStorageVersion(ctx, managementClusterProxy.GetClient()) + + // Note: Currently we only support v1beta1 core CAPI apiVersion after upgrades. + // This seems a reasonable simplification as we don't want to test upgrades to v1alpha3 / v1alpha4. + workloadCluster := framework.DiscoveryAndWaitForCluster(ctx, framework.DiscoveryAndWaitForClusterInput{ + Getter: managementClusterProxy.GetClient(), + Namespace: workloadClusterNamespace, + Name: workloadClusterName, + }, input.E2EConfig.GetIntervals(specName, "wait-cluster")...) + + if input.PostUpgrade != nil { + Byf("[%d] Running Post-upgrade steps against the management cluster", i) + input.PostUpgrade(managementClusterProxy, workloadClusterNamespace, managementClusterName) + } + + // After the upgrade check that there were no unexpected rollouts. + Byf("[%d] Verify there are no unexpected rollouts", i) + Consistently(func() bool { + postUpgradeMachineList := &unstructured.UnstructuredList{} + postUpgradeMachineList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: clusterv1.GroupVersion.Group, + Version: coreCAPIStorageVersion, + Kind: "MachineList", + }) + err = managementClusterProxy.GetClient().List( + ctx, + postUpgradeMachineList, + client.InNamespace(workloadCluster.GetNamespace()), + client.MatchingLabels{clusterv1.ClusterNameLabel: workloadCluster.GetName()}, + ) + Expect(err).ToNot(HaveOccurred()) + return validateMachineRollout(preUpgradeMachineList, postUpgradeMachineList) + }, "3m", "30s").Should(BeTrue(), "Machines should remain the same after the upgrade") + + // Scale up to 2 and back down to 1 so we can repeat this multiple times. + Byf("[%d] Scale MachineDeployment to ensure the providers work", i) + if workloadCluster.Spec.Topology != nil { + // Cluster is using ClusterClass, scale up via topology. + framework.ScaleAndWaitMachineDeploymentTopology(ctx, framework.ScaleAndWaitMachineDeploymentTopologyInput{ + ClusterProxy: managementClusterProxy, + Cluster: workloadCluster, + Replicas: 2, + WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), + }) + framework.ScaleAndWaitMachineDeploymentTopology(ctx, framework.ScaleAndWaitMachineDeploymentTopologyInput{ + ClusterProxy: managementClusterProxy, + Cluster: workloadCluster, + Replicas: 1, + WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), + }) + } else { + // Cluster is not using ClusterClass, scale up via MachineDeployment. + testMachineDeployments := framework.GetMachineDeploymentsByCluster(ctx, framework.GetMachineDeploymentsByClusterInput{ + Lister: managementClusterProxy.GetClient(), + ClusterName: workloadClusterName, + Namespace: workloadClusterNamespace, + }) + framework.ScaleAndWaitMachineDeployment(ctx, framework.ScaleAndWaitMachineDeploymentInput{ + ClusterProxy: managementClusterProxy, + Cluster: workloadCluster, + MachineDeployment: testMachineDeployments[0], + Replicas: 2, + WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), + }) + framework.ScaleAndWaitMachineDeployment(ctx, framework.ScaleAndWaitMachineDeploymentInput{ + ClusterProxy: managementClusterProxy, + Cluster: workloadCluster, + MachineDeployment: testMachineDeployments[0], + Replicas: 1, + WaitForMachineDeployments: input.E2EConfig.GetIntervals(specName, "wait-worker-nodes"), + }) + } + + Byf("[%d] Verify client-side SSA still works", i) + clusterUpdate := &unstructured.Unstructured{} + clusterUpdate.SetGroupVersionKind(clusterv1.GroupVersion.WithKind("Cluster")) + clusterUpdate.SetNamespace(workloadCluster.Namespace) + clusterUpdate.SetName(workloadCluster.Name) + clusterUpdate.SetLabels(map[string]string{ + fmt.Sprintf("test-label-upgrade-%d", i): "test-label-value", }) - } + err = managementClusterProxy.GetClient().Patch(ctx, clusterUpdate, client.Apply, client.FieldOwner("e2e-test-client")) + Expect(err).ToNot(HaveOccurred()) - By("THE UPGRADED MANAGEMENT CLUSTER WORKS!") + Byf("[%d] THE UPGRADED MANAGEMENT CLUSTER WORKS!", i) + } By("PASSED!") }) @@ -546,25 +609,8 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg dumpAllResources(ctx, managementClusterProxy, input.ArtifactFolder, testNamespace, managementClusterResources.Cluster) if !input.SkipCleanup { - switch { - case discovery.ServerSupportsVersion(managementClusterProxy.GetClientSet().DiscoveryClient, clusterv1.GroupVersion) == nil: - Byf("Deleting all %s clusters in namespace %s in management cluster %s", clusterv1.GroupVersion, testNamespace.Name, managementClusterName) - framework.DeleteAllClustersAndWait(ctx, framework.DeleteAllClustersAndWaitInput{ - Client: managementClusterProxy.GetClient(), - Namespace: testNamespace.Name, - }, input.E2EConfig.GetIntervals(specName, "wait-delete-cluster")...) - case discovery.ServerSupportsVersion(managementClusterProxy.GetClientSet().DiscoveryClient, clusterv1alpha4.GroupVersion) == nil: - Byf("Deleting all %s clusters in namespace %s in management cluster %s", clusterv1alpha4.GroupVersion, testNamespace.Name, managementClusterName) - deleteAllClustersAndWaitV1alpha4(ctx, framework.DeleteAllClustersAndWaitInput{ - Client: managementClusterProxy.GetClient(), - Namespace: testNamespace.Name, - }, input.E2EConfig.GetIntervals(specName, "wait-delete-cluster")...) - default: - log.Logf("Management Cluster does not appear to support CAPI resources.") - } - - Byf("Deleting cluster %s", klog.KRef(testNamespace.Name, managementClusterName)) - framework.DeleteAllClustersAndWait(ctx, framework.DeleteAllClustersAndWaitInput{ + Byf("Deleting all clusters in namespace %s in management cluster %s", testNamespace.Name, managementClusterName) + deleteAllClustersAndWait(ctx, deleteAllClustersAndWaitInput{ Client: managementClusterProxy.GetClient(), Namespace: testNamespace.Name, }, input.E2EConfig.GetIntervals(specName, "wait-delete-cluster")...) @@ -594,6 +640,18 @@ func ClusterctlUpgradeSpec(ctx context.Context, inputGetter func() ClusterctlUpg }) } +func setupClusterctl(ctx context.Context, clusterctlBinaryURL, clusterctlConfigPath string) (string, string) { + clusterctlBinaryPath := downloadToTmpFile(ctx, clusterctlBinaryURL) + + err := os.Chmod(clusterctlBinaryPath, 0744) //nolint:gosec + Expect(err).ToNot(HaveOccurred(), "failed to chmod temporary file") + + // Adjusts the clusterctlConfigPath in case the clusterctl version <= v1.3 (thus using a config file with only the providers supported in those versions) + clusterctlConfigPath = clusterctl.AdjustConfigPathForBinary(clusterctlBinaryPath, clusterctlConfigPath) + + return clusterctlBinaryPath, clusterctlConfigPath +} + func downloadToTmpFile(ctx context.Context, url string) string { tmpFile, err := os.CreateTemp("", "clusterctl") Expect(err).ToNot(HaveOccurred(), "failed to get temporary file") @@ -614,74 +672,75 @@ func downloadToTmpFile(ctx context.Context, url string) string { return tmpFile.Name() } -// deleteAllClustersAndWaitV1alpha4 deletes all cluster resources in the given namespace and waits for them to be gone using the older API. -func deleteAllClustersAndWaitV1alpha4(ctx context.Context, input framework.DeleteAllClustersAndWaitInput, intervals ...interface{}) { - Expect(ctx).NotTo(BeNil(), "ctx is required for deleteAllClustersAndWaitOldAPI") - Expect(input.Client).ToNot(BeNil(), "Invalid argument. input.Client can't be nil when calling deleteAllClustersAndWaitOldAPI") - Expect(input.Namespace).ToNot(BeEmpty(), "Invalid argument. input.Namespace can't be empty when calling deleteAllClustersAndWaitOldAPI") - - clusters := getAllClustersByNamespaceV1alpha4(ctx, framework.GetAllClustersByNamespaceInput{ - Lister: input.Client, - Namespace: input.Namespace, - }) - - for _, c := range clusters { - deleteClusterV1alpha4(ctx, deleteClusterV1alpha4Input{ - Deleter: input.Client, - Cluster: c, - }) +func getCoreCAPIStorageVersion(ctx context.Context, c client.Client) string { + clusterCRD := &apiextensionsv1.CustomResourceDefinition{} + if err := c.Get(ctx, client.ObjectKey{Name: "clusters.cluster.x-k8s.io"}, clusterCRD); err != nil { + Expect(err).ToNot(HaveOccurred(), "failed to retrieve a machine CRD") } - - for _, c := range clusters { - log.Logf("Waiting for the Cluster %s to be deleted", klog.KObj(c)) - waitForClusterDeletedV1alpha4(ctx, waitForClusterDeletedV1alpha4Input{ - Getter: input.Client, - Cluster: c, - }, intervals...) + // Pick the storage version + for _, version := range clusterCRD.Spec.Versions { + if version.Storage { + return version.Name + } } + Fail("Cluster CRD has no storage version") + return "" } -// getAllClustersByNamespaceV1alpha4 returns the list of Cluster objects in a namespace using the older API. -func getAllClustersByNamespaceV1alpha4(ctx context.Context, input framework.GetAllClustersByNamespaceInput) []*clusterv1alpha4.Cluster { - clusterList := &clusterv1alpha4.ClusterList{} - Expect(input.Lister.List(ctx, clusterList, client.InNamespace(input.Namespace))).To(Succeed(), "Failed to list clusters in namespace %s", input.Namespace) - - clusters := make([]*clusterv1alpha4.Cluster, len(clusterList.Items)) - for i := range clusterList.Items { - clusters[i] = &clusterList.Items[i] - } - return clusters +// deleteAllClustersAndWaitInput is the input type for deleteAllClustersAndWait. +type deleteAllClustersAndWaitInput struct { + Client client.Client + Namespace string } -// deleteClusterV1alpha4Input is the input for deleteClusterV1alpha4. -type deleteClusterV1alpha4Input struct { - Deleter framework.Deleter - Cluster *clusterv1alpha4.Cluster -} +// deleteAllClustersAndWait deletes all cluster resources in the given namespace and waits for them to be gone. +func deleteAllClustersAndWait(ctx context.Context, input deleteAllClustersAndWaitInput, intervals ...interface{}) { + Expect(ctx).NotTo(BeNil(), "ctx is required for deleteAllClustersAndWaitOldAPI") + Expect(input.Client).ToNot(BeNil(), "Invalid argument. input.Client can't be nil when calling deleteAllClustersAndWaitOldAPI") + Expect(input.Namespace).ToNot(BeEmpty(), "Invalid argument. input.Namespace can't be empty when calling deleteAllClustersAndWaitOldAPI") -// deleteClusterV1alpha4 deletes the cluster and waits for everything the cluster owned to actually be gone using the older API. -func deleteClusterV1alpha4(ctx context.Context, input deleteClusterV1alpha4Input) { - Byf("Deleting cluster %s", input.Cluster.GetName()) - Expect(input.Deleter.Delete(ctx, input.Cluster)).To(Succeed()) -} + coreCAPIStorageVersion := getCoreCAPIStorageVersion(ctx, input.Client) -// waitForClusterDeletedV1alpha4Input is the input for waitForClusterDeletedV1alpha4. -type waitForClusterDeletedV1alpha4Input struct { - Getter framework.Getter - Cluster *clusterv1alpha4.Cluster -} + clusterList := &unstructured.UnstructuredList{} + clusterList.SetGroupVersionKind(schema.GroupVersionKind{ + Group: clusterv1.GroupVersion.Group, + Version: coreCAPIStorageVersion, + Kind: "ClusterList", + }) + Expect(input.Client.List(ctx, clusterList, client.InNamespace(input.Namespace))).To(Succeed(), "Failed to list clusters in namespace %s", input.Namespace) + + // Enforce restart of kube-controller-manager by stealing its lease. + // Note: Due to a known issue in the kube-controller-manager we have to restart it + // in case the kube-controller-manager internally caches ownerRefs of apiVersions + // which now don't exist anymore (e.g. v1alpha3/v1alpha4). + // Alternatives to this would be: + // * some other way to restart the kube-controller-manager (e.g. control plane node rollout) + // * removing ownerRefs from (at least) MachineDeployments + Eventually(func(g Gomega) { + kubeControllerManagerLease := &coordinationv1.Lease{} + g.Expect(input.Client.Get(ctx, client.ObjectKey{Namespace: metav1.NamespaceSystem, Name: "kube-controller-manager"}, kubeControllerManagerLease)).To(Succeed()) + // As soon as the kube-controller-manager detects it doesn't own the lease anymore it will restart. + // Once the current lease times out the kube-controller-manager will become leader again. + kubeControllerManagerLease.Spec.HolderIdentity = pointer.String("e2e-test-client") + g.Expect(input.Client.Update(ctx, kubeControllerManagerLease)).To(Succeed()) + }, 3*time.Minute, 3*time.Second).Should(Succeed(), "failed to steal lease from kube-controller-manager to trigger restart") + + for _, c := range clusterList.Items { + Byf("Deleting cluster %s", c.GetName()) + Expect(input.Client.Delete(ctx, c.DeepCopy())).To(Succeed()) + } -// waitForClusterDeletedV1alpha4 waits until the cluster object has been deleted using the older API. -func waitForClusterDeletedV1alpha4(ctx context.Context, input waitForClusterDeletedV1alpha4Input, intervals ...interface{}) { - Byf("Waiting for cluster %s to be deleted", input.Cluster.GetName()) - Eventually(func() bool { - cluster := &clusterv1alpha4.Cluster{} - key := client.ObjectKey{ - Namespace: input.Cluster.GetNamespace(), - Name: input.Cluster.GetName(), - } - return apierrors.IsNotFound(input.Getter.Get(ctx, key, cluster)) - }, intervals...).Should(BeTrue()) + for _, c := range clusterList.Items { + Byf("Waiting for cluster %s to be deleted", c.GetName()) + Eventually(func() bool { + cluster := c.DeepCopy() + key := client.ObjectKey{ + Namespace: c.GetNamespace(), + Name: c.GetName(), + } + return apierrors.IsNotFound(input.Client.Get(ctx, key, cluster)) + }, intervals...).Should(BeTrue()) + } } // validateMachineRollout compares preMachineList and postMachineList to detect a rollout. @@ -698,7 +757,7 @@ func validateMachineRollout(preMachineList, postMachineList *unstructured.Unstru return true } - log.Logf("Rollout detected") + log.Logf("Rollout detected (%d Machines before, %d Machines after)", len(preMachineList.Items), len(postMachineList.Items)) newMachines := names(postMachineList).Difference(names(preMachineList)) deletedMachines := names(preMachineList).Difference(names(postMachineList)) diff --git a/test/e2e/clusterctl_upgrade_test.go b/test/e2e/clusterctl_upgrade_test.go index df06f2048afd..fa446de86787 100644 --- a/test/e2e/clusterctl_upgrade_test.go +++ b/test/e2e/clusterctl_upgrade_test.go @@ -20,10 +20,128 @@ limitations under the License. package e2e import ( + "runtime" + . "github.com/onsi/ginkgo/v2" "k8s.io/utils/pointer" + + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" ) +var _ = Describe("When testing clusterctl upgrades (v0.3=>v1.5=>current)", func() { + // We are testing v0.3=>v1.5=>current to ensure that old entries with v1alpha3 in managed files do not cause issues + // as described in https://github.com/kubernetes-sigs/cluster-api/issues/10051. + // NOTE: The combination of v0.3=>v1.5=>current allows us to verify this without being forced to upgrade + // the management cluster in the middle of the test as all 3 versions are ~ compatible with the same mgmt and workload Kubernetes versions. + // Additionally, clusterctl v1.5 still allows the upgrade of management clusters from v1alpha3 (v1.6 doesn't). + clusterctlDownloadURL03 := "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/clusterctl-{OS}-{ARCH}" + if runtime.GOOS == "darwin" { + // There is no arm64 binary for v0.3.x, so we'll use the amd64 one. + clusterctlDownloadURL03 = "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/clusterctl-darwin-amd64" + } + ClusterctlUpgradeSpec(ctx, func() ClusterctlUpgradeSpecInput { + return ClusterctlUpgradeSpecInput{ + E2EConfig: e2eConfig, + ClusterctlConfigPath: clusterctlConfigPath, + BootstrapClusterProxy: bootstrapClusterProxy, + ArtifactFolder: artifactFolder, + SkipCleanup: skipCleanup, + InfrastructureProvider: pointer.String("docker"), + // Configuration for the initial provider deployment. + InitWithBinary: clusterctlDownloadURL03, + // We have to pin the providers because with `InitWithProvidersContract` the test would + // use the latest version for the contract. + InitWithCoreProvider: "cluster-api:v0.3.25", + InitWithBootstrapProviders: []string{"kubeadm:v0.3.25"}, + InitWithControlPlaneProviders: []string{"kubeadm:v0.3.25"}, + InitWithInfrastructureProviders: []string{"docker:v0.3.25"}, + // We have to set this to an empty array as clusterctl v0.3 doesn't support + // runtime extension providers. If we don't do this the test will automatically + // try to deploy the latest version of our test-extension from docker.yaml. + InitWithRuntimeExtensionProviders: []string{}, + // Configuration for the provider upgrades. + Upgrades: []ClusterctlUpgradeSpecInputUpgrade{ + { + // Upgrade to v1.5. + // Note: v1.5 is the highest version we can use as it's the last one + // that is able to upgrade from a v1alpha3 management cluster. + WithBinary: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.5.0/clusterctl-{OS}-{ARCH}", + CoreProvider: "cluster-api:v1.5.0", + BootstrapProviders: []string{"kubeadm:v1.5.0"}, + ControlPlaneProviders: []string{"kubeadm:v1.5.0"}, + InfrastructureProviders: []string{"docker:v1.5.0"}, + }, + { // Upgrade to latest v1beta1. + Contract: clusterv1.GroupVersion.Version, + }, + }, + // CAPI v0.3.x does not work on Kubernetes >= v1.22. + // NOTE: If this version is changed here the image and SHA must also be updated in all DockerMachineTemplates in `test/data/infrastructure-docker/v0.3/bases. + // Note: Both InitWithKubernetesVersion and WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version. + InitWithKubernetesVersion: "v1.21.14", + WorkloadKubernetesVersion: "v1.22.17", + // CAPI does not work with Kubernetes < v1.22 if ClusterClass is enabled, so we have to disable it. + UpgradeClusterctlVariables: map[string]string{ + "CLUSTER_TOPOLOGY": "false", + }, + MgmtFlavor: "topology", + WorkloadFlavor: "", + } + }) +}) + +var _ = Describe("When testing clusterctl upgrades (v0.4=>v1.5=>current)", func() { + // We are testing v0.4=>v1.5=>current to ensure that old entries with v1alpha4 in managed files do not cause issues + // as described in https://github.com/kubernetes-sigs/cluster-api/issues/10051. + // NOTE: The combination of v0.4=>v1.5=>current allows us to verify this without being forced to upgrade + // the management cluster in the middle of the test as all 3 versions are ~ compatible with the same mgmt and workload Kubernetes versions. + // Additionally, clusterctl v1.5 still allows the upgrade of management clusters from v1alpha4 (v1.6 does as well, but v1.7 doesn't). + ClusterctlUpgradeSpec(ctx, func() ClusterctlUpgradeSpecInput { + return ClusterctlUpgradeSpecInput{ + E2EConfig: e2eConfig, + ClusterctlConfigPath: clusterctlConfigPath, + BootstrapClusterProxy: bootstrapClusterProxy, + ArtifactFolder: artifactFolder, + SkipCleanup: skipCleanup, + InfrastructureProvider: pointer.String("docker"), + // Configuration for the initial provider deployment. + InitWithBinary: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.4.8/clusterctl-{OS}-{ARCH}", + // We have to pin the providers because with `InitWithProvidersContract` the test would + // use the latest version for the contract. + InitWithCoreProvider: "cluster-api:v0.4.8", + InitWithBootstrapProviders: []string{"kubeadm:v0.4.8"}, + InitWithControlPlaneProviders: []string{"kubeadm:v0.4.8"}, + InitWithInfrastructureProviders: []string{"docker:v0.4.8"}, + // We have to set this to an empty array as clusterctl v0.4 doesn't support + // runtime extension providers. If we don't do this the test will automatically + // try to deploy the latest version of our test-extension from docker.yaml. + InitWithRuntimeExtensionProviders: []string{}, + // Configuration for the provider upgrades. + Upgrades: []ClusterctlUpgradeSpecInputUpgrade{ + { + // Upgrade to v1.5. + // Note: v1.5 is a version we can use as it's + // able to upgrade from a v1alpha4 management cluster (v1.6 would be able to as well) + WithBinary: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.5.0/clusterctl-{OS}-{ARCH}", + CoreProvider: "cluster-api:v1.5.0", + BootstrapProviders: []string{"kubeadm:v1.5.0"}, + ControlPlaneProviders: []string{"kubeadm:v1.5.0"}, + InfrastructureProviders: []string{"docker:v1.5.0"}, + }, + { // Upgrade to latest v1beta1. + Contract: clusterv1.GroupVersion.Version, + }, + }, + // NOTE: If this version is changed here the image and SHA must also be updated in all DockerMachineTemplates in `test/data/infrastructure-docker/v0.4/bases. + // Note: Both InitWithKubernetesVersion and WorkloadKubernetesVersion should be the highest mgmt cluster version supported by the source Cluster API version. + InitWithKubernetesVersion: "v1.23.17", + WorkloadKubernetesVersion: "v1.23.17", + MgmtFlavor: "topology", + WorkloadFlavor: "", + } + }) +}) + var _ = Describe("When testing clusterctl upgrades (v1.0=>current)", func() { ClusterctlUpgradeSpec(ctx, func() ClusterctlUpgradeSpecInput { return ClusterctlUpgradeSpecInput{ diff --git a/test/e2e/config/docker.yaml b/test/e2e/config/docker.yaml index 109705cd9841..33edb6e8a150 100644 --- a/test/e2e/config/docker.yaml +++ b/test/e2e/config/docker.yaml @@ -35,6 +35,24 @@ providers: - name: cluster-api type: CoreProvider versions: + - name: v0.3.25 # latest published release in the v1alpha3 series; this is used for v1alpha3 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/core-components.yaml" + type: "url" + contract: v1alpha3 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.3/metadata.yaml" + - name: v0.4.8 # latest published release in the v1alpha4 series; this is used for v1alpha4 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.4.8/core-components.yaml" + type: "url" + contract: v1alpha4 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.4/metadata.yaml" - name: v1.0.5 # supported release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.5/core-components.yaml" type: "url" @@ -73,6 +91,24 @@ providers: - name: kubeadm type: BootstrapProvider versions: + - name: v0.3.25 # latest published release in the v1alpha3 series; this is used for v1alpha3 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/bootstrap-components.yaml" + type: "url" + contract: v1alpha3 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.3/metadata.yaml" + - name: v0.4.8 # latest published release in the v1alpha4 series; this is used for v1alpha4 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.4.8/bootstrap-components.yaml" + type: "url" + contract: v1alpha4 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.4/metadata.yaml" - name: v1.0.5 # supported release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.5/bootstrap-components.yaml" type: "url" @@ -111,6 +147,24 @@ providers: - name: kubeadm type: ControlPlaneProvider versions: + - name: v0.3.25 # latest published release in the v1alpha3 series; this is used for v1alpha3 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/control-plane-components.yaml" + type: "url" + contract: v1alpha3 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.3/metadata.yaml" + - name: v0.4.8 # latest published release in the v1alpha4 series; this is used for v1alpha4 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.4.8/control-plane-components.yaml" + type: "url" + contract: v1alpha4 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.4/metadata.yaml" - name: v1.0.5 # supported release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.5/control-plane-components.yaml" type: "url" @@ -149,6 +203,26 @@ providers: - name: docker type: InfrastructureProvider versions: + - name: v0.3.25 # latest published release in the v1alpha3 series; this is used for v1alpha3 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.25/infrastructure-components-development.yaml" + type: "url" + contract: v1alpha3 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.3/metadata.yaml" + - sourcePath: "../data/infrastructure-docker/v0.3/cluster-template.yaml" + - name: v0.4.8 # latest published release in the v1alpha4 series; this is used for v1alpha4 --> v1beta1 clusterctl upgrades test only. + value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.4.8/infrastructure-components-development.yaml" + type: "url" + contract: v1alpha4 + replacements: + - old: --metrics-addr=127.0.0.1:8080 + new: --metrics-addr=:8080 + files: + - sourcePath: "../data/shared/v0.4/metadata.yaml" + - sourcePath: "../data/infrastructure-docker/v0.4/cluster-template.yaml" - name: v1.0.5 # supported release in the v1beta1 series; this is used for v1beta1 --> main clusterctl upgrades test only. value: "https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.0.5/infrastructure-components-development.yaml" type: "url" diff --git a/test/e2e/data/infrastructure-docker/v0.3/bases/cluster-with-kcp.yaml b/test/e2e/data/infrastructure-docker/v0.3/bases/cluster-with-kcp.yaml new file mode 100644 index 000000000000..1251c2d9d43c --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.3/bases/cluster-with-kcp.yaml @@ -0,0 +1,86 @@ +--- +# DockerCluster object referenced by the Cluster object +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 +kind: DockerCluster +metadata: + name: '${CLUSTER_NAME}' +--- +# Cluster object with +# - Reference to the KubeadmControlPlane object +# - the label cni=${CLUSTER_NAME}-crs-0, so the cluster can be selected by the ClusterResourceSet. +apiVersion: cluster.x-k8s.io/v1alpha3 +kind: Cluster +metadata: + name: '${CLUSTER_NAME}' + labels: + cni: "${CLUSTER_NAME}-crs-0" +spec: + clusterNetwork: + services: + cidrBlocks: ['${DOCKER_SERVICE_CIDRS}'] + pods: + cidrBlocks: ['${DOCKER_POD_CIDRS}'] + serviceDomain: '${DOCKER_SERVICE_DOMAIN}' + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 + kind: DockerCluster + name: '${CLUSTER_NAME}' + controlPlaneRef: + kind: KubeadmControlPlane + apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 + name: "${CLUSTER_NAME}-control-plane" +--- +# DockerMachineTemplate object referenced by the KubeadmControlPlane object +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 +kind: DockerMachineTemplate +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + template: + spec: + # NOTE: If the Kubernetes version is changed in `clusterctl_upgrade_test.go` the image and SHA must be updated here. + customImage: "kindest/node:v1.22.17@sha256:9af784f45a584f6b28bce2af84c494d947a05bd709151466489008f80a9ce9d5" + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" +--- +# KubeadmControlPlane referenced by the Cluster object with +# - the label kcp-adoption.step2, because it should be created in the second step of the kcp-adoption test. +kind: KubeadmControlPlane +apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 +metadata: + name: "${CLUSTER_NAME}-control-plane" + labels: + kcp-adoption.step2: "" +spec: + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + infrastructureTemplate: + kind: DockerMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 + name: "${CLUSTER_NAME}-control-plane" + kubeadmConfigSpec: + clusterConfiguration: + controllerManager: + extraArgs: {enable-hostpath-provisioner: 'true'} + apiServer: + # host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied. + certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal] + initConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + # We have to pin the cgroupDriver to cgroupfs for Kubernetes < v1.24 because kind does not support systemd for those versions, but kubeadm >= 1.21 defaults to systemd. + # This cluster is used in tests where the Kubernetes version is < 1.24 + cgroup-driver: cgroupfs + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + joinConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + # We have to pin the cgroupDriver to cgroupfs for Kubernetes < v1.24 because kind does not support systemd for those versions, but kubeadm >= 1.21 defaults to systemd. + # This cluster is used in tests where the Kubernetes version is < 1.24 + cgroup-driver: cgroupfs + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + version: "${KUBERNETES_VERSION}" diff --git a/test/e2e/data/infrastructure-docker/v0.3/bases/crs.yaml b/test/e2e/data/infrastructure-docker/v0.3/bases/crs.yaml new file mode 100644 index 000000000000..d88867d1ddb1 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.3/bases/crs.yaml @@ -0,0 +1,24 @@ +--- +# ConfigMap object referenced by the ClusterResourceSet object and with +# the CNI resource defined in the test config file +apiVersion: v1 +kind: ConfigMap +metadata: + name: "cni-${CLUSTER_NAME}-crs-0" +data: ${CNI_RESOURCES} +binaryData: +--- +# ClusterResourceSet object with +# a selector that targets all the Cluster with label cni=${CLUSTER_NAME}-crs-0 +apiVersion: addons.cluster.x-k8s.io/v1alpha3 +kind: ClusterResourceSet +metadata: + name: "${CLUSTER_NAME}-crs-0" +spec: + strategy: ApplyOnce + clusterSelector: + matchLabels: + cni: "${CLUSTER_NAME}-crs-0" + resources: + - name: "cni-${CLUSTER_NAME}-crs-0" + kind: ConfigMap diff --git a/test/e2e/data/infrastructure-docker/v0.3/bases/md.yaml b/test/e2e/data/infrastructure-docker/v0.3/bases/md.yaml new file mode 100644 index 000000000000..6285103bfb24 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.3/bases/md.yaml @@ -0,0 +1,57 @@ +--- +# DockerMachineTemplate referenced by the MachineDeployment and with +# - extraMounts for the docker sock, thus allowing self-hosting test +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 +kind: DockerMachineTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + # NOTE: If the Kubernetes version is changed in `clusterctl_upgrade_test.go` the image and SHA must be updated here. + customImage: "kindest/node:v1.22.17@sha256:9af784f45a584f6b28bce2af84c494d947a05bd709151466489008f80a9ce9d5" + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" +--- +# KubeadmConfigTemplate referenced by the MachineDeployment +apiVersion: bootstrap.cluster.x-k8s.io/v1alpha3 +kind: KubeadmConfigTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' +--- +# MachineDeployment object with +# - the label nodepool=pool1 that applies to all the machines, so those machine can be targeted by the MachineHealthCheck object +apiVersion: cluster.x-k8s.io/v1alpha3 +kind: MachineDeployment +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + clusterName: "${CLUSTER_NAME}" + replicas: ${WORKER_MACHINE_COUNT} + selector: + matchLabels: + template: + metadata: + labels: + "nodepool": "pool1" + spec: + clusterName: "${CLUSTER_NAME}" + version: "${KUBERNETES_VERSION}" + bootstrap: + configRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: bootstrap.cluster.x-k8s.io/v1alpha3 + kind: KubeadmConfigTemplate + infrastructureRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 + kind: DockerMachineTemplate diff --git a/test/e2e/data/infrastructure-docker/v0.3/cluster-template/kustomization.yaml b/test/e2e/data/infrastructure-docker/v0.3/cluster-template/kustomization.yaml new file mode 100644 index 000000000000..c7805717ecc1 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.3/cluster-template/kustomization.yaml @@ -0,0 +1,4 @@ +bases: +- ../bases/cluster-with-kcp.yaml +- ../bases/md.yaml +- ../bases/crs.yaml \ No newline at end of file diff --git a/test/e2e/data/infrastructure-docker/v0.4/bases/cluster-with-kcp.yaml b/test/e2e/data/infrastructure-docker/v0.4/bases/cluster-with-kcp.yaml new file mode 100644 index 000000000000..371789cf5745 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.4/bases/cluster-with-kcp.yaml @@ -0,0 +1,87 @@ +--- +# DockerCluster object referenced by the Cluster object +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 +kind: DockerCluster +metadata: + name: '${CLUSTER_NAME}' +--- +# Cluster object with +# - Reference to the KubeadmControlPlane object +# - the label cni=${CLUSTER_NAME}-crs-0, so the cluster can be selected by the ClusterResourceSet. +apiVersion: cluster.x-k8s.io/v1alpha4 +kind: Cluster +metadata: + name: '${CLUSTER_NAME}' + labels: + cni: "${CLUSTER_NAME}-crs-0" +spec: + clusterNetwork: + services: + cidrBlocks: ['${DOCKER_SERVICE_CIDRS}'] + pods: + cidrBlocks: ['${DOCKER_POD_CIDRS}'] + serviceDomain: '${DOCKER_SERVICE_DOMAIN}' + infrastructureRef: + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: DockerCluster + name: '${CLUSTER_NAME}' + controlPlaneRef: + kind: KubeadmControlPlane + apiVersion: controlplane.cluster.x-k8s.io/v1alpha4 + name: "${CLUSTER_NAME}-control-plane" +--- +# DockerMachineTemplate object referenced by the KubeadmControlPlane object +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 +kind: DockerMachineTemplate +metadata: + name: "${CLUSTER_NAME}-control-plane" +spec: + template: + spec: + # NOTE: If the Kubernetes version is changed in `clusterctl_upgrade_test.go` the image and SHA must be updated here. + customImage: "kindest/node:v1.23.17@sha256:f77f8cf0b30430ca4128cc7cfafece0c274a118cd0cdb251049664ace0dee4ff" + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" +--- +# KubeadmControlPlane referenced by the Cluster object with +# - the label kcp-adoption.step2, because it should be created in the second step of the kcp-adoption test. +kind: KubeadmControlPlane +apiVersion: controlplane.cluster.x-k8s.io/v1alpha4 +metadata: + name: "${CLUSTER_NAME}-control-plane" + labels: + kcp-adoption.step2: "" +spec: + replicas: ${CONTROL_PLANE_MACHINE_COUNT} + machineTemplate: + infrastructureRef: + kind: DockerMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + name: "${CLUSTER_NAME}-control-plane" + kubeadmConfigSpec: + clusterConfiguration: + controllerManager: + extraArgs: {enable-hostpath-provisioner: 'true'} + apiServer: + # host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied. + certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal] + initConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + # We have to pin the cgroupDriver to cgroupfs for Kubernetes < v1.24 because kind does not support systemd for those versions, but kubeadm >= 1.21 defaults to systemd. + # This cluster is used in tests where the Kubernetes version is < 1.24 + cgroup-driver: cgroupfs + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + joinConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + # We have to pin the cgroupDriver to cgroupfs for Kubernetes < v1.24 because kind does not support systemd for those versions, but kubeadm >= 1.21 defaults to systemd. + # This cluster is used in tests where the Kubernetes version is < 1.24 + cgroup-driver: cgroupfs + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + version: "${KUBERNETES_VERSION}" diff --git a/test/e2e/data/infrastructure-docker/v0.4/bases/crs.yaml b/test/e2e/data/infrastructure-docker/v0.4/bases/crs.yaml new file mode 100644 index 000000000000..7f8f9f9d46e1 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.4/bases/crs.yaml @@ -0,0 +1,24 @@ +--- +# ConfigMap object referenced by the ClusterResourceSet object and with +# the CNI resource defined in the test config file +apiVersion: v1 +kind: ConfigMap +metadata: + name: "cni-${CLUSTER_NAME}-crs-0" +data: ${CNI_RESOURCES} +binaryData: +--- +# ClusterResourceSet object with +# a selector that targets all the Cluster with label cni=${CLUSTER_NAME}-crs-0 +apiVersion: addons.cluster.x-k8s.io/v1alpha4 +kind: ClusterResourceSet +metadata: + name: "${CLUSTER_NAME}-crs-0" +spec: + strategy: ApplyOnce + clusterSelector: + matchLabels: + cni: "${CLUSTER_NAME}-crs-0" + resources: + - name: "cni-${CLUSTER_NAME}-crs-0" + kind: ConfigMap diff --git a/test/e2e/data/infrastructure-docker/v0.4/bases/md.yaml b/test/e2e/data/infrastructure-docker/v0.4/bases/md.yaml new file mode 100644 index 000000000000..e7c19d3c4497 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.4/bases/md.yaml @@ -0,0 +1,57 @@ +--- +# DockerMachineTemplate referenced by the MachineDeployment and with +# - extraMounts for the docker sock, thus allowing self-hosting test +apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 +kind: DockerMachineTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + # NOTE: If the Kubernetes version is changed in `clusterctl_upgrade_test.go` the image and SHA must be updated here. + customImage: "kindest/node:v1.23.17@sha256:f77f8cf0b30430ca4128cc7cfafece0c274a118cd0cdb251049664ace0dee4ff" + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" +--- +# KubeadmConfigTemplate referenced by the MachineDeployment +apiVersion: bootstrap.cluster.x-k8s.io/v1alpha4 +kind: KubeadmConfigTemplate +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + # We have to pin the cgroupDriver to cgroupfs for Kubernetes < v1.24 because kind does not support systemd for those versions, but kubeadm >= 1.21 defaults to systemd. + # This cluster is used in tests where the Kubernetes version is < 1.24 + cgroup-driver: cgroupfs + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" +--- +# MachineDeployment object +apiVersion: cluster.x-k8s.io/v1alpha4 +kind: MachineDeployment +metadata: + name: "${CLUSTER_NAME}-md-0" +spec: + clusterName: "${CLUSTER_NAME}" + replicas: ${WORKER_MACHINE_COUNT} + selector: + matchLabels: + template: + spec: + clusterName: "${CLUSTER_NAME}" + version: "${KUBERNETES_VERSION}" + bootstrap: + configRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: bootstrap.cluster.x-k8s.io/v1alpha4 + kind: KubeadmConfigTemplate + infrastructureRef: + name: "${CLUSTER_NAME}-md-0" + apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 + kind: DockerMachineTemplate diff --git a/test/e2e/data/infrastructure-docker/v0.4/cluster-template/kustomization.yaml b/test/e2e/data/infrastructure-docker/v0.4/cluster-template/kustomization.yaml new file mode 100644 index 000000000000..c7805717ecc1 --- /dev/null +++ b/test/e2e/data/infrastructure-docker/v0.4/cluster-template/kustomization.yaml @@ -0,0 +1,4 @@ +bases: +- ../bases/cluster-with-kcp.yaml +- ../bases/md.yaml +- ../bases/crs.yaml \ No newline at end of file diff --git a/test/e2e/data/shared/main/metadata.yaml b/test/e2e/data/shared/main/metadata.yaml index 2426ad4d0690..1b563a7141d9 100644 --- a/test/e2e/data/shared/main/metadata.yaml +++ b/test/e2e/data/shared/main/metadata.yaml @@ -24,4 +24,7 @@ releaseSeries: contract: v1beta1 - major: 0 minor: 4 - contract: v1alpha4 \ No newline at end of file + contract: v1alpha4 + - major: 0 + minor: 3 + contract: v1alpha3 diff --git a/test/e2e/data/shared/v0.3/metadata.yaml b/test/e2e/data/shared/v0.3/metadata.yaml new file mode 100644 index 000000000000..f3b4c3ef66bc --- /dev/null +++ b/test/e2e/data/shared/v0.3/metadata.yaml @@ -0,0 +1,9 @@ +apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3 +kind: Metadata +releaseSeries: + - major: 0 + minor: 3 + contract: v1alpha3 + - major: 0 + minor: 2 + contract: v1alpha2 \ No newline at end of file diff --git a/test/e2e/data/shared/v0.4/metadata.yaml b/test/e2e/data/shared/v0.4/metadata.yaml new file mode 100644 index 000000000000..318ea96c6eda --- /dev/null +++ b/test/e2e/data/shared/v0.4/metadata.yaml @@ -0,0 +1,12 @@ +apiVersion: clusterctl.cluster.x-k8s.io/v1alpha3 +kind: Metadata +releaseSeries: + - major: 0 + minor: 4 + contract: v1alpha4 + - major: 0 + minor: 3 + contract: v1alpha3 + - major: 0 + minor: 2 + contract: v1alpha2 \ No newline at end of file diff --git a/test/framework/clusterctl/client.go b/test/framework/clusterctl/client.go index 8419689de8ed..758018789006 100644 --- a/test/framework/clusterctl/client.go +++ b/test/framework/clusterctl/client.go @@ -26,6 +26,7 @@ import ( "path/filepath" "strings" + "github.com/blang/semver/v4" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -63,7 +64,7 @@ type InitInput struct { // Init calls clusterctl init with the list of providers defined in the local repository. func Init(ctx context.Context, input InitInput) { - args := calculateClusterCtlInitArgs(input) + args := calculateClusterCtlInitArgs(input, "") log.Logf("clusterctl %s", strings.Join(args, " ")) initOpt := clusterctlclient.InitOptions{ @@ -91,7 +92,7 @@ func Init(ctx context.Context, input InitInput) { // InitWithBinary uses clusterctl binary to run init with the list of providers defined in the local repository. func InitWithBinary(_ context.Context, binary string, input InitInput) { - args := calculateClusterCtlInitArgs(input) + args := calculateClusterCtlInitArgs(input, binary) log.Logf("clusterctl %s", strings.Join(args, " ")) cmd := exec.Command(binary, args...) //nolint:gosec // We don't care about command injection here. @@ -108,8 +109,20 @@ func InitWithBinary(_ context.Context, binary string, input InitInput) { Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl init:\nstdout:\n%s\nstderr:\n%s", string(out), stdErr) } -func calculateClusterCtlInitArgs(input InitInput) []string { +func calculateClusterCtlInitArgs(input InitInput, clusterctlBinaryPath string) []string { args := []string{"init", "--config", input.ClusterctlConfigPath, "--kubeconfig", input.KubeconfigPath} + + // If we use the clusterctl binary, only set --wait-providers for clusterctl >= v0.4.0. + if clusterctlBinaryPath != "" { + version, err := getClusterCtlVersion(clusterctlBinaryPath) + Expect(err).ToNot(HaveOccurred()) + if version.GTE(semver.MustParse("0.4.0")) { + args = append(args, "--wait-providers") + } + } else { + args = append(args, "--wait-providers") + } + if input.CoreProvider != "" { args = append(args, "--core", input.CoreProvider) } @@ -163,37 +176,8 @@ func Upgrade(ctx context.Context, input UpgradeInput) { input.ClusterctlConfigPath = outputPath } - // Check if the user want a custom upgrade - isCustomUpgrade := input.CoreProvider != "" || - len(input.BootstrapProviders) > 0 || - len(input.ControlPlaneProviders) > 0 || - len(input.InfrastructureProviders) > 0 || - len(input.IPAMProviders) > 0 || - len(input.RuntimeExtensionProviders) > 0 || - len(input.AddonProviders) > 0 - - Expect((input.Contract != "" && !isCustomUpgrade) || (input.Contract == "" && isCustomUpgrade)).To(BeTrue(), `Invalid arguments. Either the input.Contract parameter or at least one of the following providers has to be set: - input.CoreProvider, input.BootstrapProviders, input.ControlPlaneProviders, input.InfrastructureProviders, input.IPAMProviders, input.RuntimeExtensionProviders, input.AddonProviders`) - - if isCustomUpgrade { - log.Logf("clusterctl upgrade apply --core %s --bootstrap %s --control-plane %s --infrastructure %s --ipam %s --runtime-extension %s --addon %s --config %s --kubeconfig %s", - input.CoreProvider, - strings.Join(input.BootstrapProviders, ","), - strings.Join(input.ControlPlaneProviders, ","), - strings.Join(input.InfrastructureProviders, ","), - strings.Join(input.IPAMProviders, ","), - strings.Join(input.RuntimeExtensionProviders, ","), - strings.Join(input.AddonProviders, ","), - input.ClusterctlConfigPath, - input.KubeconfigPath, - ) - } else { - log.Logf("clusterctl upgrade apply --contract %s --config %s --kubeconfig %s", - input.Contract, - input.ClusterctlConfigPath, - input.KubeconfigPath, - ) - } + args := calculateClusterCtlUpgradeArgs(input) + log.Logf("clusterctl %s", strings.Join(args, " ")) upgradeOpt := clusterctlclient.ApplyUpgradeOptions{ Kubeconfig: clusterctlclient.Kubeconfig{ @@ -218,6 +202,79 @@ func Upgrade(ctx context.Context, input UpgradeInput) { Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl upgrade") } +// UpgradeWithBinary calls clusterctl upgrade apply with the list of providers defined in the local repository. +func UpgradeWithBinary(ctx context.Context, binary string, input UpgradeInput) { + if len(input.ClusterctlVariables) > 0 { + outputPath := filepath.Join(filepath.Dir(input.ClusterctlConfigPath), fmt.Sprintf("clusterctl-upgrade-config-%s.yaml", input.ClusterName)) + copyAndAmendClusterctlConfig(ctx, copyAndAmendClusterctlConfigInput{ + ClusterctlConfigPath: input.ClusterctlConfigPath, + OutputPath: outputPath, + Variables: input.ClusterctlVariables, + }) + input.ClusterctlConfigPath = outputPath + } + + args := calculateClusterCtlUpgradeArgs(input) + log.Logf("clusterctl %s", strings.Join(args, " ")) + + cmd := exec.Command(binary, args...) //nolint:gosec // We don't care about command injection here. + + out, err := cmd.CombinedOutput() + _ = os.WriteFile(filepath.Join(input.LogFolder, "clusterctl-upgrade.log"), out, 0644) //nolint:gosec // this is a log file to be shared via prow artifacts + var stdErr string + if err != nil { + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + stdErr = string(exitErr.Stderr) + } + } + Expect(err).ToNot(HaveOccurred(), "failed to run clusterctl upgrade apply:\nstdout:\n%s\nstderr:\n%s", string(out), stdErr) +} + +func calculateClusterCtlUpgradeArgs(input UpgradeInput) []string { + args := []string{"upgrade", "apply", "--config", input.ClusterctlConfigPath, "--kubeconfig", input.KubeconfigPath, "--wait-providers"} + + // Check if the user want a custom upgrade + isCustomUpgrade := input.CoreProvider != "" || + len(input.BootstrapProviders) > 0 || + len(input.ControlPlaneProviders) > 0 || + len(input.InfrastructureProviders) > 0 || + len(input.IPAMProviders) > 0 || + len(input.RuntimeExtensionProviders) > 0 || + len(input.AddonProviders) > 0 + + Expect((input.Contract != "" && !isCustomUpgrade) || (input.Contract == "" && isCustomUpgrade)).To(BeTrue(), `Invalid arguments. Either the input.Contract parameter or at least one of the following providers has to be set: + input.CoreProvider, input.BootstrapProviders, input.ControlPlaneProviders, input.InfrastructureProviders, input.IPAMProviders, input.RuntimeExtensionProviders, input.AddonProviders`) + + if isCustomUpgrade { + if input.CoreProvider != "" { + args = append(args, "--core", input.CoreProvider) + } + if len(input.BootstrapProviders) > 0 { + args = append(args, "--bootstrap", strings.Join(input.BootstrapProviders, ",")) + } + if len(input.ControlPlaneProviders) > 0 { + args = append(args, "--control-plane", strings.Join(input.ControlPlaneProviders, ",")) + } + if len(input.InfrastructureProviders) > 0 { + args = append(args, "--infrastructure", strings.Join(input.InfrastructureProviders, ",")) + } + if len(input.IPAMProviders) > 0 { + args = append(args, "--ipam", strings.Join(input.IPAMProviders, ",")) + } + if len(input.RuntimeExtensionProviders) > 0 { + args = append(args, "--runtime-extension", strings.Join(input.RuntimeExtensionProviders, ",")) + } + if len(input.AddonProviders) > 0 { + args = append(args, "--addon", strings.Join(input.AddonProviders, ",")) + } + } else { + args = append(args, "--contract", input.Contract) + } + + return args +} + // DeleteInput is the input for Delete. type DeleteInput struct { LogFolder string @@ -310,26 +367,55 @@ func ConfigCluster(ctx context.Context, input ConfigClusterInput) []byte { } // ConfigClusterWithBinary uses clusterctl binary to run config cluster or generate cluster. +// NOTE: This func detects the clusterctl version and uses config cluster or generate cluster +// accordingly. We can drop the detection when we don't have to support clusterctl v0.3.x anymore. func ConfigClusterWithBinary(_ context.Context, clusterctlBinaryPath string, input ConfigClusterInput) []byte { - log.Logf("clusterctl generate cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", - input.ClusterName, - valueOrDefault(input.InfrastructureProvider), - input.KubernetesVersion, - *input.ControlPlaneMachineCount, - *input.WorkerMachineCount, - valueOrDefault(input.Flavor), - ) - cmd := exec.Command(clusterctlBinaryPath, "generate", "cluster", //nolint:gosec // We don't care about command injection here. - input.ClusterName, - "--infrastructure", input.InfrastructureProvider, - "--kubernetes-version", input.KubernetesVersion, - "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), - "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), - "--flavor", input.Flavor, - "--target-namespace", input.Namespace, - "--config", input.ClusterctlConfigPath, - "--kubeconfig", input.KubeconfigPath, - ) + version, err := getClusterCtlVersion(clusterctlBinaryPath) + Expect(err).ToNot(HaveOccurred()) + clusterctlSupportsGenerateCluster := version.GTE(semver.MustParse("1.0.0")) + + var cmd *exec.Cmd + if clusterctlSupportsGenerateCluster { + log.Logf("clusterctl generate cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", + input.ClusterName, + valueOrDefault(input.InfrastructureProvider), + input.KubernetesVersion, + *input.ControlPlaneMachineCount, + *input.WorkerMachineCount, + valueOrDefault(input.Flavor), + ) + cmd = exec.Command(clusterctlBinaryPath, "generate", "cluster", //nolint:gosec // We don't care about command injection here. + input.ClusterName, + "--infrastructure", input.InfrastructureProvider, + "--kubernetes-version", input.KubernetesVersion, + "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), + "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), + "--flavor", input.Flavor, + "--target-namespace", input.Namespace, + "--config", input.ClusterctlConfigPath, + "--kubeconfig", input.KubeconfigPath, + ) + } else { + log.Logf("clusterctl config cluster %s --infrastructure %s --kubernetes-version %s --control-plane-machine-count %d --worker-machine-count %d --flavor %s", + input.ClusterName, + valueOrDefault(input.InfrastructureProvider), + input.KubernetesVersion, + *input.ControlPlaneMachineCount, + *input.WorkerMachineCount, + valueOrDefault(input.Flavor), + ) + cmd = exec.Command(clusterctlBinaryPath, "config", "cluster", //nolint:gosec // We don't care about command injection here. + input.ClusterName, + "--infrastructure", input.InfrastructureProvider, + "--kubernetes-version", input.KubernetesVersion, + "--control-plane-machine-count", fmt.Sprint(*input.ControlPlaneMachineCount), + "--worker-machine-count", fmt.Sprint(*input.WorkerMachineCount), + "--flavor", input.Flavor, + "--target-namespace", input.Namespace, + "--config", input.ClusterctlConfigPath, + "--kubeconfig", input.KubeconfigPath, + ) + } out, err := cmd.Output() _ = os.WriteFile(filepath.Join(input.LogFolder, fmt.Sprintf("%s-cluster-template.yaml", input.ClusterName)), out, 0644) //nolint:gosec // this is a log file to be shared via prow artifacts diff --git a/test/framework/clusterctl/clusterctl_helpers.go b/test/framework/clusterctl/clusterctl_helpers.go index d7060247bb8b..0434d04da819 100644 --- a/test/framework/clusterctl/clusterctl_helpers.go +++ b/test/framework/clusterctl/clusterctl_helpers.go @@ -144,6 +144,7 @@ type UpgradeManagementClusterAndWaitInput struct { RuntimeExtensionProviders []string AddonProviders []string LogFolder string + ClusterctlBinaryPath string } // UpgradeManagementClusterAndWait upgrades provider a management cluster using clusterctl, and waits for the cluster to be ready. @@ -165,7 +166,7 @@ func UpgradeManagementClusterAndWait(ctx context.Context, input UpgradeManagemen Expect(os.MkdirAll(input.LogFolder, 0750)).To(Succeed(), "Invalid argument. input.LogFolder can't be created for UpgradeManagementClusterAndWait") - Upgrade(ctx, UpgradeInput{ + upgradeInput := UpgradeInput{ ClusterctlConfigPath: input.ClusterctlConfigPath, ClusterctlVariables: input.ClusterctlVariables, ClusterName: input.ClusterProxy.GetName(), @@ -179,7 +180,13 @@ func UpgradeManagementClusterAndWait(ctx context.Context, input UpgradeManagemen RuntimeExtensionProviders: input.RuntimeExtensionProviders, AddonProviders: input.AddonProviders, LogFolder: input.LogFolder, - }) + } + + if input.ClusterctlBinaryPath != "" { + UpgradeWithBinary(ctx, input.ClusterctlBinaryPath, upgradeInput) + } else { + Upgrade(ctx, upgradeInput) + } client := input.ClusterProxy.GetClient() diff --git a/test/framework/clusterctl/repository.go b/test/framework/clusterctl/repository.go index 42c855a540b9..44c6bb6a7d61 100644 --- a/test/framework/clusterctl/repository.go +++ b/test/framework/clusterctl/repository.go @@ -189,9 +189,19 @@ func copyAndAmendClusterctlConfig(_ context.Context, input copyAndAmendClusterct } // AdjustConfigPathForBinary adjusts the clusterctlConfigPath in case the clusterctl version v1.3. -func AdjustConfigPathForBinary(clusterctPath, clusterctlConfigPath string) string { +func AdjustConfigPathForBinary(clusterctlBinaryPath, clusterctlConfigPath string) string { + version, err := getClusterCtlVersion(clusterctlBinaryPath) + Expect(err).ToNot(HaveOccurred()) + + if version.LT(semver.MustParse("1.3.0")) { + return strings.Replace(clusterctlConfigPath, clusterctlConfigFileName, clusterctlConfigV1_2FileName, -1) + } + return clusterctlConfigPath +} + +func getClusterCtlVersion(clusterctlBinaryPath string) (*semver.Version, error) { clusterctl := exec.NewCommand( - exec.WithCommand(clusterctPath), + exec.WithCommand(clusterctlBinaryPath), exec.WithArgs("version", "--output", "short"), ) stdout, stderr, err := clusterctl.Run(context.Background()) @@ -201,13 +211,9 @@ func AdjustConfigPathForBinary(clusterctPath, clusterctlConfigPath string) strin data := stdout version, err := semver.ParseTolerant(string(data)) if err != nil { - Expect(err).ToNot(HaveOccurred(), "clusterctl version returned an invalid version: %s", string(data)) - } - - if version.LT(semver.MustParse("1.3.0")) { - return strings.Replace(clusterctlConfigPath, clusterctlConfigFileName, clusterctlConfigV1_2FileName, -1) + return nil, fmt.Errorf("clusterctl version returned an invalid version: %s", string(data)) } - return clusterctlConfigPath + return &version, nil } // YAMLForComponentSource returns the YAML for the provided component source. diff --git a/test/framework/convenience.go b/test/framework/convenience.go index 3e0f62608692..07fa4422641d 100644 --- a/test/framework/convenience.go +++ b/test/framework/convenience.go @@ -20,6 +20,7 @@ import ( "reflect" appsv1 "k8s.io/api/apps/v1" + coordinationv1 "k8s.io/api/coordination/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" @@ -75,6 +76,10 @@ func TryAddDefaultSchemes(scheme *runtime.Scheme) { // Add rbac to the scheme. _ = rbacv1.AddToScheme(scheme) + + // Add coordination to the schema + // Note: This is e.g. used to trigger kube-controller-manager restarts by stealing its lease. + _ = coordinationv1.AddToScheme(scheme) } // ObjectToKind returns the Kind without the package prefix. Pass in a pointer to a struct diff --git a/test/infrastructure/docker/api/v1alpha3/condition_consts.go b/test/infrastructure/docker/api/v1alpha3/condition_consts.go new file mode 100644 index 000000000000..d6df6c7c8d5b --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/condition_consts.go @@ -0,0 +1,79 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + +// Conditions and condition Reasons for the DockerMachine object. + +const ( + // ContainerProvisionedCondition documents the status of the provisioning of the container + // generated by a DockerMachine. + // + // NOTE: When the container provisioning starts the process completes almost immediately and within + // the same reconciliation, so the user will always see a transition from Wait to Provisioned without + // having evidence that the operation is started/is in progress. + ContainerProvisionedCondition clusterv1alpha3.ConditionType = "ContainerProvisioned" + + // WaitingForClusterInfrastructureReason (Severity=Info) documents a DockerMachine waiting for the cluster + // infrastructure to be ready before starting to create the container that provides the DockerMachine + // infrastructure. + WaitingForClusterInfrastructureReason = "WaitingForClusterInfrastructure" + + // WaitingForBootstrapDataReason (Severity=Info) documents a DockerMachine waiting for the bootstrap + // script to be ready before starting to create the container that provides the DockerMachine infrastructure. + WaitingForBootstrapDataReason = "WaitingForBootstrapData" + + // ContainerProvisioningFailedReason (Severity=Warning) documents a DockerMachine controller detecting + // an error while provisioning the container that provides the DockerMachine infrastructure; those kind of + // errors are usually transient and failed provisioning are automatically re-tried by the controller. + ContainerProvisioningFailedReason = "ContainerProvisioningFailed" +) + +const ( + // BootstrapExecSucceededCondition provide an observation of the DockerMachine bootstrap process. + // The condition gets generated after ContainerProvisionedCondition is True. + // + // NOTE as a difference from other providers, container provisioning and bootstrap are directly managed + // by the DockerMachine controller (not by cloud-init). + BootstrapExecSucceededCondition clusterv1alpha3.ConditionType = "BootstrapExecSucceeded" + + // BootstrappingReason documents (Severity=Info) a DockerMachine currently executing the bootstrap + // script that creates the Kubernetes node on the newly provisioned machine infrastructure. + BootstrappingReason = "Bootstrapping" + + // BootstrapFailedReason documents (Severity=Warning) a DockerMachine controller detecting an error while + // bootstrapping the Kubernetes node on the machine just provisioned; those kind of errors are usually + // transient and failed bootstrap are automatically re-tried by the controller. + BootstrapFailedReason = "BootstrapFailed" +) + +// Conditions and condition Reasons for the DockerCluster object. + +const ( + // LoadBalancerAvailableCondition documents the availability of the container that implements the cluster load balancer. + // + // NOTE: When the load balancer provisioning starts the process completes almost immediately and within + // the same reconciliation, so the user will always see a transition from no condition to available without + // having evidence that the operation is started/is in progress. + LoadBalancerAvailableCondition clusterv1alpha3.ConditionType = "LoadBalancerAvailable" + + // LoadBalancerProvisioningFailedReason (Severity=Warning) documents a DockerCluster controller detecting + // an error while provisioning the container that provides the cluster load balancer.; those kind of + // errors are usually transient and failed provisioning are automatically re-tried by the controller. + LoadBalancerProvisioningFailedReason = "LoadBalancerProvisioningFailed" +) diff --git a/test/infrastructure/docker/api/v1alpha3/conversion.go b/test/infrastructure/docker/api/v1alpha3/conversion.go new file mode 100644 index 000000000000..ba133d350891 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/conversion.go @@ -0,0 +1,160 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + infrav1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *DockerCluster) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerCluster) + + if err := Convert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &infrav1.DockerCluster{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + if restored.Spec.LoadBalancer.ImageRepository != "" { + dst.Spec.LoadBalancer.ImageRepository = restored.Spec.LoadBalancer.ImageRepository + } + + if restored.Spec.LoadBalancer.ImageTag != "" { + dst.Spec.LoadBalancer.ImageTag = restored.Spec.LoadBalancer.ImageTag + } + + if restored.Spec.LoadBalancer.CustomHAProxyConfigTemplateRef != nil { + dst.Spec.LoadBalancer.CustomHAProxyConfigTemplateRef = restored.Spec.LoadBalancer.CustomHAProxyConfigTemplateRef + } + + return nil +} + +func (dst *DockerCluster) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerCluster) + + if err := Convert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *DockerClusterList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerClusterList) + + return Convert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList(src, dst, nil) +} + +func (dst *DockerClusterList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerClusterList) + + return Convert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList(src, dst, nil) +} + +func (src *DockerMachine) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerMachine) + + return Convert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(src, dst, nil) +} + +func (dst *DockerMachine) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerMachine) + + return Convert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(src, dst, nil) +} + +func (src *DockerMachineList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerMachineList) + + return Convert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList(src, dst, nil) +} + +func (dst *DockerMachineList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerMachineList) + + return Convert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList(src, dst, nil) +} + +func (src *DockerMachineTemplate) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerMachineTemplate) + + if err := Convert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &infrav1.DockerMachineTemplate{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Spec.Template.ObjectMeta = restored.Spec.Template.ObjectMeta + + return nil +} + +func (dst *DockerMachineTemplate) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerMachineTemplate) + + if err := Convert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +func (src *DockerMachineTemplateList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infrav1.DockerMachineTemplateList) + + return Convert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList(src, dst, nil) +} + +func (dst *DockerMachineTemplateList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infrav1.DockerMachineTemplateList) + + return Convert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList(src, dst, nil) +} + +// Convert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec is an autogenerated conversion function. +func Convert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(in *infrav1.DockerClusterSpec, out *DockerClusterSpec, s apiconversion.Scope) error { + // DockerClusterSpec.LoadBalancer was added in v1alpha4, so automatic conversion is not possible + return autoConvert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(in, out, s) +} + +func Convert_v1beta1_DockerMachineTemplateResource_To_v1alpha3_DockerMachineTemplateResource(in *infrav1.DockerMachineTemplateResource, out *DockerMachineTemplateResource, s apiconversion.Scope) error { + // NOTE: custom conversion func is required because spec.template.metadata has been added in v1beta1. + return autoConvert_v1beta1_DockerMachineTemplateResource_To_v1alpha3_DockerMachineTemplateResource(in, out, s) +} diff --git a/test/infrastructure/docker/api/v1alpha3/conversion_test.go b/test/infrastructure/docker/api/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..234cdc14c917 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/conversion_test.go @@ -0,0 +1,41 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + infrav1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for DockerCluster", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &infrav1.DockerCluster{}, + Spoke: &DockerCluster{}, + })) + + t.Run("for DockerMachine", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &infrav1.DockerMachine{}, + Spoke: &DockerMachine{}, + })) + + t.Run("for DockerMachineTemplate", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &infrav1.DockerMachineTemplate{}, + Spoke: &DockerMachineTemplate{}, + })) +} diff --git a/test/infrastructure/docker/api/v1alpha3/doc.go b/test/infrastructure/docker/api/v1alpha3/doc.go new file mode 100644 index 000000000000..65693f9dc4f9 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/test/infrastructure/docker/api/v1alpha3/dockercluster_types.go b/test/infrastructure/docker/api/v1alpha3/dockercluster_types.go new file mode 100644 index 000000000000..dc00714de394 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/dockercluster_types.go @@ -0,0 +1,111 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +const ( + // ClusterFinalizer allows DockerClusterReconciler to clean up resources associated with DockerCluster before + // removing it from the apiserver. + ClusterFinalizer = "dockercluster.infrastructure.cluster.x-k8s.io" +) + +// DockerClusterSpec defines the desired state of DockerCluster. +type DockerClusterSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ControlPlaneEndpoint represents the endpoint used to communicate with the control plane. + // +optional + ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint"` + + // FailureDomains are not usulaly defined on the spec. + // The docker provider is special since failure domains don't mean anything in a local docker environment. + // Instead, the docker cluster controller will simply copy these into the Status and allow the Cluster API + // controllers to do what they will with the defined failure domains. + // +optional + FailureDomains clusterv1alpha3.FailureDomains `json:"failureDomains,omitempty"` +} + +// DockerClusterStatus defines the observed state of DockerCluster. +type DockerClusterStatus struct { + // Ready denotes that the docker cluster (infrastructure) is ready. + Ready bool `json:"ready"` + + // FailureDomains don't mean much in CAPD since it's all local, but we can see how the rest of cluster API + // will use this if we populate it. + FailureDomains clusterv1alpha3.FailureDomains `json:"failureDomains,omitempty"` + + // Conditions defines current service state of the DockerCluster. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// APIEndpoint represents a reachable Kubernetes API endpoint. +type APIEndpoint struct { + // Host is the hostname on which the API server is serving. + Host string `json:"host"` + + // Port is the port on which the API server is serving. + Port int `json:"port"` +} + +// +kubebuilder:resource:path=dockerclusters,scope=Namespaced,categories=cluster-api +// +kubebuilder:subresource:status +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion + +// DockerCluster is the Schema for the dockerclusters API. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerCluster struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DockerClusterSpec `json:"spec,omitempty"` + Status DockerClusterStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (c *DockerCluster) GetConditions() clusterv1alpha3.Conditions { + return c.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (c *DockerCluster) SetConditions(conditions clusterv1alpha3.Conditions) { + c.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// DockerClusterList contains a list of DockerCluster. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerClusterList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []DockerCluster `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &DockerCluster{}, &DockerClusterList{}) +} diff --git a/test/infrastructure/docker/api/v1alpha3/dockermachine_types.go b/test/infrastructure/docker/api/v1alpha3/dockermachine_types.go new file mode 100644 index 000000000000..901d941c53d8 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/dockermachine_types.go @@ -0,0 +1,134 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +const ( + // MachineFinalizer allows ReconcileDockerMachine to clean up resources associated with AWSMachine before + // removing it from the apiserver. + MachineFinalizer = "dockermachine.infrastructure.cluster.x-k8s.io" +) + +// DockerMachineSpec defines the desired state of DockerMachine. +type DockerMachineSpec struct { + // ProviderID will be the container name in ProviderID format (docker:////) + // +optional + ProviderID *string `json:"providerID,omitempty"` + + // CustomImage allows customizing the container image that is used for + // running the machine + // +optional + CustomImage string `json:"customImage,omitempty"` + + // PreLoadImages allows to pre-load images in a newly created machine. This can be used to + // speed up tests by avoiding e.g. to download CNI images on all the containers. + // +optional + PreLoadImages []string `json:"preLoadImages,omitempty"` + + // ExtraMounts describes additional mount points for the node container + // These may be used to bind a hostPath + // +optional + ExtraMounts []Mount `json:"extraMounts,omitempty"` + + // Bootstrapped is true when the kubeadm bootstrapping has been run + // against this machine + // +optional + Bootstrapped bool `json:"bootstrapped,omitempty"` +} + +// Mount specifies a host volume to mount into a container. +// This is a simplified version of kind v1alpha4.Mount types. +type Mount struct { + // Path of the mount within the container. + ContainerPath string `json:"containerPath,omitempty"` + + // Path of the mount on the host. If the hostPath doesn't exist, then runtimes + // should report error. If the hostpath is a symbolic link, runtimes should + // follow the symlink and mount the real destination to container. + HostPath string `json:"hostPath,omitempty"` + + // If set, the mount is read-only. + // +optional + Readonly bool `json:"readOnly,omitempty"` +} + +// DockerMachineStatus defines the observed state of DockerMachine. +type DockerMachineStatus struct { + // Ready denotes that the machine (docker container) is ready + // +optional + Ready bool `json:"ready"` + + // LoadBalancerConfigured denotes that the machine has been + // added to the load balancer + // +optional + LoadBalancerConfigured bool `json:"loadBalancerConfigured,omitempty"` + + // Addresses contains the associated addresses for the docker machine. + // +optional + Addresses []clusterv1alpha3.MachineAddress `json:"addresses,omitempty"` + + // Conditions defines current service state of the DockerMachine. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// +kubebuilder:resource:path=dockermachines,scope=Namespaced,categories=cluster-api +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:subresource:status + +// DockerMachine is the Schema for the dockermachines API. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachine struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DockerMachineSpec `json:"spec,omitempty"` + Status DockerMachineStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (c *DockerMachine) GetConditions() clusterv1alpha3.Conditions { + return c.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (c *DockerMachine) SetConditions(conditions clusterv1alpha3.Conditions) { + c.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// DockerMachineList contains a list of DockerMachine. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachineList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []DockerMachine `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &DockerMachine{}, &DockerMachineList{}) +} diff --git a/test/infrastructure/docker/api/v1alpha3/dockermachinetemplate_types.go b/test/infrastructure/docker/api/v1alpha3/dockermachinetemplate_types.go new file mode 100644 index 000000000000..cfd2b5b5f500 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/dockermachinetemplate_types.go @@ -0,0 +1,62 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// DockerMachineTemplateSpec defines the desired state of DockerMachineTemplate. +type DockerMachineTemplateSpec struct { + Template DockerMachineTemplateResource `json:"template"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:resource:path=dockermachinetemplates,scope=Namespaced,categories=cluster-api + +// DockerMachineTemplate is the Schema for the dockermachinetemplates API. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachineTemplate struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DockerMachineTemplateSpec `json:"spec,omitempty"` +} + +// +kubebuilder:object:root=true + +// DockerMachineTemplateList contains a list of DockerMachineTemplate. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachineTemplateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []DockerMachineTemplate `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &DockerMachineTemplate{}, &DockerMachineTemplateList{}) +} + +// DockerMachineTemplateResource describes the data needed to create a DockerMachine from a template. +type DockerMachineTemplateResource struct { + // Spec is the specification of the desired behavior of the machine. + Spec DockerMachineSpec `json:"spec"` +} diff --git a/test/infrastructure/docker/api/v1alpha3/groupversion_info.go b/test/infrastructure/docker/api/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..65aa7c596d00 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/groupversion_info.go @@ -0,0 +1,48 @@ +/* +Copyright 2019 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the infrastructure v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=infrastructure.cluster.x-k8s.io +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "infrastructure.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = schemeBuilder.AddToScheme + + objectTypes = []runtime.Object{} + + // localSchemeBuilder is used for type conversions. + localSchemeBuilder = schemeBuilder +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, objectTypes...) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/test/infrastructure/docker/api/v1alpha3/zz_generated.conversion.go b/test/infrastructure/docker/api/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..537ae2d6ce40 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,696 @@ +//go:build !ignore_autogenerated_capd +// +build !ignore_autogenerated_capd + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + v1beta1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*APIEndpoint)(nil), (*v1beta1.APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(a.(*APIEndpoint), b.(*v1beta1.APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.APIEndpoint)(nil), (*APIEndpoint)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(a.(*v1beta1.APIEndpoint), b.(*APIEndpoint), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerCluster)(nil), (*v1beta1.DockerCluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(a.(*DockerCluster), b.(*v1beta1.DockerCluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerCluster)(nil), (*DockerCluster)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(a.(*v1beta1.DockerCluster), b.(*DockerCluster), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerClusterList)(nil), (*v1beta1.DockerClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList(a.(*DockerClusterList), b.(*v1beta1.DockerClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerClusterList)(nil), (*DockerClusterList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList(a.(*v1beta1.DockerClusterList), b.(*DockerClusterList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerClusterSpec)(nil), (*v1beta1.DockerClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec(a.(*DockerClusterSpec), b.(*v1beta1.DockerClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerClusterStatus)(nil), (*v1beta1.DockerClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus(a.(*DockerClusterStatus), b.(*v1beta1.DockerClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerClusterStatus)(nil), (*DockerClusterStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus(a.(*v1beta1.DockerClusterStatus), b.(*DockerClusterStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachine)(nil), (*v1beta1.DockerMachine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(a.(*DockerMachine), b.(*v1beta1.DockerMachine), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachine)(nil), (*DockerMachine)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(a.(*v1beta1.DockerMachine), b.(*DockerMachine), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineList)(nil), (*v1beta1.DockerMachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList(a.(*DockerMachineList), b.(*v1beta1.DockerMachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineList)(nil), (*DockerMachineList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList(a.(*v1beta1.DockerMachineList), b.(*DockerMachineList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineSpec)(nil), (*v1beta1.DockerMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(a.(*DockerMachineSpec), b.(*v1beta1.DockerMachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineSpec)(nil), (*DockerMachineSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(a.(*v1beta1.DockerMachineSpec), b.(*DockerMachineSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineStatus)(nil), (*v1beta1.DockerMachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus(a.(*DockerMachineStatus), b.(*v1beta1.DockerMachineStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineStatus)(nil), (*DockerMachineStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus(a.(*v1beta1.DockerMachineStatus), b.(*DockerMachineStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineTemplate)(nil), (*v1beta1.DockerMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(a.(*DockerMachineTemplate), b.(*v1beta1.DockerMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineTemplate)(nil), (*DockerMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(a.(*v1beta1.DockerMachineTemplate), b.(*DockerMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineTemplateList)(nil), (*v1beta1.DockerMachineTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList(a.(*DockerMachineTemplateList), b.(*v1beta1.DockerMachineTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineTemplateList)(nil), (*DockerMachineTemplateList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList(a.(*v1beta1.DockerMachineTemplateList), b.(*DockerMachineTemplateList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineTemplateResource)(nil), (*v1beta1.DockerMachineTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource(a.(*DockerMachineTemplateResource), b.(*v1beta1.DockerMachineTemplateResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachineTemplateSpec)(nil), (*v1beta1.DockerMachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec(a.(*DockerMachineTemplateSpec), b.(*v1beta1.DockerMachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachineTemplateSpec)(nil), (*DockerMachineTemplateSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec(a.(*v1beta1.DockerMachineTemplateSpec), b.(*DockerMachineTemplateSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Mount)(nil), (*v1beta1.Mount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_Mount_To_v1beta1_Mount(a.(*Mount), b.(*v1beta1.Mount), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.Mount)(nil), (*Mount)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_Mount_To_v1alpha3_Mount(a.(*v1beta1.Mount), b.(*Mount), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.DockerClusterSpec)(nil), (*DockerClusterSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(a.(*v1beta1.DockerClusterSpec), b.(*DockerClusterSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.DockerMachineTemplateResource)(nil), (*DockerMachineTemplateResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachineTemplateResource_To_v1alpha3_DockerMachineTemplateResource(a.(*v1beta1.DockerMachineTemplateResource), b.(*DockerMachineTemplateResource), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + out.Host = in.Host + out.Port = in.Port + return nil +} + +// Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint is an autogenerated conversion function. +func Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in *APIEndpoint, out *v1beta1.APIEndpoint, s conversion.Scope) error { + return autoConvert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(in, out, s) +} + +func autoConvert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + out.Host = in.Host + out.Port = in.Port + return nil +} + +// Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint is an autogenerated conversion function. +func Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in *v1beta1.APIEndpoint, out *APIEndpoint, s conversion.Scope) error { + return autoConvert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(in, out, s) +} + +func autoConvert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(in *DockerCluster, out *v1beta1.DockerCluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster is an autogenerated conversion function. +func Convert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(in *DockerCluster, out *v1beta1.DockerCluster, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(in, out, s) +} + +func autoConvert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(in *v1beta1.DockerCluster, out *DockerCluster, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster is an autogenerated conversion function. +func Convert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(in *v1beta1.DockerCluster, out *DockerCluster, s conversion.Scope) error { + return autoConvert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(in, out, s) +} + +func autoConvert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList(in *DockerClusterList, out *v1beta1.DockerClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.DockerCluster, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_DockerCluster_To_v1beta1_DockerCluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList is an autogenerated conversion function. +func Convert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList(in *DockerClusterList, out *v1beta1.DockerClusterList, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerClusterList_To_v1beta1_DockerClusterList(in, out, s) +} + +func autoConvert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList(in *v1beta1.DockerClusterList, out *DockerClusterList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerCluster, len(*in)) + for i := range *in { + if err := Convert_v1beta1_DockerCluster_To_v1alpha3_DockerCluster(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList is an autogenerated conversion function. +func Convert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList(in *v1beta1.DockerClusterList, out *DockerClusterList, s conversion.Scope) error { + return autoConvert_v1beta1_DockerClusterList_To_v1alpha3_DockerClusterList(in, out, s) +} + +func autoConvert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec(in *DockerClusterSpec, out *v1beta1.DockerClusterSpec, s conversion.Scope) error { + if err := Convert_v1alpha3_APIEndpoint_To_v1beta1_APIEndpoint(&in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint, s); err != nil { + return err + } + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(apiv1beta1.FailureDomains, len(*in)) + for key, val := range *in { + newVal := new(apiv1beta1.FailureDomainSpec) + if err := corev1alpha3.Convert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(&val, newVal, s); err != nil { + return err + } + (*out)[key] = *newVal + } + } else { + out.FailureDomains = nil + } + return nil +} + +// Convert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec is an autogenerated conversion function. +func Convert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec(in *DockerClusterSpec, out *v1beta1.DockerClusterSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerClusterSpec_To_v1beta1_DockerClusterSpec(in, out, s) +} + +func autoConvert_v1beta1_DockerClusterSpec_To_v1alpha3_DockerClusterSpec(in *v1beta1.DockerClusterSpec, out *DockerClusterSpec, s conversion.Scope) error { + if err := Convert_v1beta1_APIEndpoint_To_v1alpha3_APIEndpoint(&in.ControlPlaneEndpoint, &out.ControlPlaneEndpoint, s); err != nil { + return err + } + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(corev1alpha3.FailureDomains, len(*in)) + for key, val := range *in { + newVal := new(corev1alpha3.FailureDomainSpec) + if err := corev1alpha3.Convert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(&val, newVal, s); err != nil { + return err + } + (*out)[key] = *newVal + } + } else { + out.FailureDomains = nil + } + // WARNING: in.LoadBalancer requires manual conversion: does not exist in peer-type + return nil +} + +func autoConvert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus(in *DockerClusterStatus, out *v1beta1.DockerClusterStatus, s conversion.Scope) error { + out.Ready = in.Ready + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(apiv1beta1.FailureDomains, len(*in)) + for key, val := range *in { + newVal := new(apiv1beta1.FailureDomainSpec) + if err := corev1alpha3.Convert_v1alpha3_FailureDomainSpec_To_v1beta1_FailureDomainSpec(&val, newVal, s); err != nil { + return err + } + (*out)[key] = *newVal + } + } else { + out.FailureDomains = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus is an autogenerated conversion function. +func Convert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus(in *DockerClusterStatus, out *v1beta1.DockerClusterStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerClusterStatus_To_v1beta1_DockerClusterStatus(in, out, s) +} + +func autoConvert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus(in *v1beta1.DockerClusterStatus, out *DockerClusterStatus, s conversion.Scope) error { + out.Ready = in.Ready + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(corev1alpha3.FailureDomains, len(*in)) + for key, val := range *in { + newVal := new(corev1alpha3.FailureDomainSpec) + if err := corev1alpha3.Convert_v1beta1_FailureDomainSpec_To_v1alpha3_FailureDomainSpec(&val, newVal, s); err != nil { + return err + } + (*out)[key] = *newVal + } + } else { + out.FailureDomains = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus is an autogenerated conversion function. +func Convert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus(in *v1beta1.DockerClusterStatus, out *DockerClusterStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DockerClusterStatus_To_v1alpha3_DockerClusterStatus(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(in *DockerMachine, out *v1beta1.DockerMachine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(in *DockerMachine, out *v1beta1.DockerMachine, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(in, out, s) +} + +func autoConvert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(in *v1beta1.DockerMachine, out *DockerMachine, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine is an autogenerated conversion function. +func Convert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(in *v1beta1.DockerMachine, out *DockerMachine, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList(in *DockerMachineList, out *v1beta1.DockerMachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.DockerMachine, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_DockerMachine_To_v1beta1_DockerMachine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList(in *DockerMachineList, out *v1beta1.DockerMachineList, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineList_To_v1beta1_DockerMachineList(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList(in *v1beta1.DockerMachineList, out *DockerMachineList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachine, len(*in)) + for i := range *in { + if err := Convert_v1beta1_DockerMachine_To_v1alpha3_DockerMachine(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList(in *v1beta1.DockerMachineList, out *DockerMachineList, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineList_To_v1alpha3_DockerMachineList(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(in *DockerMachineSpec, out *v1beta1.DockerMachineSpec, s conversion.Scope) error { + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.CustomImage = in.CustomImage + out.PreLoadImages = *(*[]string)(unsafe.Pointer(&in.PreLoadImages)) + out.ExtraMounts = *(*[]v1beta1.Mount)(unsafe.Pointer(&in.ExtraMounts)) + out.Bootstrapped = in.Bootstrapped + return nil +} + +// Convert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(in *DockerMachineSpec, out *v1beta1.DockerMachineSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(in *v1beta1.DockerMachineSpec, out *DockerMachineSpec, s conversion.Scope) error { + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.CustomImage = in.CustomImage + out.PreLoadImages = *(*[]string)(unsafe.Pointer(&in.PreLoadImages)) + out.ExtraMounts = *(*[]Mount)(unsafe.Pointer(&in.ExtraMounts)) + out.Bootstrapped = in.Bootstrapped + return nil +} + +// Convert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(in *v1beta1.DockerMachineSpec, out *DockerMachineSpec, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus(in *DockerMachineStatus, out *v1beta1.DockerMachineStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.LoadBalancerConfigured = in.LoadBalancerConfigured + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]apiv1beta1.MachineAddress, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus(in *DockerMachineStatus, out *v1beta1.DockerMachineStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineStatus_To_v1beta1_DockerMachineStatus(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus(in *v1beta1.DockerMachineStatus, out *DockerMachineStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.LoadBalancerConfigured = in.LoadBalancerConfigured + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]corev1alpha3.MachineAddress, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus(in *v1beta1.DockerMachineStatus, out *DockerMachineStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineStatus_To_v1alpha3_DockerMachineStatus(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(in *DockerMachineTemplate, out *v1beta1.DockerMachineTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(in *DockerMachineTemplate, out *v1beta1.DockerMachineTemplate, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(in *v1beta1.DockerMachineTemplate, out *DockerMachineTemplate, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(in *v1beta1.DockerMachineTemplate, out *DockerMachineTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList(in *DockerMachineTemplateList, out *v1beta1.DockerMachineTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.DockerMachineTemplate, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_DockerMachineTemplate_To_v1beta1_DockerMachineTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList(in *DockerMachineTemplateList, out *v1beta1.DockerMachineTemplateList, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineTemplateList_To_v1beta1_DockerMachineTemplateList(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList(in *v1beta1.DockerMachineTemplateList, out *DockerMachineTemplateList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachineTemplate, len(*in)) + for i := range *in { + if err := Convert_v1beta1_DockerMachineTemplate_To_v1alpha3_DockerMachineTemplate(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList(in *v1beta1.DockerMachineTemplateList, out *DockerMachineTemplateList, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineTemplateList_To_v1alpha3_DockerMachineTemplateList(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource(in *DockerMachineTemplateResource, out *v1beta1.DockerMachineTemplateResource, s conversion.Scope) error { + if err := Convert_v1alpha3_DockerMachineSpec_To_v1beta1_DockerMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource(in *DockerMachineTemplateResource, out *v1beta1.DockerMachineTemplateResource, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineTemplateResource_To_v1alpha3_DockerMachineTemplateResource(in *v1beta1.DockerMachineTemplateResource, out *DockerMachineTemplateResource, s conversion.Scope) error { + // WARNING: in.ObjectMeta requires manual conversion: does not exist in peer-type + if err := Convert_v1beta1_DockerMachineSpec_To_v1alpha3_DockerMachineSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec(in *DockerMachineTemplateSpec, out *v1beta1.DockerMachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1alpha3_DockerMachineTemplateResource_To_v1beta1_DockerMachineTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec(in *DockerMachineTemplateSpec, out *v1beta1.DockerMachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachineTemplateSpec_To_v1beta1_DockerMachineTemplateSpec(in, out, s) +} + +func autoConvert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec(in *v1beta1.DockerMachineTemplateSpec, out *DockerMachineTemplateSpec, s conversion.Scope) error { + if err := Convert_v1beta1_DockerMachineTemplateResource_To_v1alpha3_DockerMachineTemplateResource(&in.Template, &out.Template, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec is an autogenerated conversion function. +func Convert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec(in *v1beta1.DockerMachineTemplateSpec, out *DockerMachineTemplateSpec, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachineTemplateSpec_To_v1alpha3_DockerMachineTemplateSpec(in, out, s) +} + +func autoConvert_v1alpha3_Mount_To_v1beta1_Mount(in *Mount, out *v1beta1.Mount, s conversion.Scope) error { + out.ContainerPath = in.ContainerPath + out.HostPath = in.HostPath + out.Readonly = in.Readonly + return nil +} + +// Convert_v1alpha3_Mount_To_v1beta1_Mount is an autogenerated conversion function. +func Convert_v1alpha3_Mount_To_v1beta1_Mount(in *Mount, out *v1beta1.Mount, s conversion.Scope) error { + return autoConvert_v1alpha3_Mount_To_v1beta1_Mount(in, out, s) +} + +func autoConvert_v1beta1_Mount_To_v1alpha3_Mount(in *v1beta1.Mount, out *Mount, s conversion.Scope) error { + out.ContainerPath = in.ContainerPath + out.HostPath = in.HostPath + out.Readonly = in.Readonly + return nil +} + +// Convert_v1beta1_Mount_To_v1alpha3_Mount is an autogenerated conversion function. +func Convert_v1beta1_Mount_To_v1alpha3_Mount(in *v1beta1.Mount, out *Mount, s conversion.Scope) error { + return autoConvert_v1beta1_Mount_To_v1alpha3_Mount(in, out, s) +} diff --git a/test/infrastructure/docker/api/v1alpha3/zz_generated.deepcopy.go b/test/infrastructure/docker/api/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..741d49e4f863 --- /dev/null +++ b/test/infrastructure/docker/api/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,373 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *APIEndpoint) DeepCopyInto(out *APIEndpoint) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIEndpoint. +func (in *APIEndpoint) DeepCopy() *APIEndpoint { + if in == nil { + return nil + } + out := new(APIEndpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerCluster) DeepCopyInto(out *DockerCluster) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerCluster. +func (in *DockerCluster) DeepCopy() *DockerCluster { + if in == nil { + return nil + } + out := new(DockerCluster) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerCluster) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerClusterList) DeepCopyInto(out *DockerClusterList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerCluster, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerClusterList. +func (in *DockerClusterList) DeepCopy() *DockerClusterList { + if in == nil { + return nil + } + out := new(DockerClusterList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerClusterList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerClusterSpec) DeepCopyInto(out *DockerClusterSpec) { + *out = *in + out.ControlPlaneEndpoint = in.ControlPlaneEndpoint + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(corev1alpha3.FailureDomains, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerClusterSpec. +func (in *DockerClusterSpec) DeepCopy() *DockerClusterSpec { + if in == nil { + return nil + } + out := new(DockerClusterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerClusterStatus) DeepCopyInto(out *DockerClusterStatus) { + *out = *in + if in.FailureDomains != nil { + in, out := &in.FailureDomains, &out.FailureDomains + *out = make(corev1alpha3.FailureDomains, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerClusterStatus. +func (in *DockerClusterStatus) DeepCopy() *DockerClusterStatus { + if in == nil { + return nil + } + out := new(DockerClusterStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachine) DeepCopyInto(out *DockerMachine) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachine. +func (in *DockerMachine) DeepCopy() *DockerMachine { + if in == nil { + return nil + } + out := new(DockerMachine) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachine) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineList) DeepCopyInto(out *DockerMachineList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachine, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineList. +func (in *DockerMachineList) DeepCopy() *DockerMachineList { + if in == nil { + return nil + } + out := new(DockerMachineList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachineList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineSpec) DeepCopyInto(out *DockerMachineSpec) { + *out = *in + if in.ProviderID != nil { + in, out := &in.ProviderID, &out.ProviderID + *out = new(string) + **out = **in + } + if in.PreLoadImages != nil { + in, out := &in.PreLoadImages, &out.PreLoadImages + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ExtraMounts != nil { + in, out := &in.ExtraMounts, &out.ExtraMounts + *out = make([]Mount, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineSpec. +func (in *DockerMachineSpec) DeepCopy() *DockerMachineSpec { + if in == nil { + return nil + } + out := new(DockerMachineSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineStatus) DeepCopyInto(out *DockerMachineStatus) { + *out = *in + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]corev1alpha3.MachineAddress, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineStatus. +func (in *DockerMachineStatus) DeepCopy() *DockerMachineStatus { + if in == nil { + return nil + } + out := new(DockerMachineStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineTemplate) DeepCopyInto(out *DockerMachineTemplate) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineTemplate. +func (in *DockerMachineTemplate) DeepCopy() *DockerMachineTemplate { + if in == nil { + return nil + } + out := new(DockerMachineTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachineTemplate) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineTemplateList) DeepCopyInto(out *DockerMachineTemplateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachineTemplate, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineTemplateList. +func (in *DockerMachineTemplateList) DeepCopy() *DockerMachineTemplateList { + if in == nil { + return nil + } + out := new(DockerMachineTemplateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachineTemplateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineTemplateResource) DeepCopyInto(out *DockerMachineTemplateResource) { + *out = *in + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineTemplateResource. +func (in *DockerMachineTemplateResource) DeepCopy() *DockerMachineTemplateResource { + if in == nil { + return nil + } + out := new(DockerMachineTemplateResource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachineTemplateSpec) DeepCopyInto(out *DockerMachineTemplateSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachineTemplateSpec. +func (in *DockerMachineTemplateSpec) DeepCopy() *DockerMachineTemplateSpec { + if in == nil { + return nil + } + out := new(DockerMachineTemplateSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Mount) DeepCopyInto(out *Mount) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Mount. +func (in *Mount) DeepCopy() *Mount { + if in == nil { + return nil + } + out := new(Mount) + in.DeepCopyInto(out) + return out +} diff --git a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockerclusters.yaml b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockerclusters.yaml index 9aa2144ed902..fc6e5771c6f6 100644 --- a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockerclusters.yaml +++ b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockerclusters.yaml @@ -16,6 +16,146 @@ spec: singular: dockercluster scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "DockerCluster is the Schema for the dockerclusters API. \n Deprecated: + This type will be removed in one of the next releases." + 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: DockerClusterSpec defines the desired state of DockerCluster. + properties: + controlPlaneEndpoint: + description: ControlPlaneEndpoint represents the endpoint used to + communicate with the control plane. + properties: + host: + description: Host is the hostname on which the API server is serving. + type: string + port: + description: Port is the port on which the API server is serving. + type: integer + required: + - host + - port + type: object + failureDomains: + additionalProperties: + description: FailureDomainSpec is the Schema for Cluster API failure + domains. It allows controllers to understand how many failure + domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an + infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain + is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains are not usulaly defined on the spec. The + docker provider is special since failure domains don't mean anything + in a local docker environment. Instead, the docker cluster controller + will simply copy these into the Status and allow the Cluster API + controllers to do what they will with the defined failure domains. + type: object + type: object + status: + description: DockerClusterStatus defines the observed state of DockerCluster. + properties: + conditions: + description: Conditions defines current service state of the DockerCluster. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + failureDomains: + additionalProperties: + description: FailureDomainSpec is the Schema for Cluster API failure + domains. It allows controllers to understand how many failure + domains a cluster can optionally span across. + properties: + attributes: + additionalProperties: + type: string + description: Attributes is a free form map of attributes an + infrastructure provider might use or require. + type: object + controlPlane: + description: ControlPlane determines if this failure domain + is suitable for use by control plane machines. + type: boolean + type: object + description: FailureDomains don't mean much in CAPD since it's all + local, but we can see how the rest of cluster API will use this + if we populate it. + type: object + ready: + description: Ready denotes that the docker cluster (infrastructure) + is ready. + type: boolean + required: + - ready + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of DockerCluster jsonPath: .metadata.creationTimestamp diff --git a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinepools.yaml b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinepools.yaml index d1f1d93a4b58..877a0a8bd0d4 100644 --- a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinepools.yaml +++ b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinepools.yaml @@ -16,6 +16,187 @@ spec: singular: dockermachinepool scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "DockerMachinePool is the Schema for the dockermachinepools API. + \n Deprecated: This type will be removed in one of the next releases." + 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: DockerMachinePoolSpec defines the desired state of DockerMachinePool. + properties: + providerID: + description: ProviderID is the identification ID of the Machine Pool + type: string + providerIDList: + description: ProviderIDList is the list of identification IDs of machine + instances managed by this Machine Pool + items: + type: string + type: array + template: + description: Template contains the details used to build a replica + machine within the Machine Pool + properties: + customImage: + description: CustomImage allows customizing the container image + that is used for running the machine + type: string + extraMounts: + description: ExtraMounts describes additional mount points for + the node container These may be used to bind a hostPath + items: + description: Mount specifies a host volume to mount into a container. + This is a simplified version of kind v1alpha4.Mount types. + properties: + containerPath: + description: Path of the mount within the container. + type: string + hostPath: + description: Path of the mount on the host. If the hostPath + doesn't exist, then runtimes should report error. If the + hostpath is a symbolic link, runtimes should follow the + symlink and mount the real destination to container. + type: string + readOnly: + description: If set, the mount is read-only. + type: boolean + type: object + type: array + preLoadImages: + description: PreLoadImages allows to pre-load images in a newly + created machine. This can be used to speed up tests by avoiding + e.g. to download CNI images on all the containers. + items: + type: string + type: array + type: object + type: object + status: + description: DockerMachinePoolStatus defines the observed state of DockerMachinePool. + properties: + conditions: + description: Conditions defines current service state of the DockerMachinePool. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + instances: + description: Instances contains the status for each instance in the + pool + items: + description: DockerMachinePoolInstanceStatus contains status information + about a DockerMachinePool. + properties: + addresses: + description: Addresses contains the associated addresses for + the docker machine. + items: + description: MachineAddress contains information for the node's + address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP + or InternalIP. + type: string + required: + - address + - type + type: object + type: array + bootstrapped: + description: Bootstrapped is true when the kubeadm bootstrapping + has been run against this machine + type: boolean + instanceName: + description: InstanceName is the identification of the Machine + Instance within the Machine Pool + type: string + providerID: + description: ProviderID is the provider identification of the + Machine Pool Instance + type: string + ready: + description: Ready denotes that the machine (docker container) + is ready + type: boolean + version: + description: Version defines the Kubernetes version for the + Machine Instance + type: string + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + ready: + description: Ready denotes that the machine pool is ready + type: boolean + replicas: + description: Replicas is the most recently observed number of replicas. + format: int32 + type: integer + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of DockerMachinePool jsonPath: .metadata.creationTimestamp diff --git a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachines.yaml b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachines.yaml index ab73711b202f..59733397eb4d 100644 --- a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachines.yaml +++ b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachines.yaml @@ -16,6 +16,149 @@ spec: singular: dockermachine scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "DockerMachine is the Schema for the dockermachines API. \n Deprecated: + This type will be removed in one of the next releases." + 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: DockerMachineSpec defines the desired state of DockerMachine. + properties: + bootstrapped: + description: Bootstrapped is true when the kubeadm bootstrapping has + been run against this machine + type: boolean + customImage: + description: CustomImage allows customizing the container image that + is used for running the machine + type: string + extraMounts: + description: ExtraMounts describes additional mount points for the + node container These may be used to bind a hostPath + items: + description: Mount specifies a host volume to mount into a container. + This is a simplified version of kind v1alpha4.Mount types. + properties: + containerPath: + description: Path of the mount within the container. + type: string + hostPath: + description: Path of the mount on the host. If the hostPath + doesn't exist, then runtimes should report error. If the hostpath + is a symbolic link, runtimes should follow the symlink and + mount the real destination to container. + type: string + readOnly: + description: If set, the mount is read-only. + type: boolean + type: object + type: array + preLoadImages: + description: PreLoadImages allows to pre-load images in a newly created + machine. This can be used to speed up tests by avoiding e.g. to + download CNI images on all the containers. + items: + type: string + type: array + providerID: + description: ProviderID will be the container name in ProviderID format + (docker:////) + type: string + type: object + status: + description: DockerMachineStatus defines the observed state of DockerMachine. + properties: + addresses: + description: Addresses contains the associated addresses for the docker + machine. + items: + description: MachineAddress contains information for the node's + address. + properties: + address: + description: The machine address. + type: string + type: + description: Machine address type, one of Hostname, ExternalIP + or InternalIP. + type: string + required: + - address + - type + type: object + type: array + conditions: + description: Conditions defines current service state of the DockerMachine. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - status + - type + type: object + type: array + loadBalancerConfigured: + description: LoadBalancerConfigured denotes that the machine has been + added to the load balancer + type: boolean + ready: + description: Ready denotes that the machine (docker container) is + ready + type: boolean + type: object + type: object + served: false + storage: false + subresources: + status: {} - additionalPrinterColumns: - description: Time duration since creation of DockerMachine jsonPath: .metadata.creationTimestamp diff --git a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinetemplates.yaml b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinetemplates.yaml index 29ad60adffea..4f2040536d7a 100644 --- a/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinetemplates.yaml +++ b/test/infrastructure/docker/config/crd/bases/infrastructure.cluster.x-k8s.io_dockermachinetemplates.yaml @@ -16,6 +16,88 @@ spec: singular: dockermachinetemplate scope: Namespaced versions: + - deprecated: true + name: v1alpha3 + schema: + openAPIV3Schema: + description: "DockerMachineTemplate is the Schema for the dockermachinetemplates + API. \n Deprecated: This type will be removed in one of the next releases." + 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: DockerMachineTemplateSpec defines the desired state of DockerMachineTemplate. + properties: + template: + description: DockerMachineTemplateResource describes the data needed + to create a DockerMachine from a template. + properties: + spec: + description: Spec is the specification of the desired behavior + of the machine. + properties: + bootstrapped: + description: Bootstrapped is true when the kubeadm bootstrapping + has been run against this machine + type: boolean + customImage: + description: CustomImage allows customizing the container + image that is used for running the machine + type: string + extraMounts: + description: ExtraMounts describes additional mount points + for the node container These may be used to bind a hostPath + items: + description: Mount specifies a host volume to mount into + a container. This is a simplified version of kind v1alpha4.Mount + types. + properties: + containerPath: + description: Path of the mount within the container. + type: string + hostPath: + description: Path of the mount on the host. If the hostPath + doesn't exist, then runtimes should report error. + If the hostpath is a symbolic link, runtimes should + follow the symlink and mount the real destination + to container. + type: string + readOnly: + description: If set, the mount is read-only. + type: boolean + type: object + type: array + preLoadImages: + description: PreLoadImages allows to pre-load images in a + newly created machine. This can be used to speed up tests + by avoiding e.g. to download CNI images on all the containers. + items: + type: string + type: array + providerID: + description: ProviderID will be the container name in ProviderID + format (docker:////) + type: string + type: object + required: + - spec + type: object + required: + - template + type: object + type: object + served: false + storage: false - additionalPrinterColumns: - description: Time duration since creation of DockerMachineTemplate jsonPath: .metadata.creationTimestamp diff --git a/test/infrastructure/docker/exp/api/v1alpha3/conversion.go b/test/infrastructure/docker/exp/api/v1alpha3/conversion.go new file mode 100644 index 000000000000..81c40e8c4601 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/conversion.go @@ -0,0 +1,72 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + infraexpv1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func (src *DockerMachinePool) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infraexpv1.DockerMachinePool) + + if err := Convert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(src, dst, nil); err != nil { + return err + } + + // Manually restore data. + restored := &infraexpv1.DockerMachinePool{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + dst.Status.InfrastructureMachineKind = restored.Status.InfrastructureMachineKind + + return nil +} + +func (dst *DockerMachinePool) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infraexpv1.DockerMachinePool) + + if err := Convert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion except for metadata + return utilconversion.MarshalData(src, dst) +} + +func (src *DockerMachinePoolList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*infraexpv1.DockerMachinePoolList) + + return Convert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList(src, dst, nil) +} + +func (dst *DockerMachinePoolList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*infraexpv1.DockerMachinePoolList) + + return Convert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList(src, dst, nil) +} + +// Convert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus(in *infraexpv1.DockerMachinePoolStatus, out *DockerMachinePoolStatus, s apiconversion.Scope) error { + // NOTE: custom conversion func is required because Status.InfrastructureMachineKind has been added in v1beta1. + return autoConvert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus(in, out, s) +} diff --git a/test/infrastructure/docker/exp/api/v1alpha3/conversion_test.go b/test/infrastructure/docker/exp/api/v1alpha3/conversion_test.go new file mode 100644 index 000000000000..9ece74966950 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/conversion_test.go @@ -0,0 +1,31 @@ +/* +Copyright 2021 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + "testing" + + infraexpv1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" +) + +func TestFuzzyConversion(t *testing.T) { + t.Run("for DockerMachinePool", utilconversion.FuzzTestFunc(utilconversion.FuzzTestFuncInput{ + Hub: &infraexpv1.DockerMachinePool{}, + Spoke: &DockerMachinePool{}, + })) +} diff --git a/test/infrastructure/docker/exp/api/v1alpha3/doc.go b/test/infrastructure/docker/exp/api/v1alpha3/doc.go new file mode 100644 index 000000000000..ae47f5c4da90 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/doc.go @@ -0,0 +1,21 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains the v1alpha3 API implementation. +// +k8s:conversion-gen=sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1 +// +// Deprecated: This package will be removed in one of the next releases. +package v1alpha3 diff --git a/test/infrastructure/docker/exp/api/v1alpha3/dockermachinepool_types.go b/test/infrastructure/docker/exp/api/v1alpha3/dockermachinepool_types.go new file mode 100644 index 000000000000..50c3fbb824d8 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/dockermachinepool_types.go @@ -0,0 +1,154 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + clusterv1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + infrav1alpha3 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha3" +) + +const ( + // MachinePoolFinalizer allows ReconcileDockerMachinePool to clean up resources. + MachinePoolFinalizer = "dockermachinepool.infrastructure.cluster.x-k8s.io" +) + +// DockerMachinePoolMachineTemplate defines the desired state of DockerMachine. +type DockerMachinePoolMachineTemplate struct { + // CustomImage allows customizing the container image that is used for + // running the machine + // +optional + CustomImage string `json:"customImage,omitempty"` + + // PreLoadImages allows to pre-load images in a newly created machine. This can be used to + // speed up tests by avoiding e.g. to download CNI images on all the containers. + // +optional + PreLoadImages []string `json:"preLoadImages,omitempty"` + + // ExtraMounts describes additional mount points for the node container + // These may be used to bind a hostPath + // +optional + ExtraMounts []infrav1alpha3.Mount `json:"extraMounts,omitempty"` +} + +// DockerMachinePoolSpec defines the desired state of DockerMachinePool. +type DockerMachinePoolSpec struct { + // Template contains the details used to build a replica machine within the Machine Pool + // +optional + Template DockerMachinePoolMachineTemplate `json:"template"` + + // ProviderID is the identification ID of the Machine Pool + // +optional + ProviderID string `json:"providerID,omitempty"` + + // ProviderIDList is the list of identification IDs of machine instances managed by this Machine Pool + //+optional + ProviderIDList []string `json:"providerIDList,omitempty"` +} + +// DockerMachinePoolStatus defines the observed state of DockerMachinePool. +type DockerMachinePoolStatus struct { + // Ready denotes that the machine pool is ready + // +optional + Ready bool `json:"ready"` + + // Replicas is the most recently observed number of replicas. + // +optional + Replicas int32 `json:"replicas"` + + // The generation observed by the deployment controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Instances contains the status for each instance in the pool + // +optional + Instances []DockerMachinePoolInstanceStatus `json:"instances,omitempty"` + + // Conditions defines current service state of the DockerMachinePool. + // +optional + Conditions clusterv1alpha3.Conditions `json:"conditions,omitempty"` +} + +// DockerMachinePoolInstanceStatus contains status information about a DockerMachinePool. +type DockerMachinePoolInstanceStatus struct { + // Addresses contains the associated addresses for the docker machine. + // +optional + Addresses []clusterv1alpha3.MachineAddress `json:"addresses,omitempty"` + + // InstanceName is the identification of the Machine Instance within the Machine Pool + InstanceName string `json:"instanceName,omitempty"` + + // ProviderID is the provider identification of the Machine Pool Instance + // +optional + ProviderID *string `json:"providerID,omitempty"` + + // Version defines the Kubernetes version for the Machine Instance + // +optional + Version *string `json:"version,omitempty"` + + // Ready denotes that the machine (docker container) is ready + // +optional + Ready bool `json:"ready"` + + // Bootstrapped is true when the kubeadm bootstrapping has been run + // against this machine + // +optional + Bootstrapped bool `json:"bootstrapped,omitempty"` +} + +// +kubebuilder:resource:path=dockermachinepools,scope=Namespaced,categories=cluster-api +// +kubebuilder:object:root=true +// +kubebuilder:unservedversion +// +kubebuilder:deprecatedversion +// +kubebuilder:subresource:status + +// DockerMachinePool is the Schema for the dockermachinepools API. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachinePool struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DockerMachinePoolSpec `json:"spec,omitempty"` + Status DockerMachinePoolStatus `json:"status,omitempty"` +} + +// GetConditions returns the set of conditions for this object. +func (c *DockerMachinePool) GetConditions() clusterv1alpha3.Conditions { + return c.Status.Conditions +} + +// SetConditions sets the conditions on this object. +func (c *DockerMachinePool) SetConditions(conditions clusterv1alpha3.Conditions) { + c.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// DockerMachinePoolList contains a list of DockerMachinePool. +// +// Deprecated: This type will be removed in one of the next releases. +type DockerMachinePoolList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []DockerMachinePool `json:"items"` +} + +func init() { + objectTypes = append(objectTypes, &DockerMachinePool{}, &DockerMachinePoolList{}) +} diff --git a/test/infrastructure/docker/exp/api/v1alpha3/groupversion_info.go b/test/infrastructure/docker/exp/api/v1alpha3/groupversion_info.go new file mode 100644 index 000000000000..26f17f0bf104 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/groupversion_info.go @@ -0,0 +1,48 @@ +/* +Copyright 2020 The Kubernetes Authors. + +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. +*/ + +// Package v1alpha3 contains API Schema definitions for the infrastructure v1alpha3 API group +// +kubebuilder:object:generate=true +// +groupName=infrastructure.cluster.x-k8s.io +package v1alpha3 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +var ( + // GroupVersion is group version used to register these objects. + GroupVersion = schema.GroupVersion{Group: "infrastructure.cluster.x-k8s.io", Version: "v1alpha3"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme. + schemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = schemeBuilder.AddToScheme + + objectTypes = []runtime.Object{} + + // localSchemeBuilder is used for type conversions. + localSchemeBuilder = schemeBuilder +) + +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(GroupVersion, objectTypes...) + metav1.AddToGroupVersion(scheme, GroupVersion) + return nil +} diff --git a/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.conversion.go b/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.conversion.go new file mode 100644 index 000000000000..15540f9e0138 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.conversion.go @@ -0,0 +1,344 @@ +//go:build !ignore_autogenerated_capd +// +build !ignore_autogenerated_capd + +/* +Copyright The Kubernetes Authors. + +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 conversion-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + unsafe "unsafe" + + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + apiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + apiv1alpha3 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha3" + dockerapiv1beta1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1" + v1beta1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*DockerMachinePool)(nil), (*v1beta1.DockerMachinePool)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(a.(*DockerMachinePool), b.(*v1beta1.DockerMachinePool), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachinePool)(nil), (*DockerMachinePool)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(a.(*v1beta1.DockerMachinePool), b.(*DockerMachinePool), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachinePoolInstanceStatus)(nil), (*v1beta1.DockerMachinePoolInstanceStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus(a.(*DockerMachinePoolInstanceStatus), b.(*v1beta1.DockerMachinePoolInstanceStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachinePoolInstanceStatus)(nil), (*DockerMachinePoolInstanceStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus(a.(*v1beta1.DockerMachinePoolInstanceStatus), b.(*DockerMachinePoolInstanceStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachinePoolList)(nil), (*v1beta1.DockerMachinePoolList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList(a.(*DockerMachinePoolList), b.(*v1beta1.DockerMachinePoolList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachinePoolList)(nil), (*DockerMachinePoolList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList(a.(*v1beta1.DockerMachinePoolList), b.(*DockerMachinePoolList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachinePoolMachineTemplate)(nil), (*v1beta1.DockerMachinePoolMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate(a.(*DockerMachinePoolMachineTemplate), b.(*v1beta1.DockerMachinePoolMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachinePoolMachineTemplate)(nil), (*DockerMachinePoolMachineTemplate)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate(a.(*v1beta1.DockerMachinePoolMachineTemplate), b.(*DockerMachinePoolMachineTemplate), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachinePoolSpec)(nil), (*v1beta1.DockerMachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec(a.(*DockerMachinePoolSpec), b.(*v1beta1.DockerMachinePoolSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1beta1.DockerMachinePoolSpec)(nil), (*DockerMachinePoolSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec(a.(*v1beta1.DockerMachinePoolSpec), b.(*DockerMachinePoolSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*DockerMachinePoolStatus)(nil), (*v1beta1.DockerMachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus(a.(*DockerMachinePoolStatus), b.(*v1beta1.DockerMachinePoolStatus), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1beta1.DockerMachinePoolStatus)(nil), (*DockerMachinePoolStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus(a.(*v1beta1.DockerMachinePoolStatus), b.(*DockerMachinePoolStatus), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(in *DockerMachinePool, out *v1beta1.DockerMachinePool, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(in *DockerMachinePool, out *v1beta1.DockerMachinePool, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(in *v1beta1.DockerMachinePool, out *DockerMachinePool, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(in *v1beta1.DockerMachinePool, out *DockerMachinePool, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus(in *DockerMachinePoolInstanceStatus, out *v1beta1.DockerMachinePoolInstanceStatus, s conversion.Scope) error { + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]apiv1beta1.MachineAddress, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_MachineAddress_To_v1beta1_MachineAddress(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + out.InstanceName = in.InstanceName + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.Version = (*string)(unsafe.Pointer(in.Version)) + out.Ready = in.Ready + out.Bootstrapped = in.Bootstrapped + return nil +} + +// Convert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus(in *DockerMachinePoolInstanceStatus, out *v1beta1.DockerMachinePoolInstanceStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus(in *v1beta1.DockerMachinePoolInstanceStatus, out *DockerMachinePoolInstanceStatus, s conversion.Scope) error { + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]corev1alpha3.MachineAddress, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_MachineAddress_To_v1alpha3_MachineAddress(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Addresses = nil + } + out.InstanceName = in.InstanceName + out.ProviderID = (*string)(unsafe.Pointer(in.ProviderID)) + out.Version = (*string)(unsafe.Pointer(in.Version)) + out.Ready = in.Ready + out.Bootstrapped = in.Bootstrapped + return nil +} + +// Convert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus(in *v1beta1.DockerMachinePoolInstanceStatus, out *DockerMachinePoolInstanceStatus, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList(in *DockerMachinePoolList, out *v1beta1.DockerMachinePoolList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1beta1.DockerMachinePool, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_DockerMachinePool_To_v1beta1_DockerMachinePool(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList(in *DockerMachinePoolList, out *v1beta1.DockerMachinePoolList, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePoolList_To_v1beta1_DockerMachinePoolList(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList(in *v1beta1.DockerMachinePoolList, out *DockerMachinePoolList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachinePool, len(*in)) + for i := range *in { + if err := Convert_v1beta1_DockerMachinePool_To_v1alpha3_DockerMachinePool(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList(in *v1beta1.DockerMachinePoolList, out *DockerMachinePoolList, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachinePoolList_To_v1alpha3_DockerMachinePoolList(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate(in *DockerMachinePoolMachineTemplate, out *v1beta1.DockerMachinePoolMachineTemplate, s conversion.Scope) error { + out.CustomImage = in.CustomImage + out.PreLoadImages = *(*[]string)(unsafe.Pointer(&in.PreLoadImages)) + out.ExtraMounts = *(*[]dockerapiv1beta1.Mount)(unsafe.Pointer(&in.ExtraMounts)) + return nil +} + +// Convert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate(in *DockerMachinePoolMachineTemplate, out *v1beta1.DockerMachinePoolMachineTemplate, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate(in *v1beta1.DockerMachinePoolMachineTemplate, out *DockerMachinePoolMachineTemplate, s conversion.Scope) error { + out.CustomImage = in.CustomImage + out.PreLoadImages = *(*[]string)(unsafe.Pointer(&in.PreLoadImages)) + out.ExtraMounts = *(*[]apiv1alpha3.Mount)(unsafe.Pointer(&in.ExtraMounts)) + return nil +} + +// Convert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate(in *v1beta1.DockerMachinePoolMachineTemplate, out *DockerMachinePoolMachineTemplate, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec(in *DockerMachinePoolSpec, out *v1beta1.DockerMachinePoolSpec, s conversion.Scope) error { + if err := Convert_v1alpha3_DockerMachinePoolMachineTemplate_To_v1beta1_DockerMachinePoolMachineTemplate(&in.Template, &out.Template, s); err != nil { + return err + } + out.ProviderID = in.ProviderID + out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) + return nil +} + +// Convert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec(in *DockerMachinePoolSpec, out *v1beta1.DockerMachinePoolSpec, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePoolSpec_To_v1beta1_DockerMachinePoolSpec(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec(in *v1beta1.DockerMachinePoolSpec, out *DockerMachinePoolSpec, s conversion.Scope) error { + if err := Convert_v1beta1_DockerMachinePoolMachineTemplate_To_v1alpha3_DockerMachinePoolMachineTemplate(&in.Template, &out.Template, s); err != nil { + return err + } + out.ProviderID = in.ProviderID + out.ProviderIDList = *(*[]string)(unsafe.Pointer(&in.ProviderIDList)) + return nil +} + +// Convert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec is an autogenerated conversion function. +func Convert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec(in *v1beta1.DockerMachinePoolSpec, out *DockerMachinePoolSpec, s conversion.Scope) error { + return autoConvert_v1beta1_DockerMachinePoolSpec_To_v1alpha3_DockerMachinePoolSpec(in, out, s) +} + +func autoConvert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus(in *DockerMachinePoolStatus, out *v1beta1.DockerMachinePoolStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.Replicas = in.Replicas + out.ObservedGeneration = in.ObservedGeneration + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]v1beta1.DockerMachinePoolInstanceStatus, len(*in)) + for i := range *in { + if err := Convert_v1alpha3_DockerMachinePoolInstanceStatus_To_v1beta1_DockerMachinePoolInstanceStatus(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Instances = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(apiv1beta1.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1alpha3_Condition_To_v1beta1_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + return nil +} + +// Convert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus is an autogenerated conversion function. +func Convert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus(in *DockerMachinePoolStatus, out *v1beta1.DockerMachinePoolStatus, s conversion.Scope) error { + return autoConvert_v1alpha3_DockerMachinePoolStatus_To_v1beta1_DockerMachinePoolStatus(in, out, s) +} + +func autoConvert_v1beta1_DockerMachinePoolStatus_To_v1alpha3_DockerMachinePoolStatus(in *v1beta1.DockerMachinePoolStatus, out *DockerMachinePoolStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.Replicas = in.Replicas + out.ObservedGeneration = in.ObservedGeneration + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]DockerMachinePoolInstanceStatus, len(*in)) + for i := range *in { + if err := Convert_v1beta1_DockerMachinePoolInstanceStatus_To_v1alpha3_DockerMachinePoolInstanceStatus(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Instances = nil + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + if err := corev1alpha3.Convert_v1beta1_Condition_To_v1alpha3_Condition(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Conditions = nil + } + // WARNING: in.InfrastructureMachineKind requires manual conversion: does not exist in peer-type + return nil +} diff --git a/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.deepcopy.go b/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.deepcopy.go new file mode 100644 index 000000000000..0f5614952317 --- /dev/null +++ b/test/infrastructure/docker/exp/api/v1alpha3/zz_generated.deepcopy.go @@ -0,0 +1,191 @@ +//go:build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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 controller-gen. DO NOT EDIT. + +package v1alpha3 + +import ( + "k8s.io/apimachinery/pkg/runtime" + corev1alpha3 "sigs.k8s.io/cluster-api/internal/apis/core/v1alpha3" + apiv1alpha3 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha3" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePool) DeepCopyInto(out *DockerMachinePool) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePool. +func (in *DockerMachinePool) DeepCopy() *DockerMachinePool { + if in == nil { + return nil + } + out := new(DockerMachinePool) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachinePool) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePoolInstanceStatus) DeepCopyInto(out *DockerMachinePoolInstanceStatus) { + *out = *in + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]corev1alpha3.MachineAddress, len(*in)) + copy(*out, *in) + } + if in.ProviderID != nil { + in, out := &in.ProviderID, &out.ProviderID + *out = new(string) + **out = **in + } + if in.Version != nil { + in, out := &in.Version, &out.Version + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePoolInstanceStatus. +func (in *DockerMachinePoolInstanceStatus) DeepCopy() *DockerMachinePoolInstanceStatus { + if in == nil { + return nil + } + out := new(DockerMachinePoolInstanceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePoolList) DeepCopyInto(out *DockerMachinePoolList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DockerMachinePool, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePoolList. +func (in *DockerMachinePoolList) DeepCopy() *DockerMachinePoolList { + if in == nil { + return nil + } + out := new(DockerMachinePoolList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DockerMachinePoolList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePoolMachineTemplate) DeepCopyInto(out *DockerMachinePoolMachineTemplate) { + *out = *in + if in.PreLoadImages != nil { + in, out := &in.PreLoadImages, &out.PreLoadImages + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ExtraMounts != nil { + in, out := &in.ExtraMounts, &out.ExtraMounts + *out = make([]apiv1alpha3.Mount, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePoolMachineTemplate. +func (in *DockerMachinePoolMachineTemplate) DeepCopy() *DockerMachinePoolMachineTemplate { + if in == nil { + return nil + } + out := new(DockerMachinePoolMachineTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePoolSpec) DeepCopyInto(out *DockerMachinePoolSpec) { + *out = *in + in.Template.DeepCopyInto(&out.Template) + if in.ProviderIDList != nil { + in, out := &in.ProviderIDList, &out.ProviderIDList + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePoolSpec. +func (in *DockerMachinePoolSpec) DeepCopy() *DockerMachinePoolSpec { + if in == nil { + return nil + } + out := new(DockerMachinePoolSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DockerMachinePoolStatus) DeepCopyInto(out *DockerMachinePoolStatus) { + *out = *in + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]DockerMachinePoolInstanceStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(corev1alpha3.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DockerMachinePoolStatus. +func (in *DockerMachinePoolStatus) DeepCopy() *DockerMachinePoolStatus { + if in == nil { + return nil + } + out := new(DockerMachinePoolStatus) + in.DeepCopyInto(out) + return out +} diff --git a/test/infrastructure/docker/main.go b/test/infrastructure/docker/main.go index 8a4c8e27932e..a76f3c426436 100644 --- a/test/infrastructure/docker/main.go +++ b/test/infrastructure/docker/main.go @@ -49,9 +49,11 @@ import ( expv1 "sigs.k8s.io/cluster-api/exp/api/v1beta1" "sigs.k8s.io/cluster-api/feature" "sigs.k8s.io/cluster-api/test/infrastructure/container" + infrav1alpha3 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha3" infrav1alpha4 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1alpha4" infrav1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1" "sigs.k8s.io/cluster-api/test/infrastructure/docker/controllers" + infraexpv1alpha3 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1alpha3" infraexpv1alpha4 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1alpha4" infraexpv1 "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/api/v1beta1" expcontrollers "sigs.k8s.io/cluster-api/test/infrastructure/docker/exp/controllers" @@ -91,8 +93,10 @@ var ( func init() { _ = clientgoscheme.AddToScheme(scheme) + _ = infrav1alpha3.AddToScheme(scheme) _ = infrav1alpha4.AddToScheme(scheme) _ = infrav1.AddToScheme(scheme) + _ = infraexpv1alpha3.AddToScheme(scheme) _ = infraexpv1alpha4.AddToScheme(scheme) _ = infraexpv1.AddToScheme(scheme) _ = clusterv1.AddToScheme(scheme)