From 1a1440f7518482f2ec41a896ddd9763a8e1c8739 Mon Sep 17 00:00:00 2001 From: Danny Bessems Date: Tue, 22 Aug 2023 12:02:13 +0200 Subject: [PATCH] build: Rebase pinniped to bitnami helm chart --- .../roles/assets/tasks/containerimages.yml | 13 +- ansible/roles/assets/tasks/main.yml | 1 - ansible/roles/assets/tasks/manifests.yml | 26 +-- .../metacluster/tasks/authentication.yml | 158 ++++++++++++++---- .../roles/metacluster/tasks/certauthority.yml | 2 +- .../bootstrap/roles/metacluster/tasks/git.yml | 2 +- .../roles/metacluster/tasks/ingress.yml | 2 +- .../bootstrap/templates/federationdomain.j2 | 7 + .../bootstrap/templates/ingressroute.j2 | 2 +- .../bootstrap/templates/ingressroutetcp.j2 | 2 +- .../templates/oidcidentityprovider.j2 | 11 ++ .../bootstrap/templates/secret.j2 | 3 + .../bootstrap/templates/serverstransport.j2 | 7 + ansible/vars/metacluster.yml | 49 +++++- ansible/vars/workloadcluster.yml | 11 ++ 15 files changed, 216 insertions(+), 80 deletions(-) create mode 100644 ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/federationdomain.j2 create mode 100644 ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/oidcidentityprovider.j2 create mode 100644 ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/serverstransport.j2 diff --git a/ansible/roles/assets/tasks/containerimages.yml b/ansible/roles/assets/tasks/containerimages.yml index 94ed164..8b23a1a 100644 --- a/ansible/roles/assets/tasks/containerimages.yml +++ b/ansible/roles/assets/tasks/containerimages.yml @@ -14,15 +14,6 @@ loop_control: label: "{{ item.dest | basename }}" -- name: Parse pinniped manifests for container images - ansible.builtin.shell: - # The pinniped manifest specify container images with *both* tag and digest; which is not supported by skopeo - cmd: cat {{ item.dest }} | yq --no-doc eval '.. | .image? | select(.) | sub("@.*", "")' | awk '!/ /' - register: pinniped_parsedmanifests - loop: "{{ pinniped_manifests.results }}" - loop_control: - label: "{{ item.dest | basename }}" - - name: Parse metacluster helm charts for container images ansible.builtin.shell: cmd: "{{ item.value.helm.parse_logic }}" @@ -52,8 +43,6 @@ results: "{{ kubeadmimages.stdout_lines }}" - source: clusterapi results: "{{ clusterapi_parsedmanifests | json_query('results[*].stdout_lines') | select() | flatten | list }}" - - source: pinniped - results: "{{ pinniped_parsedmanifests | json_query('results[*].stdout_lines') | select() | flatten | list }}" loop_control: label: "{{ item.source }}" @@ -75,4 +64,4 @@ docker://{{ item }} \ docker-archive:./{{ ( item | regex_findall('[^/:]+'))[-2] }}_{{ lookup('ansible.builtin.password', '/dev/null length=5 chars=ascii_lowercase,digits seed={{ item }}') }}.tar:{{ item }} chdir: /opt/metacluster/container-images - loop: "{{ (containerimages_charts + containerimages_kubeadm + containerimages_clusterapi + containerimages_pinniped + dependencies.container_images) | flatten | unique | sort }}" + loop: "{{ (containerimages_charts + containerimages_kubeadm + containerimages_clusterapi + dependencies.container_images) | flatten | unique | sort }}" diff --git a/ansible/roles/assets/tasks/main.yml b/ansible/roles/assets/tasks/main.yml index cbcefeb..ad8bc81 100644 --- a/ansible/roles/assets/tasks/main.yml +++ b/ansible/roles/assets/tasks/main.yml @@ -16,7 +16,6 @@ - /opt/metacluster/helm-charts - /opt/metacluster/k3s - /opt/metacluster/kube-vip - - /opt/metacluster/pinniped - /opt/workloadcluster/git-repositories/gitops/charts - /opt/workloadcluster/git-repositories/gitops/values - /opt/workloadcluster/helm-charts diff --git a/ansible/roles/assets/tasks/manifests.yml b/ansible/roles/assets/tasks/manifests.yml index 910bfea..2ac593c 100644 --- a/ansible/roles/assets/tasks/manifests.yml +++ b/ansible/roles/assets/tasks/manifests.yml @@ -16,8 +16,7 @@ { 'components': ( metacluster_chartvalues | combine({ 'clusterapi': components.clusterapi }) | - combine({ 'kubevip' : components.kubevip }) | - combine({ 'pinniped' : components.pinniped }) ), + combine({ 'kubevip' : components.kubevip }) ), 'appliance': { 'version': (applianceversion) } @@ -100,29 +99,6 @@ delay: 5 until: kubevip_manifest is not failed -- name: Download pinniped manifests - ansible.builtin.get_url: - url: "{{ item.url }}" - dest: /opt/metacluster/pinniped/{{ item.dest }} - register: pinniped_manifests - loop: - # The 'supervisor' runs in the metacluster and handles authentication - - url: https://github.com/vmware-tanzu/pinniped/releases/download/{{ components.pinniped.version }}/install-pinniped-supervisor.yaml - dest: pinniped-supervisor.yaml - # The 'local-user-authenticator' can be used to run a simple OIDC provider based on useraccounts defined in secrets. - - url: https://github.com/vmware-tanzu/pinniped/releases/download/{{ components.pinniped.version }}/install-local-user-authenticator.yaml - dest: local-user-authenticator.yaml - # The 'concierge' runs in downstream clusters and forwards authentication requests - - url: https://github.com/vmware-tanzu/pinniped/releases/download/{{ components.pinniped.version }}/install-pinniped-concierge-crds.yaml - dest: pinniped-concierge-crds.yaml - - url: https://github.com/vmware-tanzu/pinniped/releases/download/{{ components.pinniped.version }}/install-pinniped-concierge-resources.yaml - dest: pinniped-concierge-resources.yaml - loop_control: - label: "{{ item.dest }}" - retries: 5 - delay: 5 - until: pinniped_manifests is not failed - # - name: Inject manifests # ansible.builtin.template: # src: "{{ item.type }}.j2" diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/authentication.yml b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/authentication.yml index af766ae..76a6cd0 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/authentication.yml +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/authentication.yml @@ -1,37 +1,125 @@ -- name: Trim container image digests - ansible.builtin.lineinfile: - path: "{{ item }}" - regexp: "([ ]+image: (.*))@sha256:.*" - line: "\\1" - state: present - backrefs: yes - loop: "{{ query('ansible.builtin.fileglob', '/opt/metacluster/pinniped/*.yaml') }}" +- block: + - name: Install dex + kubernetes.core.helm: + name: dex + chart_ref: /opt/metacluster/helm-charts/dex + release_namespace: dex + create_namespace: true + wait: false + kubeconfig: "{{ kubeconfig.path }}" + values: "{{ components['dex'].chart_values }}" -- name: Install supervisor - kubernetes.core.k8s: - src: /opt/metacluster/pinniped/pinniped-supervisor.yaml - state: present - wait: yes - kubeconfig: "{{ kubeconfig.path }}" +- block: -- name: Add ingress for supervisor - kubernetes.core.k8s: - template: "ingressroute.j2" - state: present - kubeconfig: "{{ kubeconfig.path }}" - vars: - _template: - name: pinniped-supervisor-api - namespace: pinniped-supervisor - config: |2 - entryPoints: - - web - - websecure - routes: - - kind: Rule - match: Host(`auth.{{ vapp['metacluster.fqdn'] }}`) - services: - - kind: Service - name: pinniped-supervisor-api - namespace: pinniped-supervisor - port: 443 + - name: Install pinniped chart + kubernetes.core.helm: + name: pinniped + chart_ref: /opt/metacluster/helm-charts/pinniped + release_namespace: pinniped + create_namespace: true + wait: false + kubeconfig: "{{ kubeconfig.path }}" + values: "{{ components['pinniped'].chart_values }}" + + - name: Add ingress for supervisor + kubernetes.core.k8s: + template: "{{ item.kind }}.j2" + state: present + kubeconfig: "{{ kubeconfig.path }}" + vars: + _template: + name: "{{ item.name }}" + namespace: "{{ item.namespace }}" + config: "{{ item.config }}" + loop: + - kind: ingressroute + name: pinniped-supervisor + namespace: pinniped-supervisor + spec: |2 + entryPoints: + - web + - websecure + routes: + - kind: Rule + match: Host(`auth.{{ vapp['metacluster.fqdn'] }}`) + services: + - kind: Service + name: pinniped-supervisor + namespace: pinniped-supervisor + port: 443 + scheme: https + serversTransport: pinniped-supervisor + - kind: serverstransport + name: pinniped-supervisor + namespace: pinniped-supervisor + spec: |2 + insecureSkipVerify: true + serverName: auth.{{ vapp['metacluster.fqdn'] }} + + - name: Ensure pinniped API availability + ansible.builtin.uri: + url: https://auth.{{ vapp['metacluster.fqdn'] }}/healthz + method: GET + register: api_readycheck + until: + - api_readycheck.status == 200 + - api_readycheck.msg is search("OK") + retries: "{{ playbook.retries }}" + delay: "{{ ((storage_benchmark | float) * playbook.delay.short) | int }}" + + # TODO: Migrate to step-ca + - name: Initialize tempfile + ansible.builtin.tempfile: + state: directory + register: certificate + + - name: Create private key (RSA, 4096 bits) + community.crypto.openssl_privatekey: + path: "{{ certificate.path }}/certificate.key" + + - name: Create self-signed certificate + community.crypto.x509_certificate: + path: "{{ certificate.path }}/certificate.crt" + privatekey_path: "{{ certificate.path }}/certificate.key" + provider: selfsigned + + - name: Store self-signed certificate for use by pinniped supervisor + kubernetes.core.k8s: + template: secret.j2 + state: present + kubeconfig: "{{ kubeconfig.path }}" + vars: + _template: + name: pinniped-supervisor-tls + namespace: pinniped-supervisor + type: kubernetes.io/tls + data: + - tls.crt: "{{ lookup('ansible.builtin.file', certificate.path ~ '/certificate.crt') }}" + - tls.key: "{{ lookup('ansible.builtin.file', certificate.path ~ '/certificate.key') }}" + # TODO: Migrate to step-ca + + - name: Create pinniped resources + kubernetes.core.k8s: + template: "{{ item.kind }}.j2" + state: present + kubeconfig: "{{ kubeconfig.path }}" + vars: + _template: + name: "{{ item.name }}" + namespace: "{{ item.namespace }}" + config: "{{ item.config }}" + loop: + - kind: oidcidentityprovider + name: dex-staticpasswords + namespace: pinniped-supervisor + ca_bundle: + issuer: + + + - kind: federationdomain + name: metacluster-sso + namespace: pinniped-supervisor + spec: |2 + issuer: https://auth.{{ vapp['metacluster.fqdn'] }}/demo-issuer + tls: + secretName: pinniped-supervisor-tls diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/certauthority.yml b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/certauthority.yml index 9bfadf8..190404f 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/certauthority.yml +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/certauthority.yml @@ -82,7 +82,7 @@ _template: name: step-ca namespace: step-ca - config: |2 + spec: |2 entryPoints: - websecure routes: diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/git.yml b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/git.yml index 3da8e60..9960103 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/git.yml +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/git.yml @@ -32,7 +32,7 @@ _template: name: gitea-ssh namespace: gitea - config: |2 + spec: |2 entryPoints: - ssh routes: diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/ingress.yml b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/ingress.yml index c668e3a..c675c57 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/ingress.yml +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/roles/metacluster/tasks/ingress.yml @@ -27,7 +27,7 @@ _template: name: traefik-dashboard namespace: kube-system - config: |2 + spec: |2 entryPoints: - web - websecure diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/federationdomain.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/federationdomain.j2 new file mode 100644 index 0000000..fe7c43f --- /dev/null +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/federationdomain.j2 @@ -0,0 +1,7 @@ +apiVersion: config.supervisor.pinniped.dev/v1alpha1 +kind: FederationDomain +metadata: + name: {{ _template.name }} + namespace: {{ _template.namespace }} +spec: +{{ _template.spec }} diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroute.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroute.j2 index 0716b65..ca8f99e 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroute.j2 +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroute.j2 @@ -4,4 +4,4 @@ metadata: name: {{ _template.name }} namespace: {{ _template.namespace }} spec: -{{ _template.config }} +{{ _template.spec }} diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroutetcp.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroutetcp.j2 index d041f1f..0636003 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroutetcp.j2 +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/ingressroutetcp.j2 @@ -4,4 +4,4 @@ metadata: name: {{ _template.name }} namespace: {{ _template.namespace }} spec: -{{ _template.config }} +{{ _template.spec }} diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/oidcidentityprovider.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/oidcidentityprovider.j2 new file mode 100644 index 0000000..f03f4d7 --- /dev/null +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/oidcidentityprovider.j2 @@ -0,0 +1,11 @@ +apiVersion: idp.supervisor.pinniped.dev/v1alpha1 +kind: OIDCIdentityProvider +metadata: + name: {{ _template.name }} + namespace: {{ _template.namespace }} +spec: + issuer: {{ _template.issuer }} + tls: + certificateAuthorityData: {{ template.ca_bundle }} + client: + secretName: {{ _template.client_secret }} diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/secret.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/secret.j2 index 9537088..98eb72d 100644 --- a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/secret.j2 +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/secret.j2 @@ -3,6 +3,9 @@ kind: Secret metadata: name: {{ _template.name }} namespace: {{ _template.namespace }} +{% if _template.type is defined %} +type: {{ _template.type }} +{% endif %} data: {% for kv_pair in _template.data %} "{{ kv_pair.key }}": {{ kv_pair.value }} diff --git a/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/serverstransport.j2 b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/serverstransport.j2 new file mode 100644 index 0000000..dd15a9f --- /dev/null +++ b/ansible/roles/firstboot/files/ansible_payload/bootstrap/templates/serverstransport.j2 @@ -0,0 +1,7 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: ServersTransport +metadata: + name: {{ _template.name }} + namespace: {{ _template.namespace }} +spec: +{{ _template.spec }} diff --git a/ansible/vars/metacluster.yml b/ansible/vars/metacluster.yml index 2729a71..1aa183e 100644 --- a/ansible/vars/metacluster.yml +++ b/ansible/vars/metacluster.yml @@ -33,6 +33,10 @@ platform: helm_repositories: - name: argo url: https://argoproj.github.io/argo-helm + - name: bitnami + url: https://charts.bitnami.com/bitnami + - name: dexidp + url: https://charts.dexidp.io - name: gitea-charts url: https://dl.gitea.io/charts/ - name: harbor @@ -93,6 +97,38 @@ components: node_template: url: https://{{ repo_username }}:{{ repo_password }}@sn.itch.fyi/Repository/rel/ubuntu-2204-kube-v1.27.1.ova + dex: + helm: + version: 0.15.3 # (= Dex 2.37.0) + chart: dexidp/dex + parse_logic: helm template . | yq --no-doc eval '.. | .image? | select(.)' | sort -u | awk '!/ /' + chart_values: !unsafe | + config: + issuer: https://idps.{{ vapp['metacluster.fqdn'] }} + storage: + type: kubernetes + config: + inCluster: true + staticClients: + - id: pinniped-supervisor + secret: pinniped-supervisor-secret + name: Pinniped Supervisor client + redirectURIs: + - https://auth.{{ vapp['metacluster.fqdn'] }}/callback + enablePasswordDB: true + staticPasswords: + - email: admin@{{ vapp['metacluster.fqdn'] }} + hash: {{ vapp['metacluster.password'] | password_hash('bcrypt') }} + username: admin + userID: {{ lookup('ansible.builtin.password', '/dev/null length=64 chars=ascii_lowercase,digits seed=' ~ vapp['metacluster.fqdn']) | to_uuid }} + ingress: + enabled: true + hosts: + - host: idps.{{ vapp['metacluster.fqdn'] }} + paths: + - path: / + pathType: Prefix + gitea: helm: version: v7.0.2 # (= Gitea v1.18.3) @@ -198,8 +234,17 @@ components: defaultClassReplicaCount: 1 pinniped: - # Must match the version referenced at `dependencies.static_binaries[.filename==pinniped].url` - version: v0.25.0 + helm: + version: 1.2.11 # (= Pinniped v0.25.0) + chart: bitnami/pinniped + parse_logic: helm template . | yq --no-doc eval '.. | .image? | select(.)' | sort -u | awk '!/ /' + chart_values: !unsafe | + concierge: + enabled: false + supervisor: + service: + public: + type: ClusterIP step-certificates: helm: diff --git a/ansible/vars/workloadcluster.yml b/ansible/vars/workloadcluster.yml index c4b15d6..b4d0b1e 100644 --- a/ansible/vars/workloadcluster.yml +++ b/ansible/vars/workloadcluster.yml @@ -1,6 +1,8 @@ downstream: helm_repositories: + - name: bitnami + url: https://charts.bitnami.com/bitnami - name: longhorn url: https://charts.longhorn.io - name: sealed-secrets @@ -18,6 +20,15 @@ downstream: createDefaultDiskLabeledNodes: true defaultDataPath: /mnt/blockstorage + pinniped: + helm: + version: 1.2.11 # (= Pinniped v0.25.0) + chart: bitnami/pinniped + parse_logic: helm template . | yq --no-doc eval '.. | .image? | select(.)' | sort -u | awk '!/ /' + chart_values: !unsafe | + supervisor: + enabled: false + sealed-secrets: version: 2.8.1 # (= Sealed Secrets v0.20.2) chart: sealed-secrets/sealed-secrets