-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #366 from redhatci/acm-detach-reattach
New role for spoke cluster management operations (detach, attach and clean GitOps)
- Loading branch information
Showing
15 changed files
with
440 additions
and
3 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# ACM Spoke Management operations | ||
|
||
This role allows to perform multiple management operations on a given spoke cluster. | ||
|
||
Tasks must be executed on the hub cluster that is controlling/going to control the given spoke cluster. | ||
|
||
## Actions allowed | ||
|
||
The following variable controls the action that can be performed within this role: | ||
|
||
Name | Type | Required | Default | Description | ||
---------------------------- | ------ | -------- | -------------------------------------------------- | ------------------------------------------------------------ | ||
asm_action | string | yes | - | Action to be performed. Accepted values are `detach` and `attach`. | ||
|
||
## Detach a spoke cluster | ||
|
||
This action allows to detach a spoke cluster from a given hub cluster. | ||
|
||
This is based on the following [OCP documentation](https://docs.redhat.com/en/documentation/red_hat_advanced_cluster_management_for_kubernetes/2.5/html/clusters/managing-your-clusters#remove-a-cluster-by-using-the-cli). | ||
|
||
### Requirements | ||
|
||
* Spoke cluster running in a given hub cluster. | ||
|
||
### Role Variables | ||
|
||
Name | Type | Required | Default | Description | ||
--------------------------- | ------ | -------- | -------------------------------------------------- | ------------------------------------------------------------- | ||
asm_cluster_name | string | yes | - | Cluster name, used for identifying the ManagedCluster and the Namespace | ||
|
||
### Example | ||
|
||
```yaml | ||
- name: Detach spoke cluster from hub cluster | ||
ansible.builtin.include_role: | ||
name: redhatci.ocp.acm_spoke_mgmt | ||
vars: | ||
asm_action: "detach" | ||
asm_cluster_name: "mycluster" | ||
``` | ||
## Attach a spoke cluster | ||
This action allows to attach a spoke cluster to a given hub cluster. | ||
This is based on the following [OCP documentation](https://docs.redhat.com/en/documentation/red_hat_advanced_cluster_management_for_kubernetes/2.5/html/clusters/managing-your-clusters#importing-a-target-managed-cluster-to-the-hub-cluster). | ||
Three resources are created in this role: | ||
- ManagedCluster resource (and related Namespace is automatically created after its creation). | ||
- Autoimport Secret. | ||
- KlusterletAddonConfig. | ||
### Requirements | ||
* Active spoke cluster already created, having access to its kubeconfig. | ||
### Role Variables | ||
Name | Type | Required | Default | Description | ||
---------------------------- | ------ | -------- | -------------------------------------------------- | ------------------------------------------------------------ | ||
asm_cluster_kubeconfig_path | string | yes | - | Path to spoke cluster's kubeconfig file | ||
asm_cluster_name | string | yes | - | Cluster name, used for identifying the ManagedCluster and the Namespace | ||
### Example | ||
```yaml | ||
- name: Attach spoke cluster to hub cluster | ||
ansible.builtin.include_role: | ||
name: redhatci.ocp.acm_spoke_mgmt | ||
vars: | ||
asm_action: "attach" | ||
asm_cluster_kubeconfig_path: "/path/to/spoke/kubeconfig" | ||
asm_cluster_name: "mycluster" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
--- | ||
|
||
- name: Assert the required variables are defined | ||
ansible.builtin.assert: | ||
that: | ||
- asm_cluster_kubeconfig_path is defined | ||
- asm_cluster_kubeconfig_path | length > 0 | ||
- asm_cluster_name is defined | ||
- asm_cluster_name | length > 0 | ||
|
||
# This will automatically create the cluster namespace, called | ||
# asm_cluster_name too. | ||
- name: Create ManagedCluster | ||
community.kubernetes.k8s: | ||
definition: | ||
apiVersion: cluster.open-cluster-management.io/v1 | ||
kind: ManagedCluster | ||
metadata: | ||
name: "{{ asm_cluster_name }}" | ||
labels: | ||
name: "{{ asm_cluster_name }}" | ||
cloud: auto-detect | ||
vendor: auto-detect | ||
annotations: {} | ||
spec: | ||
hubAcceptsClient: true | ||
|
||
- name: Ensure spoke cluster namespace has been created | ||
community.kubernetes.k8s_info: | ||
api: v1 | ||
kind: Namespace | ||
name: "{{ asm_cluster_name }}" | ||
register: _asm_namespace_status | ||
until: | ||
- _asm_namespace_status.resources | length > 0 | ||
retries: 60 | ||
delay: 10 | ||
|
||
# To import the spoke cluster to the hub cluster, we need to create | ||
# a secret that contains the spoke cluster's kubeconfig. | ||
# This requires a special formatting, including double line breaks | ||
# and a correct indentation. | ||
- name: Create autoimport secret | ||
block: | ||
- name: Get kubeconfig content | ||
ansible.builtin.slurp: | ||
src: "{{ asm_cluster_kubeconfig_path }}" | ||
register: _asm_kubeconfig_content | ||
no_log: true | ||
|
||
- name: Save kubeconfig content in a variable | ||
ansible.builtin.set_fact: | ||
asm_kubeconfig: "{{ _asm_kubeconfig_content['content'] | b64decode }}" | ||
no_log: true | ||
|
||
- name: Apply Secret to attach spoke cluster to hub cluster | ||
community.kubernetes.k8s: | ||
state: present | ||
definition: "{{ lookup('ansible.builtin.template', 'autoimport_secret.yml.j2') | from_yaml }}" | ||
no_log: true | ||
|
||
# To correctly join the hub cluster, ManagedClusterJoined condition must be True. | ||
- name: Ensure ManagedCluster has joined the hub cluster | ||
community.kubernetes.k8s_info: | ||
api: cluster.open-cluster-management.io/v1 | ||
kind: ManagedCluster | ||
name: "{{ asm_cluster_name }}" | ||
register: _asm_managedcluster_status | ||
vars: | ||
_asm_status_query: "resources[0].status.conditions[?type=='ManagedClusterJoined'].status" | ||
_asm_update_status: "{{ _asm_managedcluster_status | json_query(_asm_status_query) | flatten | unique }}" # noqa: jinja[invalid] | ||
until: | ||
- _asm_managedcluster_status.resources is defined | ||
- _asm_managedcluster_status.resources | length > 0 | ||
- _asm_update_status == ['True'] | ||
retries: 30 | ||
delay: 10 | ||
|
||
- name: Create KlusterletAddonConfig | ||
community.kubernetes.k8s: | ||
definition: | ||
apiVersion: agent.open-cluster-management.io/v1 | ||
kind: KlusterletAddonConfig | ||
metadata: | ||
name: "{{ asm_cluster_name }}" | ||
namespace: "{{ asm_cluster_name }}" | ||
spec: | ||
clusterName: "{{ asm_cluster_name }}" | ||
clusterNamespace: "{{ asm_cluster_name }}" | ||
clusterLabels: | ||
cloud: auto-detect | ||
vendor: auto-detect | ||
applicationManager: | ||
enabled: false | ||
certPolicyController: | ||
enabled: false | ||
iamPolicyController: | ||
enabled: false | ||
policyController: | ||
enabled: true | ||
searchCollector: | ||
enabled: false | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
--- | ||
|
||
- name: Assert the required variables are defined | ||
ansible.builtin.assert: | ||
that: | ||
- asm_cluster_name is defined | ||
- asm_cluster_name | length > 0 | ||
|
||
- name: Delete spoke's ManagedCluster | ||
community.kubernetes.k8s: | ||
api_version: cluster.open-cluster-management.io/v1 | ||
kind: ManagedCluster | ||
name: "{{ asm_cluster_name }}" | ||
state: absent | ||
wait: true | ||
wait_sleep: 5 | ||
wait_timeout: 300 | ||
|
||
- name: Ensure ManagedCluster resource has been deleted | ||
community.kubernetes.k8s_info: | ||
api: cluster.open-cluster-management.io/v1 | ||
kind: ManagedCluster | ||
name: "{{ asm_cluster_name }}" | ||
register: _asm_managed_cluster_status | ||
until: | ||
- _asm_managed_cluster_status.resources | length == 0 | ||
retries: 18 | ||
delay: 10 | ||
|
||
# Normally, the namespace is deleted after removing the ManagedCluster, excepting | ||
# ZTP-based spoke clusters, since there are more resources living in the namespace. | ||
# For this case, we need to explicitly remove the namespace. | ||
# This may take some time. | ||
- name: Delete spoke cluster namespace | ||
community.kubernetes.k8s: | ||
api_version: v1 | ||
kind: Namespace | ||
name: "{{ asm_cluster_name }}" | ||
state: absent | ||
wait: true | ||
wait_sleep: 5 | ||
wait_timeout: 600 | ||
|
||
# Same, this may take some time. | ||
- name: Ensure spoke cluster namespace has been deleted | ||
community.kubernetes.k8s_info: | ||
api: v1 | ||
kind: Namespace | ||
name: "{{ asm_cluster_name }}" | ||
register: _asm_namespace_status | ||
until: | ||
- _asm_namespace_status.resources | length == 0 | ||
retries: 60 | ||
delay: 10 | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
--- | ||
|
||
- name: Check if the selected action is allowed | ||
vars: | ||
asm_actions: | ||
- detach | ||
- attach | ||
ansible.builtin.assert: | ||
that: | ||
- asm_action | lower in asm_actions | ||
fail_msg: "{{ asm_action }} is not a supported action" | ||
|
||
- name: Detach a spoke cluster | ||
ansible.builtin.include_tasks: detach.yaml | ||
when: | ||
- asm_action == 'detach' | ||
|
||
- name: Attach a spoke cluster | ||
ansible.builtin.include_tasks: attach.yaml | ||
when: | ||
- asm_action == 'attach' | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
|
||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: auto-import-secret | ||
namespace: {{ asm_cluster_name }} | ||
stringData: | ||
autoImportRetry: "2" | ||
kubeconfig: > | ||
|
||
{{ asm_kubeconfig | regex_replace('\n', '\n\n') | indent(4, True) }} | ||
|
||
type: Opaque | ||
|
||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
--- | ||
gcr_ssh_key_path: "{{ lookup('env', 'HOME') }}/.ssh/id_rsa" | ||
gcr_argo_cd_known_host_cm: "argocd-ssh-known-hosts-cm" | ||
gcr_private_repo_secret: "private-repo" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Remove ZTP GitOps resources | ||
|
||
Remove all GitOps related resources for a given spoke cluster, excepting the cluster namespace, which is not deleted because this will imply the spoke cluster is detached from the hub cluster. | ||
|
||
For performing a cluster detachment, then use the [acm_detach_spoke_cluster](../acm_detach_spoke_cluster) role accordingly. | ||
|
||
## Requirements | ||
|
||
* Hub cluster configured for launching ZTP. | ||
* ArgoCD configured in the hub cluster. | ||
* Spoke cluster deploying thanks to ArgoCD applications already configured. | ||
|
||
## Role Variables | ||
|
||
Default values for role variables are based on default values used in [gitops_configure_repo](../gitops_configure_repo) and [configure_ztp_gitops_apps](../configure_ztp_gitops_apps) roles. Being more precise for the second case, it's using the default resource names applied by the ZTP Site Generator container. | ||
|
||
Please adapt the values of these variables for your use case. | ||
|
||
Name | Type | Required | Default | Description | ||
--------------------------- | ------ | -------- | -------------------------------------------------- | ------------------------------------------------------------- | ||
rzgr_gitops_applications | list | no | ["clusters", "policies"] | GitOps Applications related to SiteConfig and Policy resources. | ||
rzgr_gitops_appprojects | list | no | ["ztp-app-project", "policy-app-project"] | GitOps AppProjects related to SiteConfig and Policy resources. | ||
rzgr_policies_namespace | string | no | policies-sub | Namespace for the policy generator template resources. It can not be the sabe as the clusters namespace. | ||
rzgr_extra_namespaces | list | no | ["ztp-common", "ztp-group", "ztp-site"] | Extra namespaces that are created for GitOps policy creation by default. | ||
rzgr_cluster_role_bindings | list | no | ["gitops-policy", "gitops-cluster"] | ClusterRoleBindings created for the deployment of GitOps Policy and SiteConfig. | ||
rzgr_private_repo_secret | string | no | private-repo | Secret that will hold the private repo credentials. | ||
rzgr_argo_cd_known_host_cm | string | no | argocd-ssh-known-hosts-cm | ConfigMap that will save the ArgoCD SSH known hosts. | ||
|
||
## Example | ||
|
||
Following example is the most basic call to this role, using the default arguments for each role variable: | ||
|
||
``` | ||
- name: Remove ZTP GitOps resources | ||
ansible.builtin.include_role: | ||
name: redhatci.ocp.remove_ztp_gitops_resources | ||
``` | ||
|
||
If you want to override any default value of any role variable, then you need to provide it with `vars`, for example: | ||
|
||
``` | ||
- name: Remove ZTP GitOps resources | ||
ansible.builtin.include_role: | ||
name: redhatci.ocp.remove_ztp_gitops_resources | ||
vars: | ||
rzgr_policies_namespace: "mycluster-policies" | ||
``` |
Oops, something went wrong.