From bae52f8fb653047ad512e4c4b7527d97d5a309cb Mon Sep 17 00:00:00 2001 From: Jakub Stejskal Date: Mon, 5 Feb 2024 13:05:35 +0100 Subject: [PATCH] Add option to import existing clusters (#334) * Add option to import existing clusters Signed-off-by: Jakub Stejskal * Allow to specify already existing clusters Signed-off-by: Jakub Stejskal --------- Signed-off-by: Jakub Stejskal --- .../tasks/common/prepare_kubeconfigs.yaml | 8 + .../common/setup_cluster_kubeconfig.yaml | 120 +++------- .../common/setup_cluster_kubeconfig_hive.yaml | 111 +++++++++ .../infra-setup/delete/delete_kubed.yaml | 21 -- .../delete/delete_kubernetes-replicator.yaml | 21 ++ .../install_observability.yaml | 2 +- .../install_acs_central.yaml | 12 +- .../register_cluster.yaml | 4 +- .../cert-manager/00-install_cert_manager.yaml | 26 +- .../cluster-logging/install_loki_stack.yaml | 1 + .../install/create_clusters_hive.yaml | 1 + .../infra-setup/install/install_argo.yaml | 17 +- ...aml => install_kubernetes-replicator.yaml} | 8 +- .../tasks/infra-setup/prepare_access.yaml | 2 +- install/roles/automation-hub/tasks/main.yml | 8 +- .../tekton/infra-tkn-pipelines.yaml | 5 - ...8-extend-default-metrics-allowlist.yaml.j2 | 4 +- .../cert-manager/03-certificate.yaml.j2 | 4 +- .../templates/kubed/kubed.yaml.j2 | 226 ------------------ .../kubernetes-replicator.yaml.j2 | 75 ++++++ .../odh-e2e-standard-metrics-collector.yaml | 2 +- install/secrets/clusters.yaml | Bin 11524 -> 43879 bytes install/secrets/quay-io.yaml | Bin 604 -> 637 bytes 23 files changed, 302 insertions(+), 376 deletions(-) create mode 100644 install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig_hive.yaml delete mode 100644 install/roles/automation-hub/tasks/infra-setup/delete/delete_kubed.yaml create mode 100644 install/roles/automation-hub/tasks/infra-setup/delete/delete_kubernetes-replicator.yaml rename install/roles/automation-hub/tasks/infra-setup/install/{install_kubed.yaml => install_kubernetes-replicator.yaml} (61%) delete mode 100644 install/roles/automation-hub/templates/kubed/kubed.yaml.j2 create mode 100644 install/roles/automation-hub/templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 diff --git a/install/roles/automation-hub/tasks/common/prepare_kubeconfigs.yaml b/install/roles/automation-hub/tasks/common/prepare_kubeconfigs.yaml index d413b89d..f9ef4cf7 100644 --- a/install/roles/automation-hub/tasks/common/prepare_kubeconfigs.yaml +++ b/install/roles/automation-hub/tasks/common/prepare_kubeconfigs.yaml @@ -29,11 +29,19 @@ path: "{{ kubeconfig_path }}/{{ infra_context_name }}" mode: '0755' +- include_tasks: + file: setup_cluster_kubeconfig_hive.yaml + loop: "{{ clusters_dict.values() }}" + loop_control: + loop_var: cluster + when: cluster.kubeconfig is undefined + - include_tasks: file: setup_cluster_kubeconfig.yaml loop: "{{ clusters_dict.values() }}" loop_control: loop_var: cluster + when: cluster.kubeconfig is defined - name: Check cluster type shell: kubectl api-versions diff --git a/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig.yaml b/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig.yaml index 0556c43a..8ae84d0e 100644 --- a/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig.yaml +++ b/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig.yaml @@ -1,109 +1,57 @@ -# Get cluster URL - -- name: "Check if {{ cluster.name }} cluster config exists in {{ hive_namespace }} namespace" - kubernetes.core.k8s_info: - kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" - namespace: "{{ hive_namespace }}" - kind: ClusterDeployment - name: "{{ cluster.name }}" - verify_ssl: no - ignore_errors: true - register: cluster_present - -- name: "Wait for ClusterDeployment {{ cluster.name }} readiness" - kubernetes.core.k8s_info: - kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" - namespace: "{{ hive_namespace }}" - kind: ClusterDeployment - name: "{{ cluster.name }}" - wait: true - wait_timeout: 5 - verify_ssl: no - wait_condition: - type: Provisioned - status: True - reason: Provisioned - when: cluster_present.resources != [] - ignore_errors: true - register: readiness - -- debug: - msg: "{{ readiness }}" +################################## +#### Set kubeconfig data from yaml +################################## +- name: "Debug na zacatku" + debug: + msg: "{{ clusters_dict }}" -- name: "Update facts for {{ cluster.name }}" +- name: "Update facts for {{ cluster.name }} - kubeconfig based" ansible.utils.update_fact: updates: - - path: "clusters_dict['{{ cluster.name }}'].exists" - value: "{{ cluster_present.resources != [] }}" - - path: "clusters_dict['{{ cluster.name }}'].provisioned" - value: "{{ readiness.failed == False }}" - when: cluster_present.resources != [] - register: updated_data_ready + - path: "clusters_dict['{{ cluster.name }}'].serverUrl" + value: "{{ cluster.kubeconfig.serverUrl }}" + - path: "clusters_dict['{{ cluster.name }}'].provisionRefName" + value: "{{ cluster.name }}" + register: updated_data + when: cluster.kubeconfig is defined + +- set_fact: + clusters_dict: "{{ updated_data.clusters_dict }}" + when: cluster.kubeconfig is defined - name: "Update facts for {{ cluster.name }}" ansible.utils.update_fact: updates: - path: "clusters_dict['{{ cluster.name }}'].exists" - value: "{{ cluster_present.resources != [] }}" + value: True - path: "clusters_dict['{{ cluster.name }}'].provisioned" - value: False - when: cluster_present.resources == [] - register: updated_data_not_ready + value: True + when: cluster.kubeconfig is defined + register: kubeconfig_defined - set_fact: - clusters_dict: "{{ updated_data_not_ready.clusters_dict }}" - when: updated_data_not_ready.clusters_dict is defined - -- set_fact: - clusters_dict: "{{ updated_data_ready.clusters_dict }}" - when: updated_data_ready.clusters_dict is defined - -- debug: - msg: "{{ clusters_dict }}" - -- name: "Get cluster {{ cluster.name }} API URL" - shell: "oc get clusterdeployment {{ cluster.name }} -n {{ hive_namespace }} -o=jsonpath='{.status.apiURL}'" - environment: - KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" - register: serverUrl_output - when: clusters_dict[cluster.name].provisioned - -- name: "Get cluster {{ cluster.name }} provisionRef name" - shell: "oc get clusterdeployment {{ cluster.name }} -n {{ hive_namespace }} -o=jsonpath='{.status.provisionRef.name}'" - environment: - KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" - register: provisionRefName_output - when: clusters_dict[cluster.name].provisioned - -- name: "Extract kubeconfig for cluster {{ cluster.name }}" - shell: "oc extract secret/{{ provisionRefName_output.stdout }}-admin-kubeconfig -n {{ hive_namespace }} --to=- --keys=kubeconfig" - environment: - KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" - register: kubeconfig_output - when: clusters_dict[cluster.name].provisioned - -- name: "Update facts for {{ cluster.name }}" - ansible.utils.update_fact: - updates: - - path: "clusters_dict['{{ cluster.name }}'].serverUrl" - value: "{{ serverUrl_output.stdout }}" - - path: "clusters_dict['{{ cluster.name }}'].provisionRefName" - value: "{{ provisionRefName_output.stdout }}" - register: updated_data - when: clusters_dict[cluster.name].provisioned + clusters_dict: "{{ kubeconfig_defined.clusters_dict }}" + when: cluster.kubeconfig is defined - set_fact: - clusters_dict: "{{ updated_data.clusters_dict }}" - when: clusters_dict[cluster.name].provisioned + kubeconfig_data: "{{ cluster.kubeconfig.kubeconfig }}" + when: cluster.kubeconfig is defined - name: Create kubeconfig for {{ cluster.name }} copy: - content: "{{ kubeconfig_output.stdout }}" + content: "{{ kubeconfig_data | b64decode }}" dest: "{{ kubeconfig_path }}/{{ cluster.name }}" - when: clusters_dict[cluster.name].provisioned + when: cluster.kubeconfig is defined +##################### +#### Common part #### +##################### - name: Set proper rights for kubeconfigs on {{ cluster.name }} file: path: "{{ kubeconfig_path }}/{{ cluster.name }}" mode: '0755' when: clusters_dict[cluster.name].provisioned + +- name: "Debug na konci" + debug: + msg: "{{ clusters_dict }}" diff --git a/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig_hive.yaml b/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig_hive.yaml new file mode 100644 index 00000000..0ac0aacc --- /dev/null +++ b/install/roles/automation-hub/tasks/common/setup_cluster_kubeconfig_hive.yaml @@ -0,0 +1,111 @@ +# Get cluster URL in Hive +- name: "Check if {{ cluster.name }} cluster config exists in {{ hive_namespace }} namespace" + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" + namespace: "{{ hive_namespace }}" + kind: ClusterDeployment + name: "{{ cluster.name }}" + verify_ssl: no + ignore_errors: true + register: cluster_present + +- name: "Wait for ClusterDeployment {{ cluster.name }} readiness" + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" + namespace: "{{ hive_namespace }}" + kind: ClusterDeployment + name: "{{ cluster.name }}" + wait: true + wait_timeout: 5 + verify_ssl: no + wait_condition: + type: Provisioned + status: True + reason: Provisioned + when: cluster_present.resources != [] and cluster.kubeconfig is undefined + ignore_errors: true + register: readiness + +- debug: + msg: "{{ readiness }}" + +- name: "Update facts for {{ cluster.name }}" + ansible.utils.update_fact: + updates: + - path: "clusters_dict['{{ cluster.name }}'].exists" + value: "{{ cluster_present.resources != [] }}" + - path: "clusters_dict['{{ cluster.name }}'].provisioned" + value: "{{ readiness.failed == False }}" + when: cluster_present.resources != [] + register: updated_data_ready + +- name: "Update facts for {{ cluster.name }}" + ansible.utils.update_fact: + updates: + - path: "clusters_dict['{{ cluster.name }}'].exists" + value: "{{ cluster_present.resources != [] }}" + - path: "clusters_dict['{{ cluster.name }}'].provisioned" + value: False + when: cluster_present.resources == [] + register: updated_data_not_ready + +- set_fact: + clusters_dict: "{{ updated_data_not_ready.clusters_dict }}" + when: updated_data_not_ready.clusters_dict is defined + +- set_fact: + clusters_dict: "{{ updated_data_ready.clusters_dict }}" + when: updated_data_ready.clusters_dict is defined + +- debug: + msg: "{{ clusters_dict }}" + +- name: "Get cluster {{ cluster.name }} API URL" + shell: "oc get clusterdeployment {{ cluster.name }} -n {{ hive_namespace }} -o=jsonpath='{.status.apiURL}'" + environment: + KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" + register: serverUrl_output + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +- name: "Get cluster {{ cluster.name }} provisionRef name" + shell: "oc get clusterdeployment {{ cluster.name }} -n {{ hive_namespace }} -o=jsonpath='{.status.provisionRef.name}'" + environment: + KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" + register: provisionRefName_output + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +- name: "Extract kubeconfig for cluster {{ cluster.name }}" + shell: "oc extract secret/{{ provisionRefName_output.stdout }}-admin-kubeconfig -n {{ hive_namespace }} --to=- --keys=kubeconfig" + environment: + KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" + register: kubeconfig_output + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +- name: "Update facts for {{ cluster.name }}" + ansible.utils.update_fact: + updates: + - path: "clusters_dict['{{ cluster.name }}'].serverUrl" + value: "{{ serverUrl_output.stdout }}" + - path: "clusters_dict['{{ cluster.name }}'].provisionRefName" + value: "{{ provisionRefName_output.stdout }}" + register: updated_data + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +- set_fact: + clusters_dict: "{{ updated_data.clusters_dict }}" + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +- name: Create kubeconfig for {{ cluster.name }} + copy: + content: "{{ kubeconfig_output.stdout }}" + dest: "{{ kubeconfig_path }}/{{ cluster.name }}" + when: clusters_dict[cluster.name].provisioned and cluster.kubeconfig is undefined + +##################### +#### Common part #### +##################### +- name: Set proper rights for kubeconfigs on {{ cluster.name }} + file: + path: "{{ kubeconfig_path }}/{{ cluster.name }}" + mode: '0755' + when: clusters_dict[cluster.name].provisioned diff --git a/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubed.yaml b/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubed.yaml deleted file mode 100644 index fca4430b..00000000 --- a/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubed.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: Delete KubeD on infra clusters - kubernetes.core.k8s: - kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" - namespace: "kube-system" - state: absent - apply: true - template: templates/kubed/kubed.yaml.j2 - verify_ssl: no - -- name: Delete KubeD on worker clusters - kubernetes.core.k8s: - kubeconfig: "{{ kubeconfig_path }}/{{ worker.value.name }}" - namespace: "kube-system" - state: absent - apply: true - template: templates/kubed/kubed.yaml.j2 - verify_ssl: no - loop: "{{ workers | dict2items }}" - loop_control: - loop_var: worker diff --git a/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubernetes-replicator.yaml b/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubernetes-replicator.yaml new file mode 100644 index 00000000..e707582d --- /dev/null +++ b/install/roles/automation-hub/tasks/infra-setup/delete/delete_kubernetes-replicator.yaml @@ -0,0 +1,21 @@ +--- +- name: Delete Kubernetes Replicator on infra clusters + kubernetes.core.k8s: + kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" + namespace: "kube-system" + state: absent + apply: true + template: templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 + verify_ssl: no + +- name: Delete Kubernetes Replicator on worker clusters + kubernetes.core.k8s: + kubeconfig: "{{ kubeconfig_path }}/{{ worker.name }}" + namespace: "kube-system" + state: absent + apply: true + template: templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 + verify_ssl: no + loop: "{{ clusters_dict.values() }}" + loop_control: + loop_var: worker diff --git a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-management/install_observability.yaml b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-management/install_observability.yaml index 36b15f1b..7972dbc8 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-management/install_observability.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-management/install_observability.yaml @@ -60,6 +60,6 @@ apply: true template: "templates/acm/08-extend-default-metrics-allowlist.yaml.j2" verify_ssl: no - loop: "{{ clusters_dict }}" + loop: "{{ clusters_dict.values() }}" loop_control: loop_var: worker diff --git a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/install_acs_central.yaml b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/install_acs_central.yaml index d805add2..84f8a3ea 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/install_acs_central.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/install_acs_central.yaml @@ -44,17 +44,17 @@ when: acs_central.changed - name: "Wait for Central custom resource on Infra cluster" - kubernetes.core.k8s: + kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "{{ acs_namespace }}" - kind: Central - api_version: platform.stackrox.io/v1alpha1 - name: stackrox-central-services + kind: Deployment + api_version: apps/v1 + name: central wait: true verify_ssl: no wait_condition: - type: Deployed + type: Available status: True - reason: UpgradeSuccessful + reason: MinimumReplicasAvailable retries: 60 delay: 10 diff --git a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/register_cluster.yaml b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/register_cluster.yaml index d777e546..efe80879 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/register_cluster.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/advanced-cluster-security/register_cluster.yaml @@ -20,7 +20,7 @@ - name: Generate api token shell: | - curl -k -X POST -u "admin:`oc get secret central-htpasswd -o yaml -n {{ acs_namespace }} | grep "password" | awk '{print $2}' | base64 -d`" "$ROX_ENDPOINT/v1/apitokens/generate" -d '{"name":"admin-{{ lookup('community.general.random_string', length=4, special=False) }}", "role": "Admin"}' | jq .token > {{ acs_api_token_file }} + curl -k -X POST -u "admin:`oc get secret central-htpasswd -o yaml -n {{ acs_namespace }} | grep "password" | awk '{print $2}' | base64 -d`" "{{ acs_central_url }}/v1/apitokens/generate" -d '{"name":"admin-{{ lookup('community.general.random_string', length=4, special=False) }}", "role": "Admin"}' | jq -r .token > {{ acs_api_token_file }} oc create secret generic stackrox-api-token --from-file token={{ acs_api_token_file }} -n "{{ acs_namespace }}" environment: KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" @@ -68,4 +68,4 @@ verify_ssl: no template: "{{ item }}" loop: - - templates/acs/03-secure-cluster.yaml.j2 \ No newline at end of file + - templates/acs/03-secure-cluster.yaml.j2 diff --git a/install/roles/automation-hub/tasks/infra-setup/install/cert-manager/00-install_cert_manager.yaml b/install/roles/automation-hub/tasks/infra-setup/install/cert-manager/00-install_cert_manager.yaml index c58abebb..48880d9a 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/cert-manager/00-install_cert_manager.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/cert-manager/00-install_cert_manager.yaml @@ -1,5 +1,5 @@ --- -- name: "Label namespaces for KubeD on {{ cluster_name }}" +- name: "Label namespaces for Kubernetes Replicator on {{ cluster_name }}" kubernetes.core.k8s_json_patch: kubeconfig: "{{ kubeconfig_path }}/{{ cluster_name }}" kind: Namespace @@ -56,15 +56,29 @@ kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}/{{ cluster_name }}" namespace: "{{ cm_operator_namespace }}" - kind: CertManager - name: "cluster" + kind: Deployment + api_version: apps/v1 + name: cert-manager-operator-controller-manager wait: true verify_ssl: no wait_condition: - type: cert-manager-controller-deploymentAvailable + type: Available status: True - retries: 20 - delay: 5 + reason: MinimumReplicasAvailable + +- name: "Wait for Cert-Manager on {{ cluster_name }}" + kubernetes.core.k8s_info: + kubeconfig: "{{ kubeconfig_path }}/{{ cluster_name }}" + namespace: "cert-manager" + kind: Deployment + api_version: apps/v1 + name: cert-manager + wait: true + verify_ssl: no + wait_condition: + type: Available + status: True + reason: MinimumReplicasAvailable - name: "Create Certificate Issuer on {{ cluster_name }}" kubernetes.core.k8s: diff --git a/install/roles/automation-hub/tasks/infra-setup/install/cluster-logging/install_loki_stack.yaml b/install/roles/automation-hub/tasks/infra-setup/install/cluster-logging/install_loki_stack.yaml index 2fd54854..e2facd18 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/cluster-logging/install_loki_stack.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/cluster-logging/install_loki_stack.yaml @@ -38,6 +38,7 @@ kubeconfig: "{{ kubeconfig_path }}/{{ clusterName }}" namespace: "openshift-operators-redhat" kind: Deployment + api_version: apps/v1 name: loki-operator-controller-manager wait: true wait_sleep: 10 diff --git a/install/roles/automation-hub/tasks/infra-setup/install/create_clusters_hive.yaml b/install/roles/automation-hub/tasks/infra-setup/install/create_clusters_hive.yaml index 874ff09d..f0b3745c 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/create_clusters_hive.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/create_clusters_hive.yaml @@ -14,3 +14,4 @@ loop: "{{ clusters_dict.values() }}" loop_control: loop_var: cluster + when: not clusters_dict[cluster.name].provisioned diff --git a/install/roles/automation-hub/tasks/infra-setup/install/install_argo.yaml b/install/roles/automation-hub/tasks/infra-setup/install/install_argo.yaml index 79ea2b64..a2650c2e 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/install_argo.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/install_argo.yaml @@ -21,7 +21,7 @@ verify_ssl: no src: "{{ grafana_docker_secret_path }}" -- name: Create argo subscription +- name: Create Argo subscription kubernetes.core.k8s: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" state: present @@ -34,14 +34,15 @@ timeout: 5 when: argo_sub.changed -- name: Wait for argo operator on Infra cluster +- name: Wait for Argo operator on Infra cluster kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "{{ openshift_operators_namespace }}" kind: Deployment - name: gitops-operator-controller-manager - wait: true + api_version: apps/v1 + name: openshift-gitops-operator-controller-manager verify_ssl: no + wait: true wait_condition: type: Available status: True @@ -57,7 +58,7 @@ environment: KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" -- name: Create argo app +- name: Create Argo app kubernetes.core.k8s: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "{{ infra_argo_namespace }}" @@ -90,6 +91,7 @@ kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "{{ infra_argo_namespace }}" kind: Deployment + api_version: apps/v1 name: tealc-gitops-server wait: true verify_ssl: no @@ -97,14 +99,13 @@ type: Available status: True reason: MinimumReplicasAvailable - retries: 20 - delay: 5 - name: Wait for argo dex on infra cluster kubernetes.core.k8s_info: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "{{ infra_argo_namespace }}" kind: Deployment + api_version: apps/v1 name: tealc-gitops-dex-server wait: true verify_ssl: no @@ -112,8 +113,6 @@ type: Available status: True reason: MinimumReplicasAvailable - retries: 20 - delay: 5 - name: Create argo app-projects kubernetes.core.k8s: diff --git a/install/roles/automation-hub/tasks/infra-setup/install/install_kubed.yaml b/install/roles/automation-hub/tasks/infra-setup/install/install_kubernetes-replicator.yaml similarity index 61% rename from install/roles/automation-hub/tasks/infra-setup/install/install_kubed.yaml rename to install/roles/automation-hub/tasks/infra-setup/install/install_kubernetes-replicator.yaml index 371353a5..a0b73617 100644 --- a/install/roles/automation-hub/tasks/infra-setup/install/install_kubed.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/install/install_kubernetes-replicator.yaml @@ -1,19 +1,19 @@ -- name: Deploy KubeD on infra clusters +- name: Deploy Kubernetes Replicator on infra clusters kubernetes.core.k8s: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" namespace: "kube-system" state: present apply: true - template: templates/kubed/kubed.yaml.j2 + template: templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 verify_ssl: no -- name: Deploy KubeD on worker clusters +- name: Deploy Kubernetes Replicator on worker clusters kubernetes.core.k8s: kubeconfig: "{{ kubeconfig_path }}/{{ cluster.name }}" namespace: "kube-system" state: present apply: true - template: templates/kubed/kubed.yaml.j2 + template: templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 verify_ssl: no loop: "{{ clusters_dict.values() }}" loop_control: diff --git a/install/roles/automation-hub/tasks/infra-setup/prepare_access.yaml b/install/roles/automation-hub/tasks/infra-setup/prepare_access.yaml index 2ed56464..2b4dc148 100644 --- a/install/roles/automation-hub/tasks/infra-setup/prepare_access.yaml +++ b/install/roles/automation-hub/tasks/infra-setup/prepare_access.yaml @@ -125,7 +125,7 @@ metadata: name: "odh-s3-data-connection" annotations: - kubed.appscode.com/sync: "app=open-data-hub" + replicator.v1.mittwald.de/replicate-to-matching: "app=open-data-hub" opendatahub.io/connection-type: s3 openshift.io/display-name: "{{ bucketname }}" labels: diff --git a/install/roles/automation-hub/tasks/main.yml b/install/roles/automation-hub/tasks/main.yml index 64a6bd0f..4c26fc3c 100644 --- a/install/roles/automation-hub/tasks/main.yml +++ b/install/roles/automation-hub/tasks/main.yml @@ -80,8 +80,8 @@ - import_tasks: monitoring/install_monitoring.yaml tags: [monitoring, grafana, infra, never] -- import_tasks: infra-setup/install/install_kubed.yaml - tags: [kubed, infra, never] +- import_tasks: infra-setup/install/install_kubernetes-replicator.yaml + tags: [kubernetes-replicator, infra, never] - import_tasks: infra-setup/install/orchestrate_cert_manager.yaml tags: [cert-manager, cm, infra, never] @@ -142,5 +142,5 @@ - import_tasks: infra-setup/delete/delete_acs.yaml tags: [never, teardown-acs, teardown, teardown-security] -- import_tasks: infra-setup/delete/delete_kubed.yaml - tags: [never, teardown, teardown-kubed] +- import_tasks: infra-setup/delete/delete_kubernetes-replicator.yaml + tags: [never, teardown, teardown-kubernetes-replicator] diff --git a/install/roles/automation-hub/tasks/scenario-deployment/tekton/infra-tkn-pipelines.yaml b/install/roles/automation-hub/tasks/scenario-deployment/tekton/infra-tkn-pipelines.yaml index 476df33b..c38a489b 100644 --- a/install/roles/automation-hub/tasks/scenario-deployment/tekton/infra-tkn-pipelines.yaml +++ b/install/roles/automation-hub/tasks/scenario-deployment/tekton/infra-tkn-pipelines.yaml @@ -76,11 +76,6 @@ apply: true template: "templates/tekton/pipelines/test-suite/odh-e2e-standard-metrics-collector.yaml" -- name: "Rollout collector" - shell: "oc rollout restart deployment/tealc-metrics-collector -n {{ infra_ci_namespace }}" - environment: - KUBECONFIG: "{{ kubeconfig_path }}/{{ infra_context_name }}" - - name: Create Tekton pipelines from jinja templates for release_cluster and downstream_cluster kubernetes.core.k8s: kubeconfig: "{{ kubeconfig_path }}/{{ infra_context_name }}" diff --git a/install/roles/automation-hub/templates/acm/08-extend-default-metrics-allowlist.yaml.j2 b/install/roles/automation-hub/templates/acm/08-extend-default-metrics-allowlist.yaml.j2 index fc109d8c..297188d4 100644 --- a/install/roles/automation-hub/templates/acm/08-extend-default-metrics-allowlist.yaml.j2 +++ b/install/roles/automation-hub/templates/acm/08-extend-default-metrics-allowlist.yaml.j2 @@ -2,9 +2,9 @@ kind: ConfigMap apiVersion: v1 metadata: name: observability-metrics-custom-allowlist - # let kubed sync the config map accross all namespaces + # let kubernetes-replicator sync the config map accross all namespaces annotations: - kubed.appscode.com/sync: "" + replicator.v1.mittwald.de/replicate-to: ".*" data: metrics_list.yaml: | names: diff --git a/install/roles/automation-hub/templates/cert-manager/03-certificate.yaml.j2 b/install/roles/automation-hub/templates/cert-manager/03-certificate.yaml.j2 index 725a82f4..5690a7c8 100644 --- a/install/roles/automation-hub/templates/cert-manager/03-certificate.yaml.j2 +++ b/install/roles/automation-hub/templates/cert-manager/03-certificate.yaml.j2 @@ -12,6 +12,6 @@ spec: name: lets-encrypt secretName: {{ cm_certificate_secret }} secretTemplate: - # let kubed sync the config map accross all namespaces + # let kubernetes-replicator sync the config map accross all namespaces annotations: - kubed.appscode.com/sync: "secret=cert-manager" + replicator.v1.mittwald.de/replicate-to-matching: "secret=cert-manager" diff --git a/install/roles/automation-hub/templates/kubed/kubed.yaml.j2 b/install/roles/automation-hub/templates/kubed/kubed.yaml.j2 deleted file mode 100644 index 5ba580de..00000000 --- a/install/roles/automation-hub/templates/kubed/kubed.yaml.j2 +++ /dev/null @@ -1,226 +0,0 @@ ---- -# Source: kubed/templates/serviceaccount.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: kubed - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm ---- -# Source: kubed/templates/apiregistration.yaml -apiVersion: v1 -kind: Secret -metadata: - name: kubed-apiserver-cert - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -type: Opaque -data: - tls.crt: {{ kubed_tls_cert }} - tls.key: {{ kubed_tls_key }} ---- -# Source: kubed/templates/secret.yaml -apiVersion: v1 -kind: Secret -metadata: - name: kubed - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -data: ---- -# Source: kubed/templates/cluster-role.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: kubed - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -rules: -- apiGroups: [""] - resources: - - configmaps - - secrets - verbs: ["get", "create", "patch", "delete", "list", "watch"] -- apiGroups: [""] - resources: - - namespaces - verbs: ["get", "list", "watch"] -- apiGroups: [""] - resources: - - nodes - verbs: ["list"] -- apiGroups: [""] - resources: - - events - verbs: ["create"] ---- -# Source: kubed/templates/apiregistration.yaml -# to delegate authentication and authorization -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: kubed-apiserver-auth-delegator - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -roleRef: - kind: ClusterRole - apiGroup: rbac.authorization.k8s.io - name: system:auth-delegator -subjects: -- kind: ServiceAccount - name: kubed - namespace: kube-system ---- -# Source: kubed/templates/cluster-role-binding.yaml -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: kubed - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: kubed -subjects: -- kind: ServiceAccount - name: kubed - namespace: kube-system ---- -# Source: kubed/templates/apiregistration.yaml -# to read the config for terminating authentication -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: kubed-apiserver-extension-server-authentication-reader - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -roleRef: - kind: Role - apiGroup: rbac.authorization.k8s.io - name: extension-apiserver-authentication-reader -subjects: -- kind: ServiceAccount - name: kubed - namespace: kube-system ---- -# Source: kubed/templates/service.yaml -apiVersion: v1 -kind: Service -metadata: - name: kubed - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -spec: - ports: - # Port used to expose admission webhook apiserver - - name: api - port: 443 - targetPort: 8443 - selector: - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed ---- -# Source: kubed/templates/deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: kubed - namespace: kube-system - labels: - helm.sh/chart: kubed-v0.12.0 - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - app.kubernetes.io/version: "v0.12.0" - app.kubernetes.io/managed-by: Helm -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - template: - metadata: - labels: - app.kubernetes.io/name: kubed - app.kubernetes.io/instance: kubed - annotations: - checksum/apiregistration.yaml: 0b9e2b121d6585b4396bed5a227704461197b1b8ac0ebf0b266721d075081ac5 - spec: - serviceAccountName: kubed - containers: - - name: kubed - securityContext: - {} - image: appscode/kubed:v0.12.0 - imagePullPolicy: IfNotPresent - args: - - run - - --v=3 - - --secure-port=8443 - - --audit-log-path=- - - --tls-cert-file=/var/serving-cert/tls.crt - - --tls-private-key-file=/var/serving-cert/tls.key - - --use-kubeapiserver-fqdn-for-aks=true - - --enable-analytics=true - - --cluster-name=unicorn - ports: - - containerPort: 8443 - resources: - {} - volumeMounts: - - name: config - mountPath: /srv/kubed - - name: scratch - mountPath: /tmp - - mountPath: /var/serving-cert - name: serving-cert - volumes: - - name: config - secret: - secretName: kubed - - name: scratch - emptyDir: {} - - name: serving-cert - secret: - defaultMode: 420 - secretName: kubed-apiserver-cert - securityContext: - fsGroup: 65535 diff --git a/install/roles/automation-hub/templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 b/install/roles/automation-hub/templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 new file mode 100644 index 00000000..fbef0992 --- /dev/null +++ b/install/roles/automation-hub/templates/kubernetes-replicator/kubernetes-replicator.yaml.j2 @@ -0,0 +1,75 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: replicator-kubernetes-replicator + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: replicator-kubernetes-replicator +rules: + - apiGroups: [ "" ] + resources: [ "namespaces" ] + verbs: [ "get", "watch", "list" ] + - apiGroups: [""] # "" indicates the core API group + resources: ["secrets", "configmaps", "serviceaccounts"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["roles", "rolebindings"] + verbs: ["get", "watch", "list", "create", "update", "patch", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: replicator-kubernetes-replicator +roleRef: + kind: ClusterRole + name: replicator-kubernetes-replicator + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: replicator-kubernetes-replicator + namespace: kube-system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: replicator-kubernetes-replicator + namespace: kube-system + labels: + app.kubernetes.io/name: kubernetes-replicator + app.kubernetes.io/instance: replicator +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: kubernetes-replicator + app.kubernetes.io/instance: replicator + template: + metadata: + labels: + app.kubernetes.io/name: kubernetes-replicator + app.kubernetes.io/instance: replicator + spec: + serviceAccountName: replicator-kubernetes-replicator + securityContext: {} + containers: + - name: kubernetes-replicator + securityContext: {} + image: quay.io/mittwald/kubernetes-replicator:latest + imagePullPolicy: Always + args: [] + ports: + - name: health + containerPort: 9102 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: health + readinessProbe: + httpGet: + path: /readyz + port: health + resources: {} diff --git a/install/roles/automation-hub/templates/tekton/pipelines/test-suite/odh-e2e-standard-metrics-collector.yaml b/install/roles/automation-hub/templates/tekton/pipelines/test-suite/odh-e2e-standard-metrics-collector.yaml index 17a658d4..2e4839f2 100644 --- a/install/roles/automation-hub/templates/tekton/pipelines/test-suite/odh-e2e-standard-metrics-collector.yaml +++ b/install/roles/automation-hub/templates/tekton/pipelines/test-suite/odh-e2e-standard-metrics-collector.yaml @@ -23,7 +23,7 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: och-e2e-standard-metrics-collector + name: odh-e2e-standard-metrics-collector labels: app: odh-e2e-standard-metrics-collector spec: diff --git a/install/secrets/clusters.yaml b/install/secrets/clusters.yaml index 195d55a6df9b82075b6e217509f78acd4b9d3f0e..658bfaf3c2c116bc4b72176acb7d4a063d006977 100644 GIT binary patch literal 43879 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 L1JI1zd%q1)n1WDO literal 11524 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 diff --git a/install/secrets/quay-io.yaml b/install/secrets/quay-io.yaml index 956d8909a5903a7a9dffeca4e207b0075a69b18d..ca4f9d581f7b93988a5ac11b41d374982be47fad 100644 GIT binary patch literal 637 zcmV-@0)qVjM@dveQdv+`07N-Ew}Tyz%g7IldyUmJw5`b4(#2O0?Y*5%|0aeO<1N_n zjukT0kU(*=X)SFDdNT}mKr%vE=ZJt4@%>z=#3uk*4DCcS21DHp) zU(wQ^btyxoZWvy_+&}#^GnU{&O4`Patkkk0`TD8FiAFJ-&FzAOEE-?!L{g01spCgp z(0|&SH41aH`|Mya!d~hwrN8|tLPja?nZSjlEgp6tWl-HI8fWuRcg5Oh~$aJU2<34j92_irku zLhsjW-r3fznK^*O8aBUsYI#OvL=xsz$12yYfI z5@OoHwPk(RP1F>OtOLiZP5*V*oeU9$askKur`Rh1^LT(u+=(t}h++7;4U|o^&)TGG zXlwm+Xkt!LmQS;@VB-nOg?fTYpr;j6myuNM;xAxO7&H`U{_#SXQ@;T?_sc0IsWrB4 zCzn6EKv7STV+7IjhO7w1crv5j zj01(2YR{xAz@d|ShtdjyTlmP()7;-M?Is)obRva*PbMze5)%2P+#>DwGhH#M--8Dz zaqT?f=TD%$AoXA%3{mQWVfPCWwVo{v)bz3YyMGgx1&}sx2{Vzu z2Wnr_qJ^0)FDDy{y!e#KSxTxpN%Dk)x!VkYK8?&?9i0)$_mb3&?fng~SfzY-#(aRb z%re}#lL#95Unvh`H_+S=g qU5j0vph%E({hyxvd6K$ya56se^={AhjV#l%PoYMQuj%e`-Q=e>Bs7Nr