From 9c1370d2f48894827967ad8e1fb76962aaed4ee8 Mon Sep 17 00:00:00 2001 From: Daniel Pawlik Date: Wed, 6 Nov 2024 11:30:51 +0100 Subject: [PATCH] Add crc-cloud Ansible role The Ansible tool might handle in better way how to deploy the CRC cloud. --- ansible/README.md | 59 ++++++++++ ansible/playbooks/bootstrap.yaml | 108 ++++++++++++++++++ ansible/playbooks/start.yaml | 1 + .../roles/deploy-crc-cloud/defaults/main.yaml | 33 ++++++ .../deploy-crc-cloud/tasks/console_route.yaml | 16 +++ .../create_certificate_and_patch_secret.yaml | 20 ++++ .../roles/deploy-crc-cloud/tasks/dnsmasq.yaml | 51 +++++++++ .../deploy-crc-cloud/tasks/get_htpasswd.yaml | 11 ++ .../deploy-crc-cloud/tasks/kubeconfig.yaml | 15 +++ .../roles/deploy-crc-cloud/tasks/kubelet.yaml | 30 +++++ .../roles/deploy-crc-cloud/tasks/login.yaml | 14 +++ .../roles/deploy-crc-cloud/tasks/main.yaml | 69 +++++++++++ .../tasks/patch_api_server.yaml | 7 ++ .../tasks/patch_default_route.yaml | 9 ++ .../tasks/patch_ingress_config.yaml | 26 +++++ .../tasks/patch_pull_secret.yaml | 11 ++ .../roles/deploy-crc-cloud/tasks/pubkey.yaml | 25 ++++ .../tasks/replace_default_ca.yaml | 52 +++++++++ .../tasks/set_credentials.yaml | 22 ++++ .../tasks/wait_cluster_become_healthy.yaml | 22 ++++ .../tasks/wait_for_resource.yaml | 17 +++ 21 files changed, 618 insertions(+) create mode 100644 ansible/README.md create mode 100644 ansible/playbooks/bootstrap.yaml create mode 100644 ansible/playbooks/start.yaml create mode 100644 ansible/roles/deploy-crc-cloud/defaults/main.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/console_route.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/create_certificate_and_patch_secret.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/dnsmasq.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/get_htpasswd.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/kubeconfig.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/kubelet.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/login.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/main.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/patch_api_server.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/patch_default_route.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/patch_ingress_config.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/patch_pull_secret.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/pubkey.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/replace_default_ca.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/set_credentials.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/wait_cluster_become_healthy.yaml create mode 100644 ansible/roles/deploy-crc-cloud/tasks/wait_for_resource.yaml diff --git a/ansible/README.md b/ansible/README.md new file mode 100644 index 00000000..2fe2ffd0 --- /dev/null +++ b/ansible/README.md @@ -0,0 +1,59 @@ +# Deploy CRC cloud directly on CRC host + +## Introduction + +The CRC cloud tool deploys the CRC host using its own binary, but it +requires access to the cloud provider credentials. That functionality +is useless when the CRC cloud needs to be used in externa CI, where +the crc-cloud tool can not be used - especially when the CI is responsible +to check how many VMs are spawned or checking job results. + +## CRC QCOW2 image + +There is a simply way to bootstrap the CRC without using the crc-cloud +tool and upload it to your cloud provider: + +- download libvirt bundle (you can see url when crc is in debug mode) +- extract libvirt bundle using tar command with zst: + +```shell +tar xaf crc_libvirt_$VERSION_amd64.crcbundle +``` + +- upload crc.qcow2 image to your cloud provider +- take the id_ecdsa_crc file + +## Bootstrap crc-cloud directly on host + +Now after spawning VM using the `crc.qcow2` image: + +- prepare `inventory.yaml` file: + +```shell +CRC_VM_IP= + +cat << EOF > inventory.yaml +--- +all: + hosts: + crc-cloud.dev: + ansible_port: 22 + ansible_host: $CRC_VM_IP + ansible_user: core + vars: + openshift_pull_secret: | + < PULL SECRET > +EOF +``` + +- clone crc-cloud project (FIXME: change repository) + +```shell +git clone https://github.com/danpawlik/crc-cloud -b add-ansible-role +``` + +- run playbook to boostrap the container that later would start deploy-crc-cloud role + +```shell +ansible-playbook -i inventory.yaml crc-cloud/ansible/playbooks/bootstrap.yaml +``` diff --git a/ansible/playbooks/bootstrap.yaml b/ansible/playbooks/bootstrap.yaml new file mode 100644 index 00000000..65a5c949 --- /dev/null +++ b/ansible/playbooks/bootstrap.yaml @@ -0,0 +1,108 @@ +--- +- name: Prepare and create container to start crc-cloud playbook + hosts: crc-cloud.dev + tasks: + # FIXME: change to main repository + - name: Clone crc-cloud repository + ansible.builtin.git: + repo: https://github.com/danpawlik/crc-cloud + dest: crc-cloud + version: add-ansible-role + + - name: Check if boostrap ssh key exists + ansible.builtin.stat: + path: .ssh/crc-cloud-bootstrap.pub + register: _boostrap_ssh_key + + - name: Generate ssh keypair + when: not _boostrap_ssh_key.stat.exists + community.crypto.openssh_keypair: + path: .ssh/crc-cloud-bootstrap + type: ed25519 + state: present + owner: core + group: core + + - name: Add generated key to authorized keys + ansible.builtin.shell: | + cat .ssh/crc-cloud-bootstrap.pub >> .ssh/authorized_keys.d/ignition + + # FIXME: move it to dedicated files + - name: Create entrypoint file + ansible.builtin.copy: + content: | + #!/bin/bash + + echo "Check if ${HOME}/inventory.yaml exists..." + if ! [ -f "${HOME}/inventory.yaml" ]; then + echo "Starting Ansible..." + export ANSIBLE_HOST_KEY_CHECKING=False + export ANSIBLE_LOG_PATH=/home/user/ansible-logs/ansible.log + ansible-playbook -i "${HOME}/inventory.yaml" "${HOME}/crc-cloud/ansible/playbooks/start.yaml" + else + echo "Could not find inventory file. Exit" + exit 1 + fi + dest: entrypoint.sh + + - name: Prepare Dockerfile + ansible.builtin.copy: + content: | + FROM quay.io/centos/centos:stream9 + + RUN dnf install -y ansible-core sudo && \ + ansible-galaxy collection install community.general \ + community.crypto ansible.posix \ + kubernetes.core + + + RUN groupadd --gid 1000 user && \ + useradd --uid 1000 --gid 1000 -d /home/user user + COPY entrypoint.sh /home/user/entrypoint.sh + RUN chown -R user:user /home/user && chmod +x /home/user/entrypoint.sh + + USER user + WORKDIR /home/user + ENTRYPOINT ["/home/user/entrypoint.sh"] + + dest: Dockerfile + + - name: Build bootstrap container + ansible.builtin.shell: | + podman build -t crc-cloud-bootstrap -f Dockerfile + + - name: Create inventory file + ansible.builtin.copy: + content: | + --- + all: + hosts: + {{ ansible_fqdn }}: + ansible_port: 22 + ansible_host: {{ ansible_default_ipv4.address }} + ansible_user: core + vars: + openshift_pull_secret: | + {{ openshift_pull_secret }} + dest: inventory.yaml + + - name: Create Ansible log directory + ansible.builtin.file: + path: ansible-logs + state: directory + owner: core + group: core + + - name: Create container to boostrap + ansible.builtin.shell: > + podman create --name crc-cloud-boostrap + --network host + -v "/var/home/core/.ssh:/home/user/.ssh:z" + -v "/var/home/core/inventory.yaml:/home/user/inventory.yaml" + -v "/var/home/core/crc-cloud:/home/user/crc-cloud:z" + -v "/var/home/core/ansible-logs:/home/user/ansible-logs:z" + crc-cloud-bootstrap + + - name: Start the container + ansible.builtin.shell: | + podman start crc-cloud-boostrap diff --git a/ansible/playbooks/start.yaml b/ansible/playbooks/start.yaml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible/playbooks/start.yaml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/deploy-crc-cloud/defaults/main.yaml b/ansible/roles/deploy-crc-cloud/defaults/main.yaml new file mode 100644 index 00000000..e6f104bb --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/defaults/main.yaml @@ -0,0 +1,33 @@ +--- +dnsmasq_conf_path: /etc/dnsmasq.d/crc-dnsmasq.conf +openshift_pull_secret: "" +eip: crc.dev +alternative_domain: nip.io + +# wait for resource +max_retry: 20 +wait_interval: 5 + +# wait cluster become healthy +max_retries: 20 +retry_delay: 5 + +pass_developer: _PASS_DEVELOPER_ +pass_kubeadmin: _PASS_KUBEADMIN_ +pass_redhat: _PASS_REDHAT_ + +users: + - name: developer + password: "{{ pass_developer }}" + - name: kubeadmin + password: "{{ pass_kubeadmin }}" + - name: redhat + password: "{{ pass_redhat }}" + +# replace default ca +ca_user: "system:admin" +ca_group: "system:masters" +ca_user_subj: "/O=${GROUP}/CN=${USER}" +ca_name: "custom" +ca_subj: "/OU=openshift/CN=admin-kubeconfig-signer-custom" +ca_validity: 3650 diff --git a/ansible/roles/deploy-crc-cloud/tasks/console_route.yaml b/ansible/roles/deploy-crc-cloud/tasks/console_route.yaml new file mode 100644 index 00000000..57e9c5c6 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/console_route.yaml @@ -0,0 +1,16 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L282 +- name: Get route to console custom + ansible.builtin.shell: | + oc get route console-custom -n openshift-console + register: _route_console_custom + until: _route_console_custom.rc != 1 + retries: 60 + delay: 10 + changed_when: false + +- name: Get console route + ansible.builtin.shell: > + oc get route console-custom + -n openshift-console + -o json | jq -r '.spec.host' diff --git a/ansible/roles/deploy-crc-cloud/tasks/create_certificate_and_patch_secret.yaml b/ansible/roles/deploy-crc-cloud/tasks/create_certificate_and_patch_secret.yaml new file mode 100644 index 00000000..e9b6a946 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/create_certificate_and_patch_secret.yaml @@ -0,0 +1,20 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L185 +- name: Create alternative cert + ansible.builtin.shell: > + openssl req + -newkey rsa:2048 + -new -nodes + -x509 + -days 3650 + -keyout nip.key + -out nip.crt + -subj "/CN={{ eip }}.{{ alternative_domain }}" + -addext "subjectAltName=DNS:apps.{{ eip }}.{{ alternative_domain }},DNS:*.apps.{{ eip }}.{{ alternative_domain }},DNS:api.{{ eip }}.{{ alternative_domain }}" + +- name: "Create secret for {{ alternative_domain }}" + ansible.builtin.command: > + oc create secret tls nip-secret + --cert=nip.crt + --key=nip.key + -n openshift-config diff --git a/ansible/roles/deploy-crc-cloud/tasks/dnsmasq.yaml b/ansible/roles/deploy-crc-cloud/tasks/dnsmasq.yaml new file mode 100644 index 00000000..5bb81f7d --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/dnsmasq.yaml @@ -0,0 +1,51 @@ +--- +# From https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L101 +- name: Create crc-dnsmasq.conf + become: true + ansible.builtin.copy: + content: | + listen-address={{ ansible_default_ipv4.address }} + expand-hosts + log-queries + local=/crc.testing/ + domain=crc.testing + address=/apps-crc.testing/{{ ansible_default_ipv4.address }} + address=/api.crc.testing/{{ ansible_default_ipv4.address }} + address=/api-int.crc.testing/{{ ansible_default_ipv4.address }} + address=/{{ ansible_fqdn }}.crc.testing/192.168.126.11 + dest: "{{ dnsmasq_conf_path }}" + register: _dnsmasq_conf + +- name: Set this host as first nameserver in /etc/resolv.conf + become: true + ansible.builtin.lineinfile: + path: /etc/resolv.conf + regexp: '^# Generated by NetworkManager' + line: "nameserver {{ item }}" + create: true + loop: "{{ [ansible_default_ipv4.address] + ansible_facts['dns']['nameservers'] | flatten }}" + register: _etc_resolv + +- name: Disable overwriting /etc/resolv.conf by the NetworkManager + become: true + ansible.builtin.copy: + content: | + [main] + dns=none + dest: /etc/NetworkManager/conf.d/00-custom-crc.conf + register: _disable_dns_overwrite + +- name: Restart NetworkManager when its needed + when: _disable_dns_overwrite.changed + become: true + ansible.builtin.systemd: + name: NetworkManager + state: restarted + +- name: Restart dnsmasq + when: _etc_resolv.changed + become: true + ansible.builtin.systemd: + name: dnsmasq + state: restarted + enabled: true diff --git a/ansible/roles/deploy-crc-cloud/tasks/get_htpasswd.yaml b/ansible/roles/deploy-crc-cloud/tasks/get_htpasswd.yaml new file mode 100644 index 00000000..1f4e1fb5 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/get_htpasswd.yaml @@ -0,0 +1,11 @@ +--- +- name: "Get htpasswd for {{ user.name }}" + ansible.builtin.shell: | + podman run --rm -ti xmartlabs/htpasswd {{ user.name }} {{ user.password }} + register: _user_hash + +- name: Create htpasswd.txt + ansible.builtin.lineinfile: + path: htpasswd.txt + line: "{{ _user_hash.stdout }}" + create: true diff --git a/ansible/roles/deploy-crc-cloud/tasks/kubeconfig.yaml b/ansible/roles/deploy-crc-cloud/tasks/kubeconfig.yaml new file mode 100644 index 00000000..baacdeb3 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/kubeconfig.yaml @@ -0,0 +1,15 @@ +--- +- name: Create kube directory + ansible.builtin.file: + path: .kube + state: directory + owner: core + group: core + +- name: Copy kubeconfig to user dir + ansible.builtin.copy: + src: /opt/kubeconfig + dest: .kube/config + remote_src: true + owner: core + group: core diff --git a/ansible/roles/deploy-crc-cloud/tasks/kubelet.yaml b/ansible/roles/deploy-crc-cloud/tasks/kubelet.yaml new file mode 100644 index 00000000..60ca7820 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/kubelet.yaml @@ -0,0 +1,30 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L132 +- name: Start and enable kubelet + become: true + ansible.builtin.systemd: + name: kubelet + state: started + enabled: true + +- name: Wait for port 6443 to be up + ansible.builtin.wait_for: + timeout: 300 + port: 6443 + delay: 60 + +- name: Wait for API to start before continue + ansible.builtin.command: > + oc get pods --all-namespaces + register: _openshift_containers + until: | + ('No resources found' not in _openshift_containers.stdout) or + ('connect: connection refused' not in _openshift_containers.stderr) or + ('get current server API group list' not in _openshift_containers.stderr) + retries: 60 + delay: 20 + changed_when: false + failed_when: + - "'connect: connection refused' in _openshift_containers.stderr" + - "'get current server API group list' in _openshift_containers.stderr" + - _openshift_containers.rc != 0 diff --git a/ansible/roles/deploy-crc-cloud/tasks/login.yaml b/ansible/roles/deploy-crc-cloud/tasks/login.yaml new file mode 100644 index 00000000..8707d92d --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/login.yaml @@ -0,0 +1,14 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L67 +- name: Try to login after all changes + ansible.builtin.command: > + oc login + --insecure-skip-tls-verify=true + -u kubeadmin + -p "{{ pass_kubeadmin }}" + https://api.crc.testing:6443 + register: _openshift_login + until: _openshift_login.rc != 1 + retries: 60 + delay: 10 + changed_when: false diff --git a/ansible/roles/deploy-crc-cloud/tasks/main.yaml b/ansible/roles/deploy-crc-cloud/tasks/main.yaml new file mode 100644 index 00000000..6b74cb49 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/main.yaml @@ -0,0 +1,69 @@ +--- +- name: Check if pull-secret is provided + when: not openshift_pull_secret + ansible.builtin.fail: + msg: "You need to provide openshift_pull_secret variable!" + +- name: Create kubeconfig + ansible.builtin.include_tasks: kubeconfig.yaml + +- name: Setup dnsmasq + ansible.builtin.include_tasks: dnsmasq.yaml + +- name: Start kubelet + ansible.builtin.include_tasks: kubelet.yaml + +- name: Replace default pubkey + ansible.builtin.include_tasks: pubkey.yaml + +- name: Wait for cluster become healthy + vars: + wait_components: "etcd|openshift-apiserver" + ansible.builtin.include_tasks: wait_cluster_become_healthy.yaml + +- name: Set credentials + ansible.builtin.include_tasks: set_credentials.yaml + +- name: Replace default CA + ansible.builtin.include_tasks: replace_default_ca.yaml + +- name: Login to the OpenShift cluster + ansible.builtin.include_tasks: login.yaml + +- name: Patch pull secret + ansible.builtin.include_tasks: patch_pull_secret.yaml + +- name: Wait for cluster become healthy after patching CA and pull secret + vars: + wait_components: "etcd|openshift-apiserver" + ansible.builtin.include_tasks: wait_cluster_become_healthy.yaml + +- name: Create certificate and patch secret + when: alternative_domain + ansible.builtin.include_tasks: create_certificate_and_patch_secret.yaml + +- name: Wait for cluster become healthy after adding domain + vars: + wait_components: "etcd|openshift-apiserver" + ansible.builtin.include_tasks: wait_cluster_become_healthy.yaml + +- name: Patch ingress config + when: alternative_domain + ansible.builtin.include_tasks: patch_ingress_config.yaml + +- name: Patch api server + when: alternative_domain + ansible.builtin.include_tasks: patch_api_server.yaml + +- name: Patch default route + when: alternative_domain + ansible.builtin.include_tasks: patch_default_route.yaml + +- name: Wait for cluster become healthy after changing ingress api server and default route + vars: + wait_components: "authentication|console|etcd|ingress|openshift-apiserver" + ansible.builtin.include_tasks: wait_cluster_become_healthy.yaml + +- name: Get console route + when: alternative_domain + ansible.builtin.include_tasks: console_route.yaml diff --git a/ansible/roles/deploy-crc-cloud/tasks/patch_api_server.yaml b/ansible/roles/deploy-crc-cloud/tasks/patch_api_server.yaml new file mode 100644 index 00000000..bfbe33f1 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/patch_api_server.yaml @@ -0,0 +1,7 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L215 +- name: Patch apiserver + ansible.builtin.shell: > + oc patch apiserver cluster + --type merge + --patch '{"spec":{"servingCerts": {"namedCertificates":[{"names":["api.{{ eip }}.{{ alternative_domain }}"],"servingCertificate": {"name": "nip-secret"}}]}}}' diff --git a/ansible/roles/deploy-crc-cloud/tasks/patch_default_route.yaml b/ansible/roles/deploy-crc-cloud/tasks/patch_default_route.yaml new file mode 100644 index 00000000..688129e2 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/patch_default_route.yaml @@ -0,0 +1,9 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L222 +- name: Patch default route + ansible.builtin.shell: > + oc patch + -p '{"spec": {"host": "default-route-openshift-image-registry.{{ eip }}.{{ alternative_domain }}"}}' + route default-route + -n openshift-image-registry + --type=merge diff --git a/ansible/roles/deploy-crc-cloud/tasks/patch_ingress_config.yaml b/ansible/roles/deploy-crc-cloud/tasks/patch_ingress_config.yaml new file mode 100644 index 00000000..f7b0f0e7 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/patch_ingress_config.yaml @@ -0,0 +1,26 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L185 +- name: Generate ingress patch + ansible.builtin.copy: + content: | + spec: + appsDomain: apps.{{ eip }}.{{ alternative_domain }} + componentRoutes: + - hostname: console-openshift-console.apps.{{ eip }}.{{ alternative_domain }} + name: console + namespace: openshift-console + servingCertKeyPairSecret: + name: nip-secret + - hostname: oauth-openshift.apps.{{ eip }}.{{ alternative_domain }} + name: oauth-openshift + namespace: openshift-authentication + servingCertKeyPairSecret: + name: nip-secret + dest: ingress-patch.yaml + +- name: Apply patch for ingress + ansible.builtin.command: > + oc patch ingresses.config.openshift.io + cluster + --type=merge + --patch-file=ingress-patch.yaml diff --git a/ansible/roles/deploy-crc-cloud/tasks/patch_pull_secret.yaml b/ansible/roles/deploy-crc-cloud/tasks/patch_pull_secret.yaml new file mode 100644 index 00000000..cf379680 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/patch_pull_secret.yaml @@ -0,0 +1,11 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L178 +- name: Patch pull secret + ansible.builtin.shell: > + oc -n openshift-config + patch secret pull-secret + --type merge + --patch '{"data":{".dockerconfigjson": "{{ openshift_pull_secret | replace("'", '"') | b64encode }}" }}' + when: openshift_pull_secret | length > 0 + changed_when: false + no_log: true diff --git a/ansible/roles/deploy-crc-cloud/tasks/pubkey.yaml b/ansible/roles/deploy-crc-cloud/tasks/pubkey.yaml new file mode 100644 index 00000000..f4c91267 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/pubkey.yaml @@ -0,0 +1,25 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L93 +- name: Check if id_rsa.pub exists + ansible.builtin.stat: + path: id_rsa.pub + register: _id_rsa_pub + +- name: Add master ssh key when pub key exists + when: _id_rsa_pub.stat.exists + block: + - name: Read pub key + ansible.builtin.shell: | + tr -d '\n\r' < id_rsa.pub + register: _pub_key + + - name: Wait for machineconfig + vars: + resource: machineconfig + ansible.builtin.include_tasks: wait_for_resource.yaml + + - name: Patch machineconfig 99-master-ssh + ansible.builtin.shell: > + oc patch machineconfig 99-master-ssh + -p '{"spec": {"config": {"passwd": {"users": [{"name": "core", "sshAuthorizedKeys": ["{{_pub_key.stdout}}"]}]}}}}' + --type merge diff --git a/ansible/roles/deploy-crc-cloud/tasks/replace_default_ca.yaml b/ansible/roles/deploy-crc-cloud/tasks/replace_default_ca.yaml new file mode 100644 index 00000000..cb0ef5ca --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/replace_default_ca.yaml @@ -0,0 +1,52 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L41 +- name: Generate key + ansible.builtin.command: openssl genrsa -out {{ ca_name }}-ca.key 4096 + +- name: Generate cert + ansible.builtin.command: > + openssl req -x509 -new -nodes + -key {{ ca_name }}-ca.key + -sha256 + -days {{ ca_validity }} + -out {{ ca_name }}-ca.crt + -subj "{{ ca_subj }}" + +- name: Generate csr + ansible.builtin.command: > + openssl req -nodes + -newkey rsa:2048 + -keyout {{ ca_user }}.key + -subj "{{ ca_user_subj }}" + -out {{ ca_user }}.csr + +- name: Generate user cert + ansible.builtin.shell: > + openssl x509 + -extfile <(printf "extendedKeyUsage = clientAuth") + -req -in {{ ca_user }}.csr + -CA {{ ca_name }}-ca.crt + -CAkey {{ ca_name }}-ca.key + -CAcreateserial -out {{ ca_user }}.crt + -days {{ ca_validity }} + -sha256 + +- name: Create configmap + ansible.builtin.command: > + oc create configmap + client-ca-custom + -n openshift-config + --from-file=ca-bundle.crt={{ ca_name }}-ca.crt + +- name: Patch apiserver + ansible.builtin.command: > + oc patch apiserver cluster + --type=merge + -p '{"spec": {"clientCA": {"name": "client-ca-custom"}}}' + +- name: Create configmap + ansible.builtin.shell: > + oc create configmap admin-kubeconfig-client-ca + -n openshift-config + --from-file=ca-bundle.crt={{ ca_name }}-ca.crt + --dry-run -o yaml | oc replace -f - diff --git a/ansible/roles/deploy-crc-cloud/tasks/set_credentials.yaml b/ansible/roles/deploy-crc-cloud/tasks/set_credentials.yaml new file mode 100644 index 00000000..cc71f267 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/set_credentials.yaml @@ -0,0 +1,22 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L229 +- name: Get htpasswd + ansible.builtin.include_tasks: get_htpasswd.yaml + loop: "{{ users }}" + loop_control: + loop_var: user + +- name: Cleanup htpasswd.txt file + ansible.builtin.shell: | + sed -i '/^\s*$/d' htpasswd.txt + +- name: Create secret with generic htpass-secret + ansible.builtin.shell: > + oc create secret generic htpass-secret + --from-file=htpasswd=htpasswd.txt + -n openshift-config + --dry-run=client + -o yaml > /tmp/htpass-secret.yaml + +- name: Replace htpass-secret + ansible.builtin.command: oc replace -f /tmp/htpass-secret.yaml diff --git a/ansible/roles/deploy-crc-cloud/tasks/wait_cluster_become_healthy.yaml b/ansible/roles/deploy-crc-cloud/tasks/wait_cluster_become_healthy.yaml new file mode 100644 index 00000000..cd45ca20 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/wait_cluster_become_healthy.yaml @@ -0,0 +1,22 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L159 +- name: Wait for OpenShift cluster components to become healthy + block: + - name: "Check if specified OpenShift components are healthy {{ wait_components }}" + ansible.builtin.shell: | + oc get co | grep -E '{{ wait_components }}' | awk '{ print $3 }' + register: component_status + retries: "{{ max_retries }}" + delay: "{{ retry_delay }}" + until: "'False' not in component_status.stdout_lines" + failed_when: "'False' in component_status.stdout_lines and retry_count >= max_retries" + ignore_errors: true + + - name: Output success message if components are healthy + ansible.builtin.debug: + msg: "OpenShift cluster components have become healthy in approximately {{ max_retries }} * {{ retry_delay }} seconds." + + - name: Fail if any components are still unhealthy + when: "'False' in component_status.stdout_lines" + ansible.builtin.fail: + msg: "OpenShift cluster components failed to become healthy after {{ max_retries }} checks." diff --git a/ansible/roles/deploy-crc-cloud/tasks/wait_for_resource.yaml b/ansible/roles/deploy-crc-cloud/tasks/wait_for_resource.yaml new file mode 100644 index 00000000..86338915 --- /dev/null +++ b/ansible/roles/deploy-crc-cloud/tasks/wait_for_resource.yaml @@ -0,0 +1,17 @@ +--- +# https://github.com/crc-org/crc-cloud/blob/main/pkg/bundle/setup/clustersetup.sh#L79 +- name: Wait for OpenShift resource to become available + block: + - name: Check for resource availability + ansible.builtin.command: "oc get {{ resource }}" + register: result + ignore_errors: true + retries: "{{ max_retry }}" + delay: "{{ wait_interval }}" + until: result.rc == 0 + failed_when: result.rc != 0 and retry_count >= max_retry + + - name: Fail if resource {{ resource }} unavailable + ansible.builtin.fail: + msg: "Impossible to get resource {{ resource }}" + when: result.rc != 0