From d86babdfe97403b73dba4e54f7244618e7fee9d7 Mon Sep 17 00:00:00 2001 From: Francois Andrieu Date: Sun, 25 Jun 2023 18:17:16 +0200 Subject: [PATCH] AWX: Initial configuration --- playbooks/include/proxies-reverseproxy.yml | 12 + playbooks/include/proxies-websites.yml | 7 +- playbooks/openshift-apps/awx.yml | 20 ++ roles/awx/controller/meta/main.yml | 3 + .../tasks/execution_environment.yml | 6 + .../awx/controller/tasks/execution_nodes.yml | 11 + roles/awx/controller/tasks/main.yml | 6 + roles/awx/controller/tasks/org.yml | 5 + roles/awx/controller/tasks/projects.yml | 31 +++ roles/awx/controller/tasks/saml2.yml | 50 ++++ roles/awx/execution_node/tasks/main.yml | 57 +++++ roles/awx/podman/README.md | 32 +++ roles/awx/podman/defaults/main.yml | 8 + roles/awx/podman/tasks/main.yml | 48 ++++ roles/awx/podman/tasks/setup-RedHat.yml | 5 + roles/awx/podman/tasks/variables.yml | 10 + roles/awx/podman/vars/RedHat.yml | 4 + roles/awx/receptor/README.md | 219 ++++++++++++++++++ roles/awx/receptor/defaults/main.yml | 38 +++ roles/awx/receptor/tasks/configure.yml | 41 ++++ roles/awx/receptor/tasks/main.yml | 32 +++ roles/awx/receptor/tasks/setup-RedHat.yml | 10 + roles/awx/receptor/tasks/tls.yml | 27 +++ roles/awx/receptor/tasks/tls_local.yml | 61 +++++ roles/awx/receptor/tasks/variables.yml | 10 + roles/awx/receptor/tasks/worksign.yml | 3 + roles/awx/receptor/tasks/worksign_local.yml | 18 ++ .../awx/receptor/templates/pam_limits.conf.j2 | 3 + roles/awx/receptor/templates/receptor.conf.j2 | 83 +++++++ .../receptor/templates/receptor_tmpd.conf.j2 | 1 + .../systemd_receptor_override.conf.j2 | 7 + roles/awx/receptor/vars/RedHat.yml | 3 + roles/ipsilon/tasks/main.yml | 10 + roles/ipsilon/templates/saml2_data | 4 +- 34 files changed, 882 insertions(+), 3 deletions(-) create mode 100644 playbooks/openshift-apps/awx.yml create mode 100644 roles/awx/controller/meta/main.yml create mode 100644 roles/awx/controller/tasks/execution_environment.yml create mode 100644 roles/awx/controller/tasks/execution_nodes.yml create mode 100644 roles/awx/controller/tasks/main.yml create mode 100644 roles/awx/controller/tasks/org.yml create mode 100644 roles/awx/controller/tasks/projects.yml create mode 100644 roles/awx/controller/tasks/saml2.yml create mode 100644 roles/awx/execution_node/tasks/main.yml create mode 100644 roles/awx/podman/README.md create mode 100644 roles/awx/podman/defaults/main.yml create mode 100644 roles/awx/podman/tasks/main.yml create mode 100644 roles/awx/podman/tasks/setup-RedHat.yml create mode 100644 roles/awx/podman/tasks/variables.yml create mode 100644 roles/awx/podman/vars/RedHat.yml create mode 100644 roles/awx/receptor/README.md create mode 100644 roles/awx/receptor/defaults/main.yml create mode 100644 roles/awx/receptor/tasks/configure.yml create mode 100644 roles/awx/receptor/tasks/main.yml create mode 100644 roles/awx/receptor/tasks/setup-RedHat.yml create mode 100644 roles/awx/receptor/tasks/tls.yml create mode 100644 roles/awx/receptor/tasks/tls_local.yml create mode 100644 roles/awx/receptor/tasks/variables.yml create mode 100644 roles/awx/receptor/tasks/worksign.yml create mode 100644 roles/awx/receptor/tasks/worksign_local.yml create mode 100644 roles/awx/receptor/templates/pam_limits.conf.j2 create mode 100644 roles/awx/receptor/templates/receptor.conf.j2 create mode 100644 roles/awx/receptor/templates/receptor_tmpd.conf.j2 create mode 100644 roles/awx/receptor/templates/systemd_receptor_override.conf.j2 create mode 100644 roles/awx/receptor/vars/RedHat.yml diff --git a/playbooks/include/proxies-reverseproxy.yml b/playbooks/include/proxies-reverseproxy.yml index a2dc27f450..570b04af83 100644 --- a/playbooks/include/proxies-reverseproxy.yml +++ b/playbooks/include/proxies-reverseproxy.yml @@ -900,3 +900,15 @@ ocp4: true keephost: true tags: ipsilon-website + + - role: httpd/reverseproxy + website: awx.fedoraproject.org + destname: awx + balancer_name: app-ocp + balancer_members: "{{ ocp_nodes }}" + targettype: openshift + ocp4: true + keephost: true + tags: + - awx + when: env == "production" diff --git a/playbooks/include/proxies-websites.yml b/playbooks/include/proxies-websites.yml index e21b686d25..14f82f06af 100644 --- a/playbooks/include/proxies-websites.yml +++ b/playbooks/include/proxies-websites.yml @@ -580,7 +580,12 @@ tags: - coreos.fedoraproject.org - + - role: httpd/website + site_name: awx.fedoraproject.org + sslonly: true + cert_name: "{{wildcard_cert_name}}" + tags: + - awx # # Make a website here so we can redirect it to paste.fedoraproject.org # diff --git a/playbooks/openshift-apps/awx.yml b/playbooks/openshift-apps/awx.yml new file mode 100644 index 0000000000..949e2992a8 --- /dev/null +++ b/playbooks/openshift-apps/awx.yml @@ -0,0 +1,20 @@ +--- +- name: make the app be real + hosts: localhost + connection: local + user: root + gather_facts: False + + vars_files: + - /srv/web/infra/ansible/vars/global.yml + - "/srv/private/ansible/vars.yml" + - /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml + + module_defaults: + group/awx.awx.controller: + controller_host: awx.fedoraproject.org + controller_username: "{{ awx_admin_username }}" + controller_password: "{{ awx_admin_password }}" + + roles: + - role: awx/controller diff --git a/roles/awx/controller/meta/main.yml b/roles/awx/controller/meta/main.yml new file mode 100644 index 0000000000..0dfb8ab5c5 --- /dev/null +++ b/roles/awx/controller/meta/main.yml @@ -0,0 +1,3 @@ +--- +collections: +- awx.awx diff --git a/roles/awx/controller/tasks/execution_environment.yml b/roles/awx/controller/tasks/execution_environment.yml new file mode 100644 index 0000000000..cb0cabf160 --- /dev/null +++ b/roles/awx/controller/tasks/execution_environment.yml @@ -0,0 +1,6 @@ +--- +- name: Create Fedora Ansible Execution Environment + execution_environment: + name: Fedora ansible EE + image: registry.gitlab.com/darknao/fedora-ansible-ee:latest + pull: always diff --git a/roles/awx/controller/tasks/execution_nodes.yml b/roles/awx/controller/tasks/execution_nodes.yml new file mode 100644 index 0000000000..dda97f35e9 --- /dev/null +++ b/roles/awx/controller/tasks/execution_nodes.yml @@ -0,0 +1,11 @@ +--- +- name: Define batcave01 as execution node + instance: + hostname: batcave01.vpn.fedoraproject.org + node_type: execution + +- name: Create batcave instance group + instance_group: + name: batcave + instances: + - batcave01.vpn.fedoraproject.org diff --git a/roles/awx/controller/tasks/main.yml b/roles/awx/controller/tasks/main.yml new file mode 100644 index 0000000000..b1ddc62bc5 --- /dev/null +++ b/roles/awx/controller/tasks/main.yml @@ -0,0 +1,6 @@ +--- +- include_tasks: saml2.yml +- include_tasks: execution_environment.yml +- include_tasks: org.yml +- include_tasks: execution_nodes.yml +- include_tasks: projects.yml diff --git a/roles/awx/controller/tasks/org.yml b/roles/awx/controller/tasks/org.yml new file mode 100644 index 0000000000..1b52d0004c --- /dev/null +++ b/roles/awx/controller/tasks/org.yml @@ -0,0 +1,5 @@ +--- +- name: Create Fedora organization + organization: + name: Fedora + description: Fedora Project Org diff --git a/roles/awx/controller/tasks/projects.yml b/roles/awx/controller/tasks/projects.yml new file mode 100644 index 0000000000..eeac0ee456 --- /dev/null +++ b/roles/awx/controller/tasks/projects.yml @@ -0,0 +1,31 @@ +--- +- name: Create Fedora Infra project + project: + name: Fedora Infra + description: "" + scm_type: git + scm_url: https://pagure.io/fedora-infra/ansible.git + scm_clean: true + organization: Fedora + scm_update_on_launch: true + default_environment: Fedora ansible EE + +- name: Create Fedora Infra Inventory + inventory: + name: Fedora Infra + description: "" + organization: Fedora + +- name: Set up Fedora Infra Inventory source + inventory_source: + source_project: Fedora Infra + inventory: Fedora Infra + name: Fedora Infra Git + source: scm + source_path: inventory + update_on_launch: true + +- name: Trigger inventory update + inventory_source_update: + name: Fedora Infra Git + inventory: Fedora Infra diff --git a/roles/awx/controller/tasks/saml2.yml b/roles/awx/controller/tasks/saml2.yml new file mode 100644 index 0000000000..8c21c12a65 --- /dev/null +++ b/roles/awx/controller/tasks/saml2.yml @@ -0,0 +1,50 @@ +--- +- name: Configure SAML2 authentication + settings: + settings: + SAML_AUTO_CREATE_OBJECTS: true + SOCIAL_AUTH_SAML_SP_ENTITY_ID: https://awx.fedoraproject.org/ + SOCIAL_AUTH_SAML_SP_PUBLIC_CERT: + "{{ lookup('file', '{{ private }}/files/awx/{{ env }}/awx-saml.crt') }}" + SOCIAL_AUTH_SAML_SP_PRIVATE_KEY: + "{{ lookup('file', '{{ private }}/files/awx/{{ env }}/awx-saml.key') }}" + SOCIAL_AUTH_SAML_ORG_INFO: + en-US: + url: https://awx.fedoraproject.org/ + name: AWX + displayname: Ansible AWX + SOCIAL_AUTH_SAML_TECHNICAL_CONTACT: + emailAddress: infrastructure@lists.fedoraproject.org + givenName: Fedora Infrastructure + SOCIAL_AUTH_SAML_SUPPORT_CONTACT: + emailAddress: infrastructure@lists.fedoraproject.org + givenName: Fedora Infrastructure + SOCIAL_AUTH_SAML_ENABLED_IDPS: + fedora: + x509cert: + "{{ lookup( + 'file', + '{{ private }}/files/saml2/{{ env }}/keys/idp.crt' + ) + | regex_replace('\n', '') + }}" + attr_email: "email" + attr_first_name: "givenname" + attr_last_name: "surname" + attr_user_permanent_id: "name_id" + attr_username: "name_id" + entity_id: "https://id.fedoraproject.org/idp/saml2/metadata" + url: "https://id.fedoraproject.org/idp/saml2/SSO/Redirect" + SOCIAL_AUTH_SAML_SECURITY_CONFIG: + authnRequestsSigned: true + SOCIAL_AUTH_SAML_USER_FLAGS_BY_ATTR: + is_superuser_attr: groups + is_superuser_value: + - sysadmin-main + SOCIAL_AUTH_SAML_ORGANIZATION_MAP: {} + SOCIAL_AUTH_SAML_TEAM_ATTR: + saml_attr: groups + remove: true + team_org_map: + - organization: Fedora + team: fedora-websites diff --git a/roles/awx/execution_node/tasks/main.yml b/roles/awx/execution_node/tasks/main.yml new file mode 100644 index 0000000000..ac20636a61 --- /dev/null +++ b/roles/awx/execution_node/tasks/main.yml @@ -0,0 +1,57 @@ +--- +- name: Create the awx user + user: + name: awx + shell: /bin/bash + +- name: Enable Copr repo for Ansible Receptor (Fedora) + community.general.copr: + name: ansible-awx/receptor + when: ansible_distribution == 'Fedora' + +- name: Enable Copr repo for Ansible Receptor (RHEL) + community.general.copr: + name: ansible-awx/receptor + chroot: epel-9-x86_64 + when: + - ansible_distribution == 'RedHat' + - ansible_distribution_major_version|int == 9 + +- name: Deploy podman + include_role: + name: awx/podman + vars: + podman_user: awx + podman_group: awx + +- name: Deploy Ansible Receptor + include_role: + name: awx/receptor + vars: + receptor_user: awx + receptor_group: awx + receptor_verify: true + receptor_tls: true + receptor_mintls13: false + receptor_work_commands: + ansible-runner: + command: ansible-runner + params: worker + allowruntimeparams: true + verifysignature: true + custom_worksign_public_keyfile: + "{{ private }}/files/awx/{{ inventory_hostname }}/work-public-key.pem" + custom_tls_certfile: "{{ private }}/files/awx/{{ inventory_hostname }}/tls/receptor.crt" + custom_tls_keyfile: "{{ private }}/files/awx/{{ inventory_hostname }}/tls/receptor.key" + custom_ca_certfile: "{{ private }}/files/awx/{{ inventory_hostname }}/tls/ca/receptor-ca.crt" + receptor_protocol: 'tcp' + receptor_listener: true + receptor_port: 27199 + receptor_dependencies: + - python3-pip + ansible_host: "{{ inventory_hostname }}" + +- name: Install ansible-runner + pip: + name: ansible-runner + executable: pip3 diff --git a/roles/awx/podman/README.md b/roles/awx/podman/README.md new file mode 100644 index 0000000000..45a5431b5f --- /dev/null +++ b/roles/awx/podman/README.md @@ -0,0 +1,32 @@ +# Ansible Role: Podman + +Installs and configures Podman on RHEL/CentOS/Fedora servers. + +## Role Variables + +Available variables are listed below, along with default values. + +--- + + podman_user: 'podman' + podman_group: 'podman' + +The user and group under which podman will be configured. + +--- + + default_runtime: 'crun' + +The default container runtime to use for Podman. + +--- + + default_cgroup_manager: 'cgroupfs' + +The default cgroup manager to use for Podman. + +--- + +# License + +Apache 2 diff --git a/roles/awx/podman/defaults/main.yml b/roles/awx/podman/defaults/main.yml new file mode 100644 index 0000000000..f30cc00f42 --- /dev/null +++ b/roles/awx/podman/defaults/main.yml @@ -0,0 +1,8 @@ +--- +podman_user: 'podman' +podman_group: 'podman' + +default_runtime: 'crun' +default_cgroup_manager: 'cgroupfs' + +_hostname: "{{ routable_hostname | default(ansible_host) }}" diff --git a/roles/awx/podman/tasks/main.yml b/roles/awx/podman/tasks/main.yml new file mode 100644 index 0000000000..cd87f048a0 --- /dev/null +++ b/roles/awx/podman/tasks/main.yml @@ -0,0 +1,48 @@ +--- +# Variable configuration. +- include_tasks: variables.yml + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- name: Create directory for podman runtime config + ansible.builtin.file: + path: "~{{ podman_user }}/.config/containers" + state: directory + mode: 0700 + owner: "{{ podman_user }}" + group: "{{ podman_group }}" + +- name: Configure podman default runtime + ansible.builtin.copy: + content: | + [engine] + runtime = "{{ default_runtime }}" + cgroup_manager = "{{ default_cgroup_manager }}" + dest: "~{{ podman_user }}/.config/containers/containers.conf" + owner: "{{ podman_user }}" + group: "{{ podman_group }}" + mode: 0600 + +- name: Create empty mounts config file to avoid permissions error message + ansible.builtin.copy: + content: "" + dest: "~{{ podman_user }}/.config/containers/mounts.conf" + force: false + owner: "{{ podman_user }}" + group: "{{ podman_group }}" + mode: 0600 + +- name: Ensure registries.conf.d exists + ansible.builtin.file: + path: /etc/containers/registries.conf.d/ + state: directory + mode: 0755 + +- name: Force fully qualified image names to be provided to podman pull + ansible.builtin.copy: + content: | + unqualified-search-registries = [] + dest: /etc/containers/registries.conf.d/force-fully-qualified-images.conf + mode: 0644 diff --git a/roles/awx/podman/tasks/setup-RedHat.yml b/roles/awx/podman/tasks/setup-RedHat.yml new file mode 100644 index 0000000000..9f7691357c --- /dev/null +++ b/roles/awx/podman/tasks/setup-RedHat.yml @@ -0,0 +1,5 @@ +--- +- name: Install podman packages + ansible.builtin.dnf: + name: "{{ podman_packages }}" + state: present diff --git a/roles/awx/podman/tasks/variables.yml b/roles/awx/podman/tasks/variables.yml new file mode 100644 index 0000000000..2916ff078c --- /dev/null +++ b/roles/awx/podman/tasks/variables.yml @@ -0,0 +1,10 @@ +--- +- name: Include OS-specific variables (RedHat) + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" + when: + - ansible_os_family == 'RedHat' + +- name: Define podman_packages + ansible.builtin.set_fact: + podman_packages: "{{ __podman_packages | list }}" + when: podman_packages is not defined diff --git a/roles/awx/podman/vars/RedHat.yml b/roles/awx/podman/vars/RedHat.yml new file mode 100644 index 0000000000..9b95ffedc1 --- /dev/null +++ b/roles/awx/podman/vars/RedHat.yml @@ -0,0 +1,4 @@ +--- +__podman_packages: + - podman + - crun diff --git a/roles/awx/receptor/README.md b/roles/awx/receptor/README.md new file mode 100644 index 0000000000..466bfd697a --- /dev/null +++ b/roles/awx/receptor/README.md @@ -0,0 +1,219 @@ +# Ansible Role: Setup + +Installs and configures a Receptor node on RHEL/CentOS/Fedora servers. + + +## Role Variables + +Available variables are listed below, along with default values. + +--- + + receptor_packages: + - receptor + +Set the names of the packages needed to install Receptor. + +--- + + receptor_dependencies: [] + +Specify other packages needed, probably on a per-node-type basis using +groupvars or hostvars. + +--- + + receptor_user: 'receptor' + receptor_group: 'receptor' + +The user and group under which Receptor will run. + +--- + + receptor_socket_dir: '/var/run/receptor' + +The directory that Receptor will place its control socket into. + +--- + + receptor_control_filename: 'receptor.sock' + +The name of the control socket file. + +--- + + receptor_config_path: '/etc/receptor' + +Path to the Receptor config file. + +--- + + routable_hostname: # defaults to not set + +Hostvar for the routable address to this node. If this is unset +`ansible_host` will be used instead. Must be unique. + +--- + + receptor_peers: # defaults to not set + +Hostvar for the Ansible hosts that this node is peering outwards to. +This is expected to be a list of dicts. + +In the dicts, the `'host'` key is required, `'port'` and `'protocol'` +are optional and will default to the overall defaults for +`receptor_port` and `receptor_protocol`. + +--- + + receptor_tls: false + +Enables the TLS protocol to be used for communication between nodes. +If enabled, appropriate certificates will have to be provided or +generated. + +--- + + receptor_mintls13: false + +If set to true, this forces the minimum TLS version used to be 1.3. +Otherwise, the minimum version will be 1.2. This variable has no +effect unless `receptor_tls` is enabled. + +--- + + receptor_tls_dir: '/etc/receptor/tls' + receptor_tls_ca_dir: '{{ receptor_tls_dir }}/ca' + +Directories on the server where the TLS keys and CA keys would be located. + +--- + + receptor_tls_certfile: "{{ receptor_tls_dir }}/{{ receptor_host_identifier }}.crt" + receptor_tls_keyfile: "{{ receptor_tls_dir }}/{{ receptor_host_identifier }}.key" + +Path on the server to the public and private TLS key files. + +--- + + receptor_ca_certfile: "{{ receptor_tls_ca_dir }}/mesh-CA.crt" + receptor_ca_keyfile: "{{ receptor_tls_ca_dir }}/mesh-CA.key" + +Path on the server where the public and private Certificate Authority +key files would be located. + +--- + + custom_ca_certfile: # defaults to not set + custom_ca_keyfile: # defaults to not set + +Path on the local filesystem to user-provided Certificate Authority +files. + +--- + + custom_tls_certfile: # defaults to not set + custom_tls_keyfile: # defaults to not set + +Hostvar that is the path on the local filesystem to user-provided +per-node certificate files. If used, both must be provided in +combination with a `custom_ca_certfile` that was used to sign them. + +--- + + receptor_sign: false + +Hostvar designating that this host will sign any work that it sends +over the Receptor mesh. + +--- + + receptor_verify: false + +Hostvar designating that this host will verify any work that it +receives using a public key. + +--- + + receptor_worksign_key_dir: "/etc/receptor" + receptor_worksign_private_keyfile: "{{ receptor_worksign_key_dir }}/work_private_key.pem" + receptor_worksign_public_keyfile: "{{ receptor_worksign_key_dir }}/work_public_key.pem" + +Path on the server to the public and private OpenSSL work signing key files. + +--- + + custom_worksign_private_keyfile: # defaults to not set + custom_worksign_public_keyfile: # defaults to not set + +Path on the local filesystem to user-provided OpenSSL work signing key +files. + +--- + + receptor_fd_limit_soft: 4096 + receptor_fd_limit_hard: 8192 + +The file descriptor limits in PAM for Receptor. + +--- + + receptor_app_service: # defaults to not set + +Optional variable to tie Receptor together with some other service in systemd. + +--- + + receptor_log_level: 'info' + +The level at which Receptor should write logs. Allowable options are 'error', 'warning', 'info', and 'debug'. + +--- + + receptor_listener: true + +Hostvar to enable Receptor to listen for incoming remote connections. + +--- + + receptor_local_only: false + +Hostvar to make this instance of Receptor listen for local-only +connections. If set to true, this will take precedence over the value +of `receptor_listener`. + +--- + + receptor_protocol: 'tcp' + receptor_port: 27199 + +Override with hostvars for the protocol this instance of Receptor will +use (allowable options are 'tcp', 'udp', and 'ws' for websockets), and +the port number it will listen for those connections on. + +--- + + receptor_work_commands: # defaults to not set + +The definition of the Receptor work commands. This variable is +expected to be a dictionary, with keys the unique worktype name, and +values a dict of the rest of the key-value pairs of the work +definition. See + for more +information. + +--- + + receptor_kubernetes_commands: # defaults to not set + +The definition of the Receptor work-kubernetes commands. This +variable is expected to be a dictionary, with keys the unique worktype +name, and values a dict of the rest of the key-value pairs of the work +definition. See +for more information. + +--- + +# License + +Apache 2 diff --git a/roles/awx/receptor/defaults/main.yml b/roles/awx/receptor/defaults/main.yml new file mode 100644 index 0000000000..a5f5bbe486 --- /dev/null +++ b/roles/awx/receptor/defaults/main.yml @@ -0,0 +1,38 @@ +--- +receptor_user: receptor +receptor_group: receptor + +receptor_config_path: '/etc/receptor' +receptor_socket_dir: '/var/run/receptor' +receptor_control_filename: 'receptor.sock' + +receptor_tls: false +receptor_mintls13: false + +receptor_tls_dir: '/etc/receptor/tls' +receptor_tls_ca_dir: '{{ receptor_tls_dir }}/ca' +receptor_tls_certfile: "{{ receptor_tls_dir }}/{{ receptor_host_identifier }}.crt" +receptor_tls_keyfile: "{{ receptor_tls_dir }}/{{ receptor_host_identifier }}.key" +receptor_ca_certfile: "{{ receptor_tls_ca_dir }}/mesh-CA.crt" +receptor_ca_keyfile: "{{ receptor_tls_ca_dir }}/mesh-CA.key" + +receptor_worksign_key_dir: "/etc/receptor" +receptor_worksign_private_keyfile: "{{ receptor_worksign_key_dir }}/work_private_key.pem" +receptor_worksign_public_keyfile: "{{ receptor_worksign_key_dir }}/work_public_key.pem" + +receptor_fd_limit_soft: 4096 +receptor_fd_limit_hard: 8192 + +receptor_listener: true +receptor_local_only: false + +receptor_protocol: 'tcp' +receptor_port: 27199 +receptor_sign: false +receptor_verify: false + +receptor_log_level: 'info' + +_hostname: "{{ routable_hostname | default(ansible_host) }}" +receptor_host_identifier: + "{{ (_hostname == 'localhost') | ternary('localhost.localdomain', _hostname) }}" diff --git a/roles/awx/receptor/tasks/configure.yml b/roles/awx/receptor/tasks/configure.yml new file mode 100644 index 0000000000..8523fc0892 --- /dev/null +++ b/roles/awx/receptor/tasks/configure.yml @@ -0,0 +1,41 @@ +--- +- name: Ensure soft/hard file descriptors limits + ansible.builtin.template: + src: templates/pam_limits.conf.j2 + dest: /etc/security/limits.d/receptor.conf + mode: '0600' + owner: root + group: root + +- name: Ensure systemd override directory exists + ansible.builtin.file: + dest: /etc/systemd/system/receptor.service.d + state: directory + owner: root + group: root + mode: '0755' + +- name: Override receptor's systemd service runuser + ansible.builtin.template: + src: templates/systemd_receptor_override.conf.j2 + dest: /etc/systemd/system/receptor.service.d/override.conf + mode: '0644' + owner: root + group: root +# notify: Restart Receptor + +- name: Configure the receptor socket directory + ansible.builtin.file: + path: "{{ receptor_socket_dir }}" + state: directory + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + mode: '0750' + +- name: Create tmpfiles.d entry for receptor socket directory + ansible.builtin.template: + src: templates/receptor_tmpd.conf.j2 + dest: /etc/tmpfiles.d/receptor.conf + mode: '0640' + owner: root + group: root diff --git a/roles/awx/receptor/tasks/main.yml b/roles/awx/receptor/tasks/main.yml new file mode 100644 index 0000000000..db1ee1c3c2 --- /dev/null +++ b/roles/awx/receptor/tasks/main.yml @@ -0,0 +1,32 @@ +--- +# Variable configuration. +- include_tasks: variables.yml + +# Setup/install tasks. +- include_tasks: setup-RedHat.yml + when: ansible_os_family == 'RedHat' + +- include_tasks: configure.yml + +- include_tasks: tls.yml + when: receptor_tls + +- include_tasks: worksign.yml + when: receptor_sign or receptor_verify + +- name: Deploy receptor config + ansible.builtin.template: + src: templates/receptor.conf.j2 + dest: "{{ receptor_config_path }}/receptor.conf" + mode: '0644' + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" +# notify: +# - "Receptor Reload" + +- name: Start Receptor service + ansible.builtin.systemd: + name: receptor + state: started + daemon_reload: true + enabled: true diff --git a/roles/awx/receptor/tasks/setup-RedHat.yml b/roles/awx/receptor/tasks/setup-RedHat.yml new file mode 100644 index 0000000000..24c51a2db2 --- /dev/null +++ b/roles/awx/receptor/tasks/setup-RedHat.yml @@ -0,0 +1,10 @@ +--- +- name: Install receptor packages + ansible.builtin.dnf: + name: "{{ receptor_packages }}" + state: present + +- name: Install dependencies specific to the node type + ansible.builtin.dnf: + name: "{{ receptor_dependencies | default([]) }}" + state: present diff --git a/roles/awx/receptor/tasks/tls.yml b/roles/awx/receptor/tasks/tls.yml new file mode 100644 index 0000000000..c364be92f4 --- /dev/null +++ b/roles/awx/receptor/tasks/tls.yml @@ -0,0 +1,27 @@ +--- +- name: Create Receptor cert directories + ansible.builtin.file: + dest: "{{ item }}" + state: directory + mode: '0750' + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + recurse: true + with_items: + - "{{ receptor_tls_dir }}" + - "{{ receptor_tls_ca_dir }}" + +- name: Process provided TLS files + include_tasks: tls_local.yml + when: custom_tls_certfile is defined or custom_tls_keyfile is defined + +- name: Set TLS file permissions + ansible.builtin.file: + dest: "{{ item }}" + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + mode: '0640' + with_items: + - "{{ receptor_tls_certfile }}" + - "{{ receptor_tls_keyfile }}" + - "{{ receptor_ca_certfile }}" diff --git a/roles/awx/receptor/tasks/tls_local.yml b/roles/awx/receptor/tasks/tls_local.yml new file mode 100644 index 0000000000..3cace48859 --- /dev/null +++ b/roles/awx/receptor/tasks/tls_local.yml @@ -0,0 +1,61 @@ +--- +- name: Ensure both TLS files are provided + ansible.builtin.assert: + quiet: true + that: + - custom_tls_certfile | default('') | length + - custom_tls_keyfile | default('') | length + fail_msg: > + "You must provide both 'custom_tls_certfile' and 'custom_tls_keyfile'." + +- name: Ensure CA certfile is provided + ansible.builtin.assert: + quiet: true + that: + - custom_ca_certfile | default('') | length + fail_msg: > + "You must provide the public CA file when providing custom TLS certificates." + +- name: Check TLS private key modulus + delegate_to: localhost + become: false + ansible.builtin.command: openssl rsa -modulus -noout -in "{{ custom_tls_keyfile }}" + register: _tls_keyfile_modulus + changed_when: false + +- name: Check TLS x509 key modulus + delegate_to: localhost + become: false + ansible.builtin.command: openssl x509 -modulus -noout -in "{{ custom_tls_certfile }}" + register: _tls_certfile_modulus + changed_when: false + +- name: Ensure TLS pair matches + ansible.builtin.assert: + quiet: true + that: + - _tls_keyfile_modulus.stdout == _tls_certfile_modulus.stdout + fail_msg: > + "TLS !modulus! for {{ custom_tls_keyfile }} and {{ custom_tls_certfile }} doesn't match." + success_msg: "TLS !modulus! for {{ custom_tls_keyfile }} and {{ custom_tls_certfile }} matches." + +- name: Ensure x509 certificate was signed by the expected Certificate Authority + delegate_to: localhost + become: false + ansible.builtin.command: + openssl verify -CAfile "{{ custom_ca_certfile }}" "{{ custom_tls_certfile }}" + changed_when: false + +- name: Upload TLS files + become: true + become_user: "{{ receptor_user }}" + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + mode: '0640' + with_items: + - {src: '{{ custom_tls_certfile }}', dest: '{{ receptor_tls_certfile }}'} + - {src: '{{ custom_tls_keyfile }}', dest: '{{ receptor_tls_keyfile }}'} + - {src: '{{ custom_ca_certfile }}', dest: '{{ receptor_ca_certfile }}'} diff --git a/roles/awx/receptor/tasks/variables.yml b/roles/awx/receptor/tasks/variables.yml new file mode 100644 index 0000000000..a3b849b1ab --- /dev/null +++ b/roles/awx/receptor/tasks/variables.yml @@ -0,0 +1,10 @@ +--- +- name: Include OS-specific variables (RedHat) + ansible.builtin.include_vars: "{{ ansible_os_family }}.yml" + when: + - ansible_os_family == 'RedHat' + +- name: Define receptor_packages + ansible.builtin.set_fact: + receptor_packages: "{{ __receptor_packages | list }}" + when: receptor_packages is not defined diff --git a/roles/awx/receptor/tasks/worksign.yml b/roles/awx/receptor/tasks/worksign.yml new file mode 100644 index 0000000000..cd8c1b7f62 --- /dev/null +++ b/roles/awx/receptor/tasks/worksign.yml @@ -0,0 +1,3 @@ +--- +- include_tasks: worksign_local.yml + when: custom_worksign_private_keyfile is defined or custom_worksign_public_keyfile is defined diff --git a/roles/awx/receptor/tasks/worksign_local.yml b/roles/awx/receptor/tasks/worksign_local.yml new file mode 100644 index 0000000000..7f1532ca64 --- /dev/null +++ b/roles/awx/receptor/tasks/worksign_local.yml @@ -0,0 +1,18 @@ +--- +- name: Distribute private work signing key + ansible.builtin.copy: + src: "{{ custom_worksign_private_keyfile }}" + dest: "{{ receptor_worksign_private_keyfile }}" + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + mode: '0640' + when: receptor_sign + +- name: Distribute public work signing key + ansible.builtin.copy: + src: "{{ custom_worksign_public_keyfile }}" + dest: "{{ receptor_worksign_public_keyfile }}" + owner: "{{ receptor_user }}" + group: "{{ receptor_group }}" + mode: '0640' + when: receptor_verify diff --git a/roles/awx/receptor/templates/pam_limits.conf.j2 b/roles/awx/receptor/templates/pam_limits.conf.j2 new file mode 100644 index 0000000000..843eae4df7 --- /dev/null +++ b/roles/awx/receptor/templates/pam_limits.conf.j2 @@ -0,0 +1,3 @@ +# Receptor limits +{{ receptor_user }} soft nofile {{ receptor_fd_limit_soft }} +{{ receptor_user }} hard nofile {{ receptor_fd_limit_hard }} diff --git a/roles/awx/receptor/templates/receptor.conf.j2 b/roles/awx/receptor/templates/receptor.conf.j2 new file mode 100644 index 0000000000..043dd3f97c --- /dev/null +++ b/roles/awx/receptor/templates/receptor.conf.j2 @@ -0,0 +1,83 @@ +--- +- node: + id: {{ receptor_host_identifier }} + +{% if receptor_sign %} +- work-signing: + privatekey: {{ receptor_worksign_private_keyfile }} + tokenexpiration: 1m +{% endif %} + +{% if receptor_verify %} +- work-verification: + publickey: {{ receptor_worksign_public_keyfile }} +{% endif %} + +- log-level: {{ receptor_log_level }} + +- control-service: + service: control + filename: {{ receptor_socket_dir }}/{{ receptor_control_filename }} + permissions: 0660 + {% if receptor_tls -%} + tls: tls_server + {%- endif %} + +{% if receptor_tls -%} +- tls-server: + name: tls_server + cert: {{ receptor_tls_certfile }} + key: {{ receptor_tls_keyfile }} + clientcas: {{ receptor_ca_certfile }} + requireclientcert: true + mintls13: {{ receptor_mintls13 | bool }} + +- tls-client: + name: tls_client + cert: {{ receptor_tls_certfile }} + key: {{ receptor_tls_keyfile }} + rootcas: {{ receptor_ca_certfile }} + insecureskipverify: false + mintls13: {{ receptor_mintls13 | bool }} +{%- endif %} + +{% if receptor_local_only %} +- local-only +{% elif receptor_listener %} +- {{ receptor_protocol }}-listener: + port: {{ receptor_port }} + {% if receptor_tls -%} + tls: tls_server + {%- endif %} +{% endif %} + +{% if receptor_peers | default([]) %} +{% for peer in receptor_peers %} +- {{ peer['protocol'] }}-peer: + address: {{ peer['address'] | default(peer['host']) }}:{{ peer['port'] }} + redial: true +{% if receptor_tls -%} + tls: tls_client +{%- endif %} +{% endfor %} +{% endif %} + +{% if receptor_work_commands is defined -%} +{% for command, config in receptor_work_commands.items() %} +- work-command: + worktype: {{ command }} +{% for key, value in config.items() %} + {{ key }}: {{ value }} +{% endfor %} +{% endfor %} +{%- endif %} + +{%- if receptor_kubernetes_commands is defined %} +{% for command, config in receptor_kubernetes_commands.items() %} +- work-kubernetes: + worktype: {{ command }} +{% for key, value in config.items() %} + {{ key }}: {{ value }} +{% endfor %} +{% endfor %} +{% endif -%} diff --git a/roles/awx/receptor/templates/receptor_tmpd.conf.j2 b/roles/awx/receptor/templates/receptor_tmpd.conf.j2 new file mode 100644 index 0000000000..1b2e07ae49 --- /dev/null +++ b/roles/awx/receptor/templates/receptor_tmpd.conf.j2 @@ -0,0 +1 @@ +D {{ receptor_socket_dir }} 0750 {{ receptor_user }} {{ receptor_group }} - diff --git a/roles/awx/receptor/templates/systemd_receptor_override.conf.j2 b/roles/awx/receptor/templates/systemd_receptor_override.conf.j2 new file mode 100644 index 0000000000..f3e268bde6 --- /dev/null +++ b/roles/awx/receptor/templates/systemd_receptor_override.conf.j2 @@ -0,0 +1,7 @@ +[Service] +User={{ receptor_user }} +Group={{ receptor_group }} +{% if receptor_app_service is defined %} +[Unit] +PartOf={{ receptor_app_service }} +{% endif %} diff --git a/roles/awx/receptor/vars/RedHat.yml b/roles/awx/receptor/vars/RedHat.yml new file mode 100644 index 0000000000..c83931d68c --- /dev/null +++ b/roles/awx/receptor/vars/RedHat.yml @@ -0,0 +1,3 @@ +--- +__receptor_packages: + - receptor diff --git a/roles/ipsilon/tasks/main.yml b/roles/ipsilon/tasks/main.yml index d6b5059093..4b9f78f8ca 100644 --- a/roles/ipsilon/tasks/main.yml +++ b/roles/ipsilon/tasks/main.yml @@ -122,6 +122,16 @@ - ipsilon - config +- name: load the AWX SAML2 metadata that will be included in the configuration.conf file + uri: + url: https://awx.fedoraproject.org/sso/metadata/saml/ + return_content: yes + register: awx_metadata + when: env == "production" + tags: + - ipsilon + - config + - name: copy ipsilon admin configuration template: src: "configuration.conf" diff --git a/roles/ipsilon/templates/saml2_data b/roles/ipsilon/templates/saml2_data index e7d4092e9a..a5c92c5b30 100644 --- a/roles/ipsilon/templates/saml2_data +++ b/roles/ipsilon/templates/saml2_data @@ -46,8 +46,8 @@ rhbz metadata = MIIFADCCAugCCQCtO4Mdj/UfEjANBgkqhkiG9w0BAQsFADBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMB4XDTE4MDQxMjE2MDQzOFoXDTE5MDQxMjE2MDQzOFowQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM0xqadxtdgfZhQe5nbQvKwIutxEAqnFht+U/87N0x8LClTn4xqTSjt78Uw3Mmm9LI1Xp/X/Q5vQWBpCntM16ACLEArACwh+qP3JRq2n89FPpIuuOQp7ZCve/gMHtMTjSmfp+P/NNkNRwSnT1V8ruOn1GKc8uv9uOaHHlFN+d8I0TBGMzzmNcZmn/ZKEHfhlAon+3ogZ4d0ExYapSbTuE0TNoTn0nM21hHgZreDFvXHHgXZKQy2ROiFp4AnWNeZ03zvswwWuJ6Y0L1psVmwYoZ1pLtoEA9881ZYx7RyS49Lje7Ixqej8DJPQ88ntUguz/pUeGAc0210MIcfqPr3TqvCteCjFNCo/GHO+vu3HbNBDH3iPKr+Sj9H96jWQXgEcOFPLZZuZ3UzsfXBC6dEdarUw96jsg7p0Y67mLWHGWhKmdjKLe1hRUfT4ZYVPsuqKxU+KYU5XdrfPCryeh7zd/dMGaZSaxAdSzIr0PdyEjcOPBo5Kn2QDYl2VEBRk6Qxjx2aRk6ET/PIvvz/VYm2S5fTYazvN8L3r3mpnK4G5zF8j1W4Y34qGrANhZDryZV1dFVwWQr31AemxEoLHYkBw5OqusKSBjcDb4+ek5SdfJuRbd8DyjEN+klDeF9+XhouedLC29Z3jRNvgzE6XarfjVZUaHSmw4qsM8YFRV7Wz2R0tAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAD9bqMfBUfNfS9gP+isOXAgs0Sb8Klaq+YAkzY06PQP1ia7EAXBiDX85je8+NdU3v3wQhACzOsS9aPBQT0eK+1urbeNd5vr7zsOUKcCFknFV9wP+LNNhMGbcysEf7WUVjPkEpor36aldTrUsnkGb6bVxlrWEnJtWqekOlpwDPC3Hrv9F+4/auhKzLs98lqAOhIT5c+72oT6viffaiWhvvsJhJj6weZuBR+Rat4F+60TtONX8jAtZaWzlIfSacMDp5QNj688GJRm2wJ6IQjaf1maJEBjMSWqCyBsuskEvEF2YWrdRpaY1+gZ2X7OjQ+iuvuLzxFYlnznIrsSHEPMHjSuL+JYIJM2dEGf6NKi5EQy9mzz3Fi3bJJD9mHqjWY3AFWM3u1ig+u94AZJCsmXGDOuqDOyUqbin6leDgDQdbwjpgBZWygmu2BxV1nWrtgz90qD9MyD10wuKIA6Sp3Z69kYXGgNe13bQ4r8r1vvdqgj2BJRxIujOPyBFCxhsFG8hIaMrqrhNqYnFzrx58LfNgj7OEeI+YhZfCx1iuDlU1AkvSxQhO0HioFg+ahWxLydHwGuI9U489UccVmIYDZd7UYSHq11OBCtCiOwwVUhAMwVTdJJGK0qChDYDOXFXYw/nzTTwhIo7aO70EVHzF2jRdv47ukBui52LsDnlFyTa8uJHurn:oasis:names:tc:SAML:1.1:nameid-format:unspecified fedora Fedora Authentication https://id.fedoraproject.org Fedora Infrastructure infrastructure@lists.fedoraproject.org Fedora Infrastructure infrastructure@lists.fedoraproject.org +awx Allowed Attributes = ["email", "_groups", "givenname", "surname"] +awx metadata = {{ awx_metadata.content | replace("\n", " ") }} rhbzdev id = https://bugzilla.dev.redhat.com/saml2_metadata.cgi