diff --git a/api/core/v1beta1/conversion.go b/api/core/v1beta1/conversion.go index 43ff16560c13..9f67740c47ac 100644 --- a/api/core/v1beta1/conversion.go +++ b/api/core/v1beta1/conversion.go @@ -250,6 +250,8 @@ func (src *ClusterClass) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.KubernetesVersions = restored.Spec.KubernetesVersions + dst.Spec.Upgrade.External.GenerateUpgradePlanExtension = restored.Spec.Upgrade.External.GenerateUpgradePlanExtension + return nil } diff --git a/api/core/v1beta1/zz_generated.conversion.go b/api/core/v1beta1/zz_generated.conversion.go index 7a54a418e8e4..00cf25f842ad 100644 --- a/api/core/v1beta1/zz_generated.conversion.go +++ b/api/core/v1beta1/zz_generated.conversion.go @@ -1207,6 +1207,7 @@ func autoConvert_v1beta2_ClusterClassSpec_To_v1beta1_ClusterClassSpec(in *v1beta } else { out.Patches = nil } + // WARNING: in.Upgrade requires manual conversion: does not exist in peer-type // WARNING: in.KubernetesVersions requires manual conversion: does not exist in peer-type return nil } diff --git a/api/core/v1beta2/clusterclass_types.go b/api/core/v1beta2/clusterclass_types.go index 189995e33e24..af13f9d030cc 100644 --- a/api/core/v1beta2/clusterclass_types.go +++ b/api/core/v1beta2/clusterclass_types.go @@ -136,6 +136,10 @@ type ClusterClassSpec struct { // +kubebuilder:validation:MaxItems=1000 Patches []ClusterClassPatch `json:"patches,omitempty"` + // upgrade defines the upgrade configuration for clusters using this ClusterClass. + // +optional + Upgrade ClusterClassUpgrade `json:"upgrade,omitempty,omitzero"` + // kubernetesVersions is the list of Kubernetes versions that can be // used for clusters using this ClusterClass. // The list of version must be ordered from the older to the newer version, and there should be @@ -1252,6 +1256,24 @@ type ClusterClassPatch struct { External *ExternalPatchDefinition `json:"external,omitempty"` } +// ClusterClassUpgrade defines the upgrade configuration for clusters using the ClusterClass. +// +kubebuilder:validation:MinProperties=1 +type ClusterClassUpgrade struct { + // external defines external runtime extensions for upgrade operations. + // +optional + External ClusterClassUpgradeExternal `json:"external,omitempty,omitzero"` +} + +// ClusterClassUpgradeExternal defines external runtime extensions for upgrade operations. +// +kubebuilder:validation:MinProperties=1 +type ClusterClassUpgradeExternal struct { + // generateUpgradePlanExtension references an extension which is called to generate upgrade plan. + // +optional + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=512 + GenerateUpgradePlanExtension string `json:"generateUpgradePlanExtension,omitempty"` +} + // PatchDefinition defines a patch which is applied to customize the referenced templates. type PatchDefinition struct { // selector defines on which templates the patch should be applied. diff --git a/api/core/v1beta2/zz_generated.deepcopy.go b/api/core/v1beta2/zz_generated.deepcopy.go index f53aa29c59c7..0c5ee6208d3c 100644 --- a/api/core/v1beta2/zz_generated.deepcopy.go +++ b/api/core/v1beta2/zz_generated.deepcopy.go @@ -253,6 +253,7 @@ func (in *ClusterClassSpec) DeepCopyInto(out *ClusterClassSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + out.Upgrade = in.Upgrade if in.KubernetesVersions != nil { in, out := &in.KubernetesVersions, &out.KubernetesVersions *out = make([]string, len(*in)) @@ -368,6 +369,37 @@ func (in *ClusterClassTemplateReference) DeepCopy() *ClusterClassTemplateReferen return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterClassUpgrade) DeepCopyInto(out *ClusterClassUpgrade) { + *out = *in + out.External = in.External +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterClassUpgrade. +func (in *ClusterClassUpgrade) DeepCopy() *ClusterClassUpgrade { + if in == nil { + return nil + } + out := new(ClusterClassUpgrade) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterClassUpgradeExternal) DeepCopyInto(out *ClusterClassUpgradeExternal) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterClassUpgradeExternal. +func (in *ClusterClassUpgradeExternal) DeepCopy() *ClusterClassUpgradeExternal { + if in == nil { + return nil + } + out := new(ClusterClassUpgradeExternal) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterClassV1Beta1DeprecatedStatus) DeepCopyInto(out *ClusterClassV1Beta1DeprecatedStatus) { *out = *in diff --git a/api/core/v1beta2/zz_generated.openapi.go b/api/core/v1beta2/zz_generated.openapi.go index 45b8f5b952e7..42744b6836e6 100644 --- a/api/core/v1beta2/zz_generated.openapi.go +++ b/api/core/v1beta2/zz_generated.openapi.go @@ -42,6 +42,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassStatusVariable": schema_cluster_api_api_core_v1beta2_ClusterClassStatusVariable(ref), "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassStatusVariableDefinition": schema_cluster_api_api_core_v1beta2_ClusterClassStatusVariableDefinition(ref), "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassTemplateReference": schema_cluster_api_api_core_v1beta2_ClusterClassTemplateReference(ref), + "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgrade": schema_cluster_api_api_core_v1beta2_ClusterClassUpgrade(ref), + "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgradeExternal": schema_cluster_api_api_core_v1beta2_ClusterClassUpgradeExternal(ref), "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassV1Beta1DeprecatedStatus": schema_cluster_api_api_core_v1beta2_ClusterClassV1Beta1DeprecatedStatus(ref), "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassVariable": schema_cluster_api_api_core_v1beta2_ClusterClassVariable(ref), "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassVariableMetadata": schema_cluster_api_api_core_v1beta2_ClusterClassVariableMetadata(ref), @@ -617,6 +619,13 @@ func schema_cluster_api_api_core_v1beta2_ClusterClassSpec(ref common.ReferenceCa }, }, }, + "upgrade": { + SchemaProps: spec.SchemaProps{ + Description: "upgrade defines the upgrade configuration for clusters using this ClusterClass.", + Default: map[string]interface{}{}, + Ref: ref("sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgrade"), + }, + }, "kubernetesVersions": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -642,7 +651,7 @@ func schema_cluster_api_api_core_v1beta2_ClusterClassSpec(ref common.ReferenceCa }, }, Dependencies: []string{ - "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterAvailabilityGate", "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassPatch", "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassVariable", "sigs.k8s.io/cluster-api/api/core/v1beta2.ControlPlaneClass", "sigs.k8s.io/cluster-api/api/core/v1beta2.InfrastructureClass", "sigs.k8s.io/cluster-api/api/core/v1beta2.WorkersClass"}, + "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterAvailabilityGate", "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassPatch", "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgrade", "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassVariable", "sigs.k8s.io/cluster-api/api/core/v1beta2.ControlPlaneClass", "sigs.k8s.io/cluster-api/api/core/v1beta2.InfrastructureClass", "sigs.k8s.io/cluster-api/api/core/v1beta2.WorkersClass"}, } } @@ -843,6 +852,48 @@ func schema_cluster_api_api_core_v1beta2_ClusterClassTemplateReference(ref commo } } +func schema_cluster_api_api_core_v1beta2_ClusterClassUpgrade(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ClusterClassUpgrade defines the upgrade configuration for clusters using the ClusterClass.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "external": { + SchemaProps: spec.SchemaProps{ + Description: "external defines external runtime extensions for upgrade operations.", + Default: map[string]interface{}{}, + Ref: ref("sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgradeExternal"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "sigs.k8s.io/cluster-api/api/core/v1beta2.ClusterClassUpgradeExternal"}, + } +} + +func schema_cluster_api_api_core_v1beta2_ClusterClassUpgradeExternal(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ClusterClassUpgradeExternal defines external runtime extensions for upgrade operations.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "generateUpgradePlanExtension": { + SchemaProps: spec.SchemaProps{ + Description: "generateUpgradePlanExtension references an extension which is called to generate upgrade plan.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_cluster_api_api_core_v1beta2_ClusterClassV1Beta1DeprecatedStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml b/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml index 69d6725d76b0..19c37ad21aaa 100644 --- a/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml +++ b/config/crd/bases/cluster.x-k8s.io_clusterclasses.yaml @@ -3559,6 +3559,24 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + upgrade: + description: upgrade defines the upgrade configuration for clusters + using this ClusterClass. + minProperties: 1 + properties: + external: + description: external defines external runtime extensions for + upgrade operations. + minProperties: 1 + properties: + generateUpgradePlanExtension: + description: generateUpgradePlanExtension references an extension + which is called to generate upgrade plan. + maxLength: 512 + minLength: 1 + type: string + type: object + type: object variables: description: |- variables defines the variables which can be configured diff --git a/internal/api/core/v1alpha4/conversion.go b/internal/api/core/v1alpha4/conversion.go index 0f49ec959472..57ac08a4ea98 100644 --- a/internal/api/core/v1alpha4/conversion.go +++ b/internal/api/core/v1alpha4/conversion.go @@ -263,6 +263,7 @@ func (src *ClusterClass) ConvertTo(dstRaw conversion.Hub) error { dst.Spec.Workers.MachineDeployments[i].Rollout.Strategy = restored.Spec.Workers.MachineDeployments[i].Rollout.Strategy } dst.Status = restored.Status + dst.Spec.Upgrade.External.GenerateUpgradePlanExtension = restored.Spec.Upgrade.External.GenerateUpgradePlanExtension return nil } diff --git a/internal/api/core/v1alpha4/zz_generated.conversion.go b/internal/api/core/v1alpha4/zz_generated.conversion.go index 85bbb1cda8d5..aca82dc6be1d 100644 --- a/internal/api/core/v1alpha4/zz_generated.conversion.go +++ b/internal/api/core/v1alpha4/zz_generated.conversion.go @@ -683,6 +683,7 @@ func autoConvert_v1beta2_ClusterClassSpec_To_v1alpha4_ClusterClassSpec(in *v1bet } // WARNING: in.Variables requires manual conversion: does not exist in peer-type // WARNING: in.Patches requires manual conversion: does not exist in peer-type + // WARNING: in.Upgrade requires manual conversion: does not exist in peer-type // WARNING: in.KubernetesVersions requires manual conversion: does not exist in peer-type return nil }