diff --git a/.github/workflows/molecule.yml b/.github/workflows/molecule.yml index 1e86f6de..d627a48a 100644 --- a/.github/workflows/molecule.yml +++ b/.github/workflows/molecule.yml @@ -49,6 +49,7 @@ jobs: - complete - complete_plus - default + - entitlement_plus - push_config - reverse_proxy - stub_status diff --git a/CHANGELOG.md b/CHANGELOG.md index c1a96971..d56dd95b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ FEATURES: - Add validation tasks to check the Ansible version, the Jinja2 version, and whether the required Ansible collections for this role are installed. - Bump the Ansible `community.general` collection to `9.2.0`, `community.crypto` collection to `2.21.1` and `community.docker` collection to `3.11.0`. -- Add templating support for the `ngx_http_gzip_static_module` and `ngx_stream_map_module` NGINX modules. +- Add templating support for the `ngx_mgmt_module`, `ngx_http_gzip_static_module`, and `ngx_stream_map_module` NGINX modules. BUG FIXES: diff --git a/defaults/main/template.yml b/defaults/main/template.yml index 670ea93a..81750652 100644 --- a/defaults/main/template.yml +++ b/defaults/main/template.yml @@ -66,6 +66,25 @@ nginx_config_main_template: worker_connections: 1024 # Number # include: # String or a list of strings # - /etc/nginx/modules.conf + mgmt: # Configure NGINX management directives. Only required when using NGINX Plus >R33. + enforce_initial_report: true # Boolean + license_token: license.jwt + # proxy: 123.456.789:8353 + # proxy_username: username + # proxy_password: password + resolver: + address: 127.0.0.1 # Required -- String or a list of strings + valid: 30s + ipv4: true # Boolean + ipv6: true # Boolean + status_zone: mgmt_mem_zone + # ssl_crl: /path/to/file + # ssl_trusted_certificate: /path/to/file + ssl_verify: false # Boolean + state_path: /var/lib/nginx/state + usage_report: + endpoint: product.connect.nginx.com + interval: 30m http: include: # String or a list of strings - /etc/nginx/mime.types diff --git a/molecule/entitlement_plus/converge.yml b/molecule/entitlement_plus/converge.yml new file mode 100644 index 00000000..e1cc7344 --- /dev/null +++ b/molecule/entitlement_plus/converge.yml @@ -0,0 +1,47 @@ +--- +- name: Converge + hosts: all + tasks: + - name: Configure NGINX + ansible.builtin.include_role: + name: ansible-role-nginx-config + vars: + nginx_config_debug_output: true + + nginx_config_main_template_enable: true + nginx_config_main_template: + template_file: nginx.conf.j2 + deployment_location: /etc/nginx/nginx.conf + config: + main: + user: nginx + worker_processes: auto + error_log: + - file: /var/log/nginx/error.log + level: notice + pid: /var/run/nginx.pid + worker_rlimit_nofile: 2048 + events: + worker_connections: 1024 + mgmt: + enforce_initial_report: true + license_token: license.jwt + # proxy: + # proxy_username: + # proxy_password: + resolver: + address: 127.0.0.1 + valid: 30s + ipv4: true + ipv6: true + status_zone: mgmt_mem_zone + # ssl_crl: /path/to/file + # ssl_trusted_certificate: /path/to/file + ssl_verify: false + state_path: /var/lib/nginx/state + usage_report: + endpoint: product.connect.nginx.com + interval: 30m + http: + include: + - /etc/nginx/conf.d/*.conf diff --git a/molecule/entitlement_plus/molecule.yml b/molecule/entitlement_plus/molecule.yml new file mode 100644 index 00000000..813c8240 --- /dev/null +++ b/molecule/entitlement_plus/molecule.yml @@ -0,0 +1,51 @@ +--- +dependency: + name: galaxy + options: + role-file: molecule/common/requirements/oss_requirements.yml +driver: + name: docker +lint: | + set -e + ansible-lint --force-color +platforms: + - name: alpine-3.19 + image: alpine:3.19 + dockerfile: ../common/Dockerfile.j2 + privileged: true + cgroupns_mode: host + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + command: /sbin/init + - name: debian-bullseye + image: debian:bullseye-slim + dockerfile: ../common/Dockerfile.j2 + privileged: true + cgroupns_mode: host + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + command: /sbin/init + - name: rhel-9 + image: redhat/ubi9:9.4 + dockerfile: ../common/Dockerfile.j2 + privileged: true + cgroupns_mode: host + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + command: /usr/sbin/init + - name: ubuntu-jammy + image: ubuntu:jammy + dockerfile: ../common/Dockerfile.j2 + privileged: true + cgroupns_mode: host + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:rw + command: /sbin/init +provisioner: + name: ansible + playbooks: + prepare: prepare.yml + converge: converge.yml + verify: verify.yml + env: + ANSIBLE_ROLES_PATH: ~/.cache/molecule/ansible-role-nginx-config/${MOLECULE_SCENARIO_NAME}/roles:${MOLECULE_PROJECT_DIRECTORY}/..:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles diff --git a/molecule/entitlement_plus/prepare.yml b/molecule/entitlement_plus/prepare.yml new file mode 100644 index 00000000..d962353a --- /dev/null +++ b/molecule/entitlement_plus/prepare.yml @@ -0,0 +1,39 @@ +--- +- name: Prepare + hosts: localhost + gather_facts: false + tasks: + - name: Create ephemeral license certificate file from b64 decoded env var + ansible.builtin.copy: + content: "{{ lookup('env', 'NGINX_CRT') | b64decode }}" + dest: ../common/files/license/nginx-repo.crt + force: false + mode: "0444" + + - name: Create ephemeral license key file from b64 decoded env var + ansible.builtin.copy: + content: "{{ lookup('env', 'NGINX_KEY') | b64decode }}" + dest: ../common/files/license/nginx-repo.key + force: false + mode: "0444" + + - name: Create ephemeral license JWT file from b64 encoded env var + ansible.builtin.copy: + content: "{{ lookup('env', 'NGINX_JWT') }}" + dest: ../common/files/license/license.jwt + force: false + mode: "0444" + +- name: Install NGINX Plus + hosts: all + tasks: + - name: Install NGINX Plus + ansible.builtin.include_role: + name: nginxinc.nginx + vars: + nginx_type: plus + nginx_license: + certificate: ../common/files/license/nginx-repo.crt + key: ../common/files/license/nginx-repo.key + jwt: ../common/files/license/license.jwt + nginx_remove_license: false diff --git a/molecule/entitlement_plus/verify.yml b/molecule/entitlement_plus/verify.yml new file mode 100644 index 00000000..17308d48 --- /dev/null +++ b/molecule/entitlement_plus/verify.yml @@ -0,0 +1,20 @@ +--- +- name: Verify + hosts: all + tasks: + - name: Check if NGINX Plus is installed + ansible.builtin.package: + name: nginx-plus + state: present + check_mode: true + register: install + failed_when: (install is changed) or (install is failed) + + - name: Check if NGINX service is running + ansible.builtin.service: + name: nginx + state: started + enabled: true + check_mode: true + register: service + failed_when: (service is changed) or (service is failed) diff --git a/templates/core.j2 b/templates/core.j2 index a5ad984b..ff097ebb 100644 --- a/templates/core.j2 +++ b/templates/core.j2 @@ -116,3 +116,43 @@ worker_aio_requests {{ events['worker_aio_requests'] }}; worker_connections {{ events['worker_connections'] }}; {% endif %} {% endmacro %} + +{% macro mgmt(mgmt) %} +{% if mgmt['enforce_initial_report'] is defined and mgmt['enforce_initial_report'] is boolean %} +enforce_initial_report {{ mgmt['enforce_initial_report'] | ternary('on', 'off') }}; +{% endif %} +{% if mgmt['license_token'] is defined %} +license_token {{ mgmt['license_token'] }}; +{% endif %} +{% if mgmt['proxy'] is defined %} +proxy {{ mgmt['proxy'] }}; +{% endif %} +{% if mgmt['proxy_username'] is defined %} +proxy_username {{ mgmt['proxy_username'] }}; +{% endif %} +{% if mgmt['proxy_password'] is defined %} +proxy_password {{ mgmt['proxy_password'] }}; +{% endif %} +{% if mgmt['resolver'] is defined %} +resolver {{ mgmt['resolver']['address'] if mgmt['resolver']['address'] is string else mgmt['resolver']['address'] | join(' ') -}} +{{- (' valid=' + mgmt['resolver']['valid'] | string) if mgmt['resolver']['valid'] is defined -}} +{{- (' ipv4=' + mgmt['resolver']['ipv4'] | ternary('on', 'off')) if mgmt['resolver']['ipv4'] is defined and mgmt['resolver']['ipv4'] is boolean -}} +{{- (' ipv6=' + mgmt['resolver']['ipv6'] | ternary('on', 'off')) if mgmt['resolver']['ipv6'] is defined and mgmt['resolver']['ipv6'] is boolean -}} +{{- (' status_zone=' + mgmt['resolver']['status_zone'] | string) if mgmt['resolver']['status_zone'] is defined }}; +{% endif %} +{% if mgmt['ssl_crl'] is defined %} +ssl_crl {{ mgmt['ssl_crl'] }}; +{% endif %} +{% if mgmt['ssl_trusted_certificate'] is defined %} +ssl_trusted_certificate {{ mgmt['ssl_trusted_certificate'] }}; +{% endif %} +{% if mgmt['ssl_verify'] is defined and mgmt['ssl_verify'] is boolean %} +ssl_verify {{ mgmt['ssl_verify'] | ternary('on', 'off') }}; +{% endif %} +{% if mgmt['state_path'] is defined %} +state_path {{ mgmt['state_path'] }}; +{% endif %} +{% if mgmt['usage_report'] is defined %} +usage_report{{ ' endpoint=' + mgmt['usage_report']['endpoint'] if mgmt['usage_report']['endpoint'] is defined }}{{ (' interval=' + mgmt['usage_report']['interval'] | string) if mgmt['usage_report']['interval'] is defined }}; +{% endif %} +{% endmacro %} diff --git a/templates/nginx.conf.j2 b/templates/nginx.conf.j2 index 8b39c340..396172a5 100644 --- a/templates/nginx.conf.j2 +++ b/templates/nginx.conf.j2 @@ -22,6 +22,15 @@ events { {% endif %} } +{% if nginx_config_main_template['config']['mgmt'] is defined %} +mgmt { +{% from 'core.j2' import mgmt with context %} +{% filter indent(4) %} + {{ mgmt(nginx_config_main_template['config']['mgmt']) }} +{%- endfilter %} +} +{% endif %} + {% if nginx_config_main_template['config']['http'] is defined %} http { {% if nginx_config_main_template['config']['http']['include'] is defined and nginx_config_main_template['config']['http']['include'] is not mapping %}