From 034244b5017c7b1fe4769f130aaa5ee24afdf918 Mon Sep 17 00:00:00 2001 From: Andrei Pavlov Date: Fri, 20 Sep 2024 15:06:39 +0700 Subject: [PATCH] Add Release CRD for HMC upgrades Signed-off-by: Andrei Pavlov --- PROJECT | 7 + api/v1alpha1/release_types.go | 65 +++++++ api/v1alpha1/zz_generated.deepcopy.go | 109 +++++++++++ .../crds/hmc.mirantis.com_releases.yaml | 172 ++++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 api/v1alpha1/release_types.go create mode 100644 templates/provider/hmc/templates/crds/hmc.mirantis.com_releases.yaml diff --git a/PROJECT b/PROJECT index 8be57a3e8..d42dd0100 100644 --- a/PROJECT +++ b/PROJECT @@ -35,4 +35,11 @@ resources: kind: Management path: github.com/Mirantis/hmc/api/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + domain: hmc.mirantis.com + group: hmc.mirantis.com + kind: Release + path: github.com/Mirantis/hmc/api/v1alpha1 + version: v1alpha1 version: "3" diff --git a/api/v1alpha1/release_types.go b/api/v1alpha1/release_types.go new file mode 100644 index 000000000..df2eb0e7c --- /dev/null +++ b/api/v1alpha1/release_types.go @@ -0,0 +1,65 @@ +// Copyright 2024 +// +// 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ReleaseSpec defines the desired state of Release +type ReleaseSpec struct { + // Version of the HMC Release in the semver format. + Version string `json:"version"` + // UpgradeableVersions contains a list of versions available to upgrade from. + UpgradeableVersions []string `json:"upgradeableVersions,omitempty"` + // Providers contains a list of Providers associated with the Release. + Providers []Provider `json:"providers,omitempty"` +} + +// ReleaseStatus defines the observed state of Release +type ReleaseStatus struct { + // Templates indicates the status of templates associated with the Release. + Templates ComponentStatus `json:"templates,omitempty"` + // Conditions contains details for the current state of the Release + Conditions []metav1.Condition `json:"conditions,omitempty"` + // Ready indicates whether HMC is ready to be upgraded to this Release. + Ready bool `json:"ready,omitempty"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:scope=Cluster + +// Release is the Schema for the releases API +type Release struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ReleaseSpec `json:"spec,omitempty"` + Status ReleaseStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// ReleaseList contains a list of Release +type ReleaseList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Release `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Release{}, &ReleaseList{}) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e947f8aa2..c14a9fc52 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -634,6 +634,115 @@ func (in *Providers) DeepCopy() *Providers { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Release) DeepCopyInto(out *Release) { + *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 Release. +func (in *Release) DeepCopy() *Release { + if in == nil { + return nil + } + out := new(Release) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Release) 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 *ReleaseList) DeepCopyInto(out *ReleaseList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Release, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseList. +func (in *ReleaseList) DeepCopy() *ReleaseList { + if in == nil { + return nil + } + out := new(ReleaseList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ReleaseList) 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 *ReleaseSpec) DeepCopyInto(out *ReleaseSpec) { + *out = *in + if in.UpgradeableVersions != nil { + in, out := &in.UpgradeableVersions, &out.UpgradeableVersions + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Providers != nil { + in, out := &in.Providers, &out.Providers + *out = make([]Provider, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseSpec. +func (in *ReleaseSpec) DeepCopy() *ReleaseSpec { + if in == nil { + return nil + } + out := new(ReleaseSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReleaseStatus) DeepCopyInto(out *ReleaseStatus) { + *out = *in + out.Templates = in.Templates + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseStatus. +func (in *ReleaseStatus) DeepCopy() *ReleaseStatus { + if in == nil { + return nil + } + out := new(ReleaseStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceTemplate) DeepCopyInto(out *ServiceTemplate) { *out = *in diff --git a/templates/provider/hmc/templates/crds/hmc.mirantis.com_releases.yaml b/templates/provider/hmc/templates/crds/hmc.mirantis.com_releases.yaml new file mode 100644 index 000000000..0c3e84c17 --- /dev/null +++ b/templates/provider/hmc/templates/crds/hmc.mirantis.com_releases.yaml @@ -0,0 +1,172 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: releases.hmc.mirantis.com +spec: + group: hmc.mirantis.com + names: + kind: Release + listKind: ReleaseList + plural: releases + singular: release + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: Release is the Schema for the releases 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: ReleaseSpec defines the desired state of Release + properties: + providers: + description: Providers contains a list of Providers associated with + the Release. + items: + properties: + config: + description: |- + Config allows to provide parameters for management component customization. + If no Config provided, the field will be populated with the default + values for the template. + x-kubernetes-preserve-unknown-fields: true + name: + description: Name of the provider. + type: string + template: + description: Template is the name of the Template associated + with this component. + type: string + required: + - name + - template + type: object + type: array + upgradeableVersions: + description: UpgradeableVersions contains a list of versions available + to upgrade from. + items: + type: string + type: array + version: + description: Version of the HMC Release in the semver format. + type: string + required: + - version + type: object + status: + description: ReleaseStatus defines the observed state of Release + properties: + conditions: + description: Conditions contains details for the current state of + the Release + items: + description: "Condition contains details for one aspect of the current + state of this API Resource.\n---\nThis struct is intended for + direct use as an array at the field path .status.conditions. For + example,\n\n\n\ttype FooStatus struct{\n\t // Represents the + observations of a foo's current state.\n\t // Known .status.conditions.type + are: \"Available\", \"Progressing\", and \"Degraded\"\n\t // + +patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t + \ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\" + patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t + \ // other fields\n\t}" + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the 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: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "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. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + ready: + description: Ready indicates whether HMC is ready to be upgraded to + this Release. + type: boolean + templates: + description: Templates indicates the status of templates associated + with the Release. + properties: + error: + description: Error stores as error message in case of failed installation + type: string + success: + description: Success represents if a component installation was + successful + type: boolean + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {}