123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- ---
- # Tasks required by 10-quay-deploy.adoc.
- - name: Issue a new Cert for Quay if necessary.
- hosts: workstation.lab.example.com
- gather_subset: min
- tasks:
- - name: Check if Quay key exists to save time
- ansible.builtin.stat:
- path: "{{ ansible_facts['user_dir'] }}/ca/quay-key.pem"
- get_attributes: no
- get_checksum: no
- get_mime: no
- register: qkey_file
- - name: Check if Quay cert exists to save time
- ansible.builtin.stat:
- path: "{{ ansible_facts['user_dir'] }}/ca/quay-cert.pem"
- get_attributes: no
- get_checksum: no
- get_mime: no
- register: qcert_file
- - name: Create a new private key for Quay, if it does not exist yet.
- community.crypto.openssl_privatekey:
- path: "{{ ansible_facts['user_dir'] }}/ca/quay-key.pem"
- type: RSA
- size: 4096
- mode: 0600
- when: qkey_file.stat.exists == false
- - name: Create a CSR for Quay
- community.crypto.openssl_csr:
- path: "{{ ansible_facts['user_dir'] }}/ca/quay-csr.pem"
- privatekey_path: "{{ ansible_facts['user_dir'] }}/ca/quay-key.pem"
- subject:
- C: US
- ST: North Carolina
- L: Raleigh
- O: Red Hat
- OU: RHT
- CN: registry.ocp4.example.com
- use_common_name_for_san: yes
- mode: 0600
- when: qcert_file.stat.exists == false
- - name: Issue a certificate for Quay if one isn't there yet.
- ansible.builtin.command:
- cmd: openssl ca -config {{ ansible_facts['user_dir'] }}/ca/openssl.cnf -passin pass:verysecret -in {{ ansible_facts['user_dir'] }}/ca/quay-csr.pem -out {{ ansible_facts['user_dir'] }}/ca/quay-cert.pem -batch -notext
- creates: "{{ ansible_facts['user_dir'] }}/ca/quay-cert.pem"
- - name: Load CA cert and Quay cert.
- ansible.builtin.set_fact:
- ca_cert: "{{ lookup('file', ansible_facts['user_dir'] + '/ca/ca-cert.pem') }}"
- quay_cert: "{{ lookup('file', ansible_facts['user_dir'] + '/ca/lab-ca/newcerts/00.pem') }}"
- - name: Concatenate Quay and CA certs.
- ansible.builtin.copy:
- dest: "{{ ansible_facts['user_dir'] }}/ca/quay-cert.pem"
- content: |
- {{ quay_cert }}
- {{ ca_cert }}
- - name: Ensure registry VM has a data directory for Quay.
- hosts: registry.ocp4.example.com
- become: yes
- gather_subset: min
- tasks:
- - name: Ensure data directory is there.
- ansible.builtin.file:
- path: /local/quay
- mode: 0770
- owner: quay
- group: quay
- state: directory
- - name: Configure containers and their environment on registry VM.
- hosts: registry.ocp4.example.com
- gather_subset: min
- remote_user: quay
- tasks:
- - name: Pull all the images if necessary.
- containers.podman.podman_image:
- name: "{{ registry_host }}/quay/quay-rhel8:v{{ quay_version }}"
- pull: yes
- state: present
- - name: Create Quay config directory if necessary.
- ansible.builtin.file:
- path: "{{ ansible_facts['user_dir'] }}/config"
- state: directory
- mode: 0770
- - name: Publish Quay key on registry.
- ansible.builtin.copy:
- src: /home/student/ca/quay-key.pem
- dest: "{{ ansible_facts['user_dir'] }}/config/ssl.key"
- mode: 0440
- - name: Publish Quay cert on registry.
- ansible.builtin.copy:
- src: /home/student/ca/quay-cert.pem
- dest: "{{ ansible_facts['user_dir'] }}/config/ssl.cert"
- mode: 0440
- - name: Publish Quay config file.
- ansible.builtin.copy:
- dest: "{{ ansible_facts['user_dir'] }}/config/config.yaml"
- content: |
- BUILDLOGS_REDIS:
- host: redis
- password: verysecret
- port: 6379
- CREATE_NAMESPACE_ON_PUSH: true
- DATABASE_SECRET_KEY: 410c87de-8ad8-4f4c-9670-2ec25bc87191
- DB_URI: postgresql://quay:secret@postgresql:5432/quay
- DISTRIBUTED_STORAGE_CONFIG:
- default:
- - LocalStorage
- - storage_path: /registry
- DISTRIBUTED_STORAGE_DEFAULT_LOCATIONS: []
- DISTRIBUTED_STORAGE_PREFERENCE:
- - default
- FEATURE_MAILING: false
- SECRET_KEY: 7ce58d4d-b6f5-4400-ba6b-77b9f728a115
- SERVER_HOSTNAME: registry.ocp4.example.com
- PREFERRED_URL_SCHEME: https
- SETUP_COMPLETE: true
- SUPER_USERS:
- - admin
- TESTING: false
- USER_EVENTS_REDIS:
- host: redis
- password: verysecret
- port: 6379
- mode: 0660
- # TODO: recursive!
- - name: Ensure Quay data dirs are owned by the correct user.
- become_method: containers.podman.podman_unshare
- become: yes
- ansible.builtin.file:
- path: "{{ item }}"
- state: directory
- owner: 1001
- loop:
- - /local/quay
- - "{{ ansible_facts['user_dir'] }}/config"
- - name: Ensure systemd user dir is there.
- ansible.builtin.file:
- path: "{{ ansible_facts['user_dir'] }}/.config/systemd/user"
- state: directory
- - name: Deploy service units.
- ansible.builtin.template:
- dest: "{{ ansible_facts['user_dir'] }}/.config/systemd/user/quay.service"
- src: "templates/quay.service.j2"
- - name: Reload systemd.
- ansible.builtin.systemd_service:
- daemon_reload: yes
- scope: user
- - name: Enable services and start them.
- ansible.builtin.systemd_service:
- name: quay
- scope: user
- state: started
- enabled: yes
- register: startup
- - name: Wait a bit if the Quay container was just started.
- ansible.builtin.uri:
- method: GET
- url: https://registry.ocp4.example.com/
- headers:
- Accept: application/json
- Content-Type: application/json
- validate_certs: no
- status_code:
- - 200
- - 404
- - 502
- when: startup.changed
- register: startup_wait
- until: startup_wait.status == 200
- retries: 30
- delay: 5
- - name: Check if the admin user exists already.
- ansible.builtin.uri:
- method: GET
- url: https://registry.ocp4.example.com/api/v1/users/admin
- headers:
- Accept: application/json
- Content-Type: application/json
- validate_certs: no
- status_code:
- - 200
- - 404
- return_content: yes
- register: adminuser_is_there
- - name: Create an admin user if not yet there.
- block:
- - name: Obtain an encoded CSRF token.
- ansible.builtin.uri:
- method: GET
- url: https://registry.ocp4.example.com/
- headers:
- Accept: application/json
- Content-Type: application/json
- validate_certs: no
- return_content: yes
- ignore_errors: yes
- register: csrf_token_payload
- - ansible.builtin.assert:
- that:
- - csrf_token_payload.cookies['_csrf_token'] is defined
- fail_msg: "No CSRF token returned by registry. Can not proceed."
- success_msg: "Good, CSRF token found in response."
- # In case of issues, run with -v and this will show the raw cookie.
- - ansible.builtin.debug:
- var: csrf_token_payload.cookies
- verbosity: 1
- - name: Store the cookie as a new fact. We need it later.
- ansible.builtin.set_fact:
- csrf_cookie: "{{ csrf_token_payload.cookies['_csrf_token'] }}"
- # In case of issues, run with -v and this will show the cookie payload.
- - ansible.builtin.debug:
- var: csrf_cookie
- verbosity: 1
- # Must chop out the part of the token before the first dot (the rest is control shit).
- # Next, and pad it (==) at the end to have 112 characters (no checking done here).
- # Lastly, convert that from JSON to a dict and obtain the value of the token (_csrf_token).
- - name: Store CSRF token as a new fact.
- ansible.builtin.set_fact:
- csrf_token: "{{ (csrf_token_payload.cookies['_csrf_token'] | ansible.builtin.regex_replace('^(\\w+)\\..*$', '\\1==') | ansible.builtin.b64decode | ansible.builtin.from_json)['_csrf_token'] }}"
- # In case of issues, run with -v and this will show the decoded token.
- - ansible.builtin.debug:
- var: csrf_token
- verbosity: 1
- - name: Send a POST request to registry API to create the admin user.
- ansible.builtin.uri:
- method: POST
- url: https://registry.ocp4.example.com/api/v1/user/
- headers:
- Accept: application/json
- Content-Type: application/json
- Cookie: _csrf_token={{ csrf_cookie }}
- X-CSRF-Token: "{{ csrf_token }}"
- body: |
- {
- "username": "admin",
- "password": "redhat123",
- "repeatPassword": "redhat123",
- "email": "admin@example.com"
- }
- body_format: json
- validate_certs: no
- return_content: yes
- register: admin_user_response
- # In case of issues, run with -v and this will show the response.
- - ansible.builtin.debug:
- var: admin_user_response
- verbosity: 1
- when: adminuser_is_there.status == 404
- ...
|