From 047904b0ddbaa5abf049f8c172f78111fd6387b8 Mon Sep 17 00:00:00 2001 From: Kyle Wuolle Date: Wed, 11 Dec 2024 13:17:36 -0800 Subject: [PATCH] Add adopted cluster template to adopt existing k8s clusters --- config/dev/adopted-clusterdeployment.yaml | 16 + config/dev/adopted-credentials.yaml | 21 ++ templates/cluster/adopted-cluster/.helmignore | 23 ++ templates/cluster/adopted-cluster/Chart.yaml | 11 + .../adopted-cluster/templates/_helpers.tpl | 4 + .../templates/sveltoscluster.yaml | 10 + .../adopted-cluster/values.schema.json | 33 ++ templates/cluster/adopted-cluster/values.yaml | 7 + .../templates/adopted-cluster-0-0-4.yaml | 15 + .../hmc.mirantis.com_clusterdeployments.yaml | 295 ++++++++++++++++++ 10 files changed, 435 insertions(+) create mode 100644 config/dev/adopted-clusterdeployment.yaml create mode 100644 config/dev/adopted-credentials.yaml create mode 100644 templates/cluster/adopted-cluster/.helmignore create mode 100644 templates/cluster/adopted-cluster/Chart.yaml create mode 100644 templates/cluster/adopted-cluster/templates/_helpers.tpl create mode 100644 templates/cluster/adopted-cluster/templates/sveltoscluster.yaml create mode 100644 templates/cluster/adopted-cluster/values.schema.json create mode 100644 templates/cluster/adopted-cluster/values.yaml create mode 100644 templates/provider/hmc-templates/files/templates/adopted-cluster-0-0-4.yaml create mode 100644 templates/provider/hmc/templates/crds/hmc.mirantis.com_clusterdeployments.yaml diff --git a/config/dev/adopted-clusterdeployment.yaml b/config/dev/adopted-clusterdeployment.yaml new file mode 100644 index 000000000..36afd93aa --- /dev/null +++ b/config/dev/adopted-clusterdeployment.yaml @@ -0,0 +1,16 @@ +apiVersion: hmc.mirantis.com/v1alpha1 +kind: ClusterDeployment +metadata: + name: aws-dev + namespace: ${NAMESPACE} +spec: + template: adopted-cluster-0-0-4 + credential: adopted-cluster-cred + config: {} + services: + - template: kyverno-3-2-6 + name: kyverno + namespace: kyverno + - template: ingress-nginx-4-11-0 + name: ingress-nginx + namespace: ingress-nginx \ No newline at end of file diff --git a/config/dev/adopted-credentials.yaml b/config/dev/adopted-credentials.yaml new file mode 100644 index 000000000..bdd68f0bf --- /dev/null +++ b/config/dev/adopted-credentials.yaml @@ -0,0 +1,21 @@ +apiVersion: v1 +data: + value: ${KUBECONFIG_DATA} +kind: Secret +metadata: + name: adopted-cluster-kubeconf + namespace: ${NAMESPACE} +type: Opaque +--- +apiVersion: hmc.mirantis.com/v1alpha1 +kind: Credential +metadata: + name: adopted-cluster-cred + namespace: ${NAMESPACE} +spec: + description: Adopted Credentials + identityRef: + apiVersion: v1 + kind: Secret + name: adopted-cluster-kubeconf + namespace: ${NAMESPACE} \ No newline at end of file diff --git a/templates/cluster/adopted-cluster/.helmignore b/templates/cluster/adopted-cluster/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/templates/cluster/adopted-cluster/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/templates/cluster/adopted-cluster/Chart.yaml b/templates/cluster/adopted-cluster/Chart.yaml new file mode 100644 index 000000000..53fa99c13 --- /dev/null +++ b/templates/cluster/adopted-cluster/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: adopted-cluster +description: | + An HMC template to adopt an already existing kubernetes cluster +type: application +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.0.4 +annotations: + cluster.x-k8s.io/provider: infrastructure-internal diff --git a/templates/cluster/adopted-cluster/templates/_helpers.tpl b/templates/cluster/adopted-cluster/templates/_helpers.tpl new file mode 100644 index 000000000..50922cc27 --- /dev/null +++ b/templates/cluster/adopted-cluster/templates/_helpers.tpl @@ -0,0 +1,4 @@ +{{- define "cluster.name" -}} + {{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} + diff --git a/templates/cluster/adopted-cluster/templates/sveltoscluster.yaml b/templates/cluster/adopted-cluster/templates/sveltoscluster.yaml new file mode 100644 index 000000000..dd189255a --- /dev/null +++ b/templates/cluster/adopted-cluster/templates/sveltoscluster.yaml @@ -0,0 +1,10 @@ +apiVersion: lib.projectsveltos.io/v1beta1 +kind: SveltosCluster +metadata: + labels: + projectsveltos.io/k8s-version: v1.31.1 + name: {{ include "cluster.name" . }} + namespace: {{ .Release.Namespace }} +spec: + consecutiveFailureThreshold: {{ .Values.consecutiveFailureThreshold }} + kubeconfigName: {{ .Values.clusterIdentity.name }} diff --git a/templates/cluster/adopted-cluster/values.schema.json b/templates/cluster/adopted-cluster/values.schema.json new file mode 100644 index 000000000..d54c0bd57 --- /dev/null +++ b/templates/cluster/adopted-cluster/values.schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "An HMC template to adopt an existing k8s cluster.", + "type": "object", + "required": [ + "clusterIdentity" + ], + "properties": { + "consecutiveFailureThreshold": { + "description": "The number of the failures prior to setting the status condition", + "type": "integer", + "minimum": 1 + }, + "clusterIdentity": { + "type": "object", + "description": "Adopted Cluster Identity object reference", + "required": [ + "name", + "kind" + ], + "properties": { + "name": { + "description": "Adopted ClusterIdentity object name", + "type": "string" + }, + "kind": { + "description": "Adopted ClusterIdentity object kind", + "type": "string" + } + } + } + } +} diff --git a/templates/cluster/adopted-cluster/values.yaml b/templates/cluster/adopted-cluster/values.yaml new file mode 100644 index 000000000..bb189cedf --- /dev/null +++ b/templates/cluster/adopted-cluster/values.yaml @@ -0,0 +1,7 @@ +# Cluster parameters + +clusterIdentity: + name: "adopted-cluster-identity" + kind: "Secret" + +consecutiveFailureThreshold: 3 diff --git a/templates/provider/hmc-templates/files/templates/adopted-cluster-0-0-4.yaml b/templates/provider/hmc-templates/files/templates/adopted-cluster-0-0-4.yaml new file mode 100644 index 000000000..19ba46f5c --- /dev/null +++ b/templates/provider/hmc-templates/files/templates/adopted-cluster-0-0-4.yaml @@ -0,0 +1,15 @@ +apiVersion: hmc.mirantis.com/v1alpha1 +kind: ClusterTemplate +metadata: + name: adopted-cluster-0-0-4 + annotations: + helm.sh/resource-policy: keep +spec: + helm: + chartSpec: + chart: adopted-cluster + version: 0.0.4 + interval: 10m0s + sourceRef: + kind: HelmRepository + name: hmc-templates diff --git a/templates/provider/hmc/templates/crds/hmc.mirantis.com_clusterdeployments.yaml b/templates/provider/hmc/templates/crds/hmc.mirantis.com_clusterdeployments.yaml new file mode 100644 index 000000000..1c76d3062 --- /dev/null +++ b/templates/provider/hmc/templates/crds/hmc.mirantis.com_clusterdeployments.yaml @@ -0,0 +1,295 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.3 + name: clusterdeployments.hmc.mirantis.com +spec: + group: hmc.mirantis.com + names: + kind: ClusterDeployment + listKind: ClusterDeploymentList + plural: clusterdeployments + shortNames: + - mcluster + - mcl + singular: clusterdeployment + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Ready + jsonPath: .status.conditions[?(@.type=="Ready")].status + name: ready + type: string + - description: Status + jsonPath: .status.conditions[?(@.type=="Ready")].message + name: status + type: string + - description: Dry Run + jsonPath: .spec.dryRun + name: dryRun + priority: 1 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: ClusterDeployment is the Schema for the ClusterDeployments 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: ClusterDeploymentSpec defines the desired state of ClusterDeployment + properties: + config: + description: |- + Config allows to provide parameters for template customization. + If no Config provided, the field will be populated with the default values for + the template and DryRun will be enabled. + x-kubernetes-preserve-unknown-fields: true + credential: + description: Name reference to the related Credentials object. + type: string + dryRun: + description: DryRun specifies whether the template should be applied + after validation or only validated. + type: boolean + services: + description: |- + Services is a list of services created via ServiceTemplates + that could be installed on the target cluster. + items: + description: ServiceSpec represents a Service to be managed + properties: + disable: + description: Disable can be set to disable handling of this + service. + type: boolean + name: + description: Name is the chart release. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace the release will be installed in. + It will default to Name if not provided. + type: string + template: + description: Template is a reference to a Template object located + in the same namespace. + maxLength: 253 + minLength: 1 + type: string + values: + description: |- + Values is the helm values to be passed to the chart used by the template. + The string type is used in order to allow for templating. + type: string + required: + - name + - template + type: object + type: array + servicesPriority: + default: 100 + description: |- + ServicesPriority sets the priority for the services defined in this spec. + Higher value means higher priority and lower means lower. + In case of conflict with another object managing the service, + the one with higher priority will get to deploy its services. + format: int32 + maximum: 2147483646 + minimum: 1 + type: integer + stopOnConflict: + default: false + description: |- + StopOnConflict specifies what to do in case of a conflict. + E.g. If another object is already managing a service. + By default the remaining services will be deployed even if conflict is detected. + If set to true, the deployment will stop after encountering the first conflict. + type: boolean + template: + description: Template is a reference to a Template object located + in the same namespace. + maxLength: 253 + minLength: 1 + type: string + required: + - template + type: object + status: + description: ClusterDeploymentStatus defines the observed state of ClusterDeployment + properties: + availableUpgrades: + description: |- + AvailableUpgrades is the list of ClusterTemplate names to which + this cluster can be upgraded. It can be an empty array, which means no upgrades are + available. + items: + type: string + type: array + conditions: + description: Conditions contains details for the current state of + the ClusterDeployment. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + 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. + 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 + k8sVersion: + description: |- + Currently compatible exact Kubernetes version of the cluster. Being set only if + provided by the corresponding ClusterTemplate. + type: string + observedGeneration: + description: ObservedGeneration is the last observed generation. + format: int64 + type: integer + services: + description: Services contains details for the state of services. + items: + description: ServiceStatus contains details for the state of services. + properties: + clusterName: + description: ClusterName is the name of the associated cluster. + type: string + clusterNamespace: + description: ClusterNamespace is the namespace of the associated + cluster. + type: string + conditions: + description: Conditions contains details for the current state + of managed services. + items: + description: Condition contains details for one aspect of + the current state of this API Resource. + 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. + 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 + required: + - clusterName + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {}