Skip to content

Commit

Permalink
Implement adoption of k8s clusters (Mirantis#725)
Browse files Browse the repository at this point in the history
* Rename ManagedCluster to ClusterDeployment

* Add adopted cluster template to adopt existing k8s clusters

---------

Co-authored-by: Ekaterina Kazakova <[email protected]>
  • Loading branch information
kylewuolle and eromanova authored Dec 24, 2024
1 parent 6209d28 commit 720e56c
Show file tree
Hide file tree
Showing 76 changed files with 957 additions and 821 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
- name: Run E2E tests
env:
GINKGO_LABEL_FILTER: 'controller'
MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }}
CLUSTER_DEPLOYMENT_NAME: ${{ needs.build.outputs.clustername }}
IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}'
VERSION: ${{ needs.build.outputs.version }}
run: |
Expand Down Expand Up @@ -162,7 +162,7 @@ jobs:
- name: Run E2E tests
env:
GINKGO_LABEL_FILTER: 'provider:cloud'
MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }}
CLUSTER_DEPLOYMENT_NAME: ${{ needs.build.outputs.clustername }}
IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}'
VERSION: ${{ needs.build.outputs.version }}
run: |
Expand Down Expand Up @@ -215,7 +215,7 @@ jobs:
- name: Run E2E tests
env:
GINKGO_LABEL_FILTER: 'provider:onprem'
MANAGED_CLUSTER_NAME: ${{ needs.build.outputs.clustername }}
CLUSTER_DEPLOYMENT_NAME: ${{ needs.build.outputs.clustername }}
IMG: 'ghcr.io/mirantis/hmc/controller-ci:${{ needs.build.outputs.version }}'
VERSION: ${{ needs.build.outputs.version }}
run: |
Expand Down
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ dev-templates: templates-generate
dev-release:
@$(YQ) e ".spec.version = \"${VERSION}\"" $(PROVIDER_TEMPLATES_DIR)/hmc-templates/files/release.yaml | $(KUBECTL) -n $(NAMESPACE) apply -f -

.PHONY: dev-adopted-creds
dev-adopted-creds: envsubst
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -i config/dev/adopted-credentials.yaml | $(KUBECTL) apply -f -

.PHONY: dev-aws-creds
dev-aws-creds: envsubst
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -i config/dev/aws-credentials.yaml | $(KUBECTL) apply -f -
Expand All @@ -359,11 +363,11 @@ dev-destroy: kind-undeploy registry-undeploy ## Destroy the development environm

.PHONY: dev-mcluster-apply
dev-mcluster-apply: envsubst
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -no-unset -i config/dev/$(DEV_PROVIDER)-managedcluster.yaml | $(KUBECTL) apply -f -
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -no-unset -i config/dev/$(DEV_PROVIDER)-clusterdeployment.yaml | $(KUBECTL) apply -f -

.PHONY: dev-mcluster-delete
dev-mcluster-delete: envsubst
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -no-unset -i config/dev/$(DEV_PROVIDER)-managedcluster.yaml | $(KUBECTL) delete -f -
@NAMESPACE=$(NAMESPACE) $(ENVSUBST) -no-unset -i config/dev/$(DEV_PROVIDER)-clusterdeployment.yaml | $(KUBECTL) delete -f -

.PHONY: dev-creds-apply
dev-creds-apply: dev-$(DEV_PROVIDER)-creds
Expand Down
2 changes: 1 addition & 1 deletion PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ resources:
controller: true
domain: hmc.mirantis.com
group: hmc.mirantis.com
kind: ManagedCluster
kind: ClusterDeployment
path: github.com/Mirantis/hmc/api/v1alpha1
version: v1alpha1
- api:
Expand Down
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ or install using `helm`
helm install hmc oci://ghcr.io/mirantis/hmc/charts/hmc --version 0.0.5 -n hmc-system --create-namespace
```

Then follow the [Deploy a managed cluster](#deploy-a-managed-cluster) guide to
create a managed cluster.
Then follow the [Deploy a cluster deployment](#deploy-a-cluster-deployment) guide to
create a cluster deployment.

> [!NOTE]
> The HMC installation using Kubernetes manifests does not allow
Expand All @@ -51,7 +51,7 @@ Mirantis Hybrid Container Cloud requires the following:
Optionally, the following CLIs may be helpful:

1. `helm` (required only when installing HMC using `helm`).
2. `clusterctl` (to handle the lifecycle of the managed clusters).
2. `clusterctl` (to handle the lifecycle of the cluster deployments).

### Providers configuration

Expand Down Expand Up @@ -109,9 +109,9 @@ own `Management` configuration:

`kubectl --kubeconfig <path-to-management-kubeconfig> create -f management.yaml`

## Deploy a managed cluster
## Create a ClusterDeployment

To deploy a managed cluster:
To create a ClusterDeployment:

1. Create `Credential` object with all credentials required.

Expand All @@ -131,7 +131,7 @@ If you want to deploy hosted control plane template, make sure to check
additional notes on Hosted control plane in 2A Docs, see
[Documentation](#documentation).

2. Create the file with the `ManagedCluster` configuration:
2. Create the file with the `ClusterDeployment` configuration:

> [!NOTE]
> Substitute the parameters enclosed in angle brackets with the corresponding
Expand All @@ -140,7 +140,7 @@ additional notes on Hosted control plane in 2A Docs, see

```yaml
apiVersion: hmc.mirantis.com/v1alpha1
kind: ManagedCluster
kind: ClusterDeployment
metadata:
name: <cluster-name>
namespace: <cluster-namespace>
Expand All @@ -152,46 +152,46 @@ spec:
<cluster-configuration>
```

3. Create the `ManagedCluster` object:
3. Create the `ClusterDeployment` object:

`kubectl create -f managedcluster.yaml`
`kubectl create -f clusterdeployment.yaml`

4. Check the status of the newly created `ManagedCluster` object:
4. Check the status of the newly created `ClusterDeployment` object:

`kubectl -n <managedcluster-namespace> get managedcluster <managedcluster-name> -o=yaml`
`kubectl -n <clusterdeployment-namespace> get ClusterDeployment <clusterdeployment-name> -o=yaml`

5. Wait for infrastructure to be provisioned and the cluster to be deployed (the
provisioning starts only when `spec.dryRun` is disabled):

```bash
kubectl -n <managedcluster-namespace> get cluster <managedcluster-name> -o=yaml
kubectl -n <clusterdeployment-namespace> get cluster <clusterdeployment-name> -o=yaml
```

> [!NOTE]
> You may also watch the process with the `clusterctl describe` command
> (requires the `clusterctl` CLI to be installed): ``` clusterctl describe
> cluster <managedcluster-name> -n <managedcluster-namespace> --show-conditions
> cluster <clusterdeployment-name> -n <clusterdeployment-namespace> --show-conditions
> all ```

6. Retrieve the `kubeconfig` of your managed cluster:
6. Retrieve the `kubeconfig` of your cluster deployment:

```
kubectl get secret -n hmc-system <managedcluster-name>-kubeconfig -o=jsonpath={.data.value} | base64 -d > kubeconfig
kubectl get secret -n hmc-system <clusterdeployment-name>-kubeconfig -o=jsonpath={.data.value} | base64 -d > kubeconfig
```

### Dry run

HMC `ManagedCluster` supports two modes: with and without (default) `dryRun`.
HMC `ClusterDeployment` supports two modes: with and without (default) `dryRun`.

If no configuration (`spec.config`) provided, the `ManagedCluster` object will
If no configuration (`spec.config`) provided, the `ClusterDeployment` object will
be populated with defaults (default configuration can be found in the
corresponding `Template` status) and automatically marked as `dryRun`.

Here is an example of the `ManagedCluster` object with default configuration:
Here is an example of the `ClusterDeployment` object with default configuration:

```yaml
apiVersion: hmc.mirantis.com/v1alpha1
kind: ManagedCluster
kind: ClusterDeployment
metadata:
name: <cluster-name>
namespace: <cluster-namespace>
Expand Down Expand Up @@ -226,11 +226,11 @@ After you adjust your configuration and ensure that it passes validation
(`TemplateReady` condition from `status.conditions`), remove the `spec.dryRun`
flag to proceed with the deployment.

Here is an example of a `ManagedCluster` object that passed the validation:
Here is an example of a `ClusterDeployment` object that passed the validation:

```yaml
apiVersion: hmc.mirantis.com/v1alpha1
kind: ManagedCluster
kind: ClusterDeployment
metadata:
name: aws-standalone
namespace: hmc-system
Expand Down Expand Up @@ -259,7 +259,7 @@ spec:
status: "True"
type: HelmChartReady
- lastTransitionTime: "2024-07-22T09:25:49Z"
message: ManagedCluster is ready
message: ClusterDeployment is ready
reason: Succeeded
status: "True"
type: Ready
Expand All @@ -275,7 +275,7 @@ kubectl delete management.hmc hmc
```

> [!NOTE]
> Make sure you have no HMC ManagedCluster objects left in the cluster prior to
> Make sure you have no HMC ClusterDeployment objects left in the cluster prior to
> Management deletion

2. Remove the `hmc` Helm release:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
)

const (
BlockingFinalizer = "hmc.mirantis.com/cleanup"
ManagedClusterFinalizer = "hmc.mirantis.com/managed-cluster"
BlockingFinalizer = "hmc.mirantis.com/cleanup"
ClusterDeploymentFinalizer = "hmc.mirantis.com/cluster-deployment"

FluxHelmChartNameKey = "helm.toolkit.fluxcd.io/name"
FluxHelmChartNamespaceKey = "helm.toolkit.fluxcd.io/namespace"
Expand All @@ -35,20 +35,20 @@ const (
)

const (
// ManagedClusterKind is the string representation of a ManagedCluster.
ManagedClusterKind = "ManagedCluster"
// ClusterDeploymentKind is the string representation of a ClusterDeployment.
ClusterDeploymentKind = "ClusterDeployment"
// TemplateReadyCondition indicates the referenced Template exists and valid.
TemplateReadyCondition = "TemplateReady"
// HelmChartReadyCondition indicates the corresponding HelmChart is valid and ready.
HelmChartReadyCondition = "HelmChartReady"
// HelmReleaseReadyCondition indicates the corresponding HelmRelease is ready and fully reconciled.
HelmReleaseReadyCondition = "HelmReleaseReady"
// ReadyCondition indicates the ManagedCluster is ready and fully reconciled.
// ReadyCondition indicates the ClusterDeployment is ready and fully reconciled.
ReadyCondition string = "Ready"
)

// ManagedClusterSpec defines the desired state of ManagedCluster
type ManagedClusterSpec struct {
// ClusterDeploymentSpec defines the desired state of ClusterDeployment
type ClusterDeploymentSpec struct {
// 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.
Expand Down Expand Up @@ -86,14 +86,14 @@ type ManagedClusterSpec struct {
StopOnConflict bool `json:"stopOnConflict,omitempty"`
}

// ManagedClusterStatus defines the observed state of ManagedCluster
type ManagedClusterStatus struct {
// ClusterDeploymentStatus defines the observed state of ClusterDeployment
type ClusterDeploymentStatus struct {
// Services contains details for the state of services.
Services []ServiceStatus `json:"services,omitempty"`
// Currently compatible exact Kubernetes version of the cluster. Being set only if
// provided by the corresponding ClusterTemplate.
KubernetesVersion string `json:"k8sVersion,omitempty"`
// Conditions contains details for the current state of the ManagedCluster.
// Conditions contains details for the current state of the ClusterDeployment.
Conditions []metav1.Condition `json:"conditions,omitempty"`

// AvailableUpgrades is the list of ClusterTemplate names to which
Expand All @@ -106,32 +106,32 @@ type ManagedClusterStatus struct {

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName=mcluster;mcl
// +kubebuilder:resource:shortName=clusterd;cld
// +kubebuilder:printcolumn:name="ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="Ready",priority=0
// +kubebuilder:printcolumn:name="status",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].message",description="Status",priority=0
// +kubebuilder:printcolumn:name="dryRun",type="string",JSONPath=".spec.dryRun",description="Dry Run",priority=1

// ManagedCluster is the Schema for the managedclusters API
type ManagedCluster struct {
// ClusterDeployment is the Schema for the ClusterDeployments API
type ClusterDeployment struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec ManagedClusterSpec `json:"spec,omitempty"`
Status ManagedClusterStatus `json:"status,omitempty"`
Spec ClusterDeploymentSpec `json:"spec,omitempty"`
Status ClusterDeploymentStatus `json:"status,omitempty"`
}

func (in *ManagedCluster) HelmValues() (values map[string]any, err error) {
func (in *ClusterDeployment) HelmValues() (values map[string]any, err error) {
if in.Spec.Config != nil {
err = yaml.Unmarshal(in.Spec.Config.Raw, &values)
}
return values, err
}

func (in *ManagedCluster) GetConditions() *[]metav1.Condition {
func (in *ClusterDeployment) GetConditions() *[]metav1.Condition {
return &in.Status.Conditions
}

func (in *ManagedCluster) InitConditions() {
func (in *ClusterDeployment) InitConditions() {
apimeta.SetStatusCondition(in.GetConditions(), metav1.Condition{
Type: TemplateReadyCondition,
Status: metav1.ConditionUnknown,
Expand All @@ -156,19 +156,19 @@ func (in *ManagedCluster) InitConditions() {
Type: ReadyCondition,
Status: metav1.ConditionUnknown,
Reason: ProgressingReason,
Message: "ManagedCluster is not yet ready",
Message: "ClusterDeployment is not yet ready",
})
}

// +kubebuilder:object:root=true

// ManagedClusterList contains a list of ManagedCluster
type ManagedClusterList struct {
// ClusterDeploymentList contains a list of ClusterDeployment
type ClusterDeploymentList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ManagedCluster `json:"items"`
Items []ClusterDeployment `json:"items"`
}

func init() {
SchemeBuilder.Register(&ManagedCluster{}, &ManagedClusterList{})
SchemeBuilder.Register(&ClusterDeployment{}, &ClusterDeploymentList{})
}
Loading

0 comments on commit 720e56c

Please sign in to comment.