Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement automatic download and install of security patches #9

Merged
merged 3 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions roles/jbcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Dependencies

The roles depends on:

* the `redhat_csp_download` role from [middleware_automation.redhat_csp_download](https://github.com/ansible-middleware/redhat-csp-download) collection if Red Hat Single Sign-on zip have to be downloaded from RHN.
* [middleware_automation.common](https://github.com/ansible-middleware/common)


Role Defaults
-------------

| Variable | Description | Default |
| Parameter | Description | Default |
|:---------|:------------|:--------|
|`jbcs_ssl_enable`| Enable SSL | `True` |
|`jbcs_ssl_port`| SSL listen port | `443` |
Expand All @@ -38,11 +38,16 @@ Role Defaults
|`jbcs_configure_firewalld`| Whether to configure firewalld ports for jbcs | `True` |
|`jbcs_port_check`| Whether to check open ports at end of playbook | `False` |
|`jbcs_proxy_pass`| List of proxy pass directives/options. Element keys: path, url, reverse_path, reverse_url | `[]` |
|`jbcs_patch`| Enable security patches install | `True` |
|`jbcs_distro`|Target instance distributrion version | `RHEL8` |
|`jbcs_arch`| Target instance architecture | `x86_64` |
|`jbcs_bundle_prefix`| Filename prefix for JBCS install archives | `jbcs-httpd24-httpd` |


Role Variables
--------------

* No required variables at this time

License
-------
Expand Down
6 changes: 5 additions & 1 deletion roles/jbcs/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ jbcs_ssl_port: 443
jbcs_version: '2.4.57'
jbcs_distro: RHEL8
jbcs_arch: x86_64
jbcs_bundle_prefix: "jbcs-httpd24-httpd"

jbcs_bundle: "jbcs-httpd24-httpd-{{ jbcs_version }}-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
jbcs_bundle: "{{ jbcs_bundle_prefix }}-{{ jbcs_version }}-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
jbcs_patch_bundle: "{{ jbcs_bundle_prefix }}-{{ jbcs_version }}-SP[1-9][0-9]*-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"

jbcs_patch: true
jbcs_zip_path: /opt/apps/

jbcs_home: /opt/jbcs/jbcs-httpd24-2.4/
Expand Down
12 changes: 10 additions & 2 deletions roles/jbcs/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ argument_specs:
default: 'x86_64'
description: "Install on this architecture"
type: "str"
jbcs_patch:
default: true
description: "Enable security patches install"
type: "bool"
jbcs_bundle:
# line 5 of jbcs/defaults/main.yml
default: "jbcs-httpd24-httpd-{{ jbcs_version }}-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
default: "{{ jbcs_bundle_prefix }}-{{ jbcs_version }}-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
description: "Filename of JBCS install archive"
type: "str"
jbcs_patch_bundle:
default: "jbcs-httpd24-httpd-{{ jbcs_version }}-SP[0-9]*-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
default: "{{ jbcs_bundle_prefix }}-{{ jbcs_version }}-SP[1-9][0-9]*-{{ jbcs_distro }}-{{ jbcs_arch }}.zip"
description: "Filename of JBCS patch install archive"
type: "str"
jbcs_bundle_prefix:
default: "jbcs-httpd24-httpd"
description: "Filename prefix for JBCS install archives"
type: "str"
jbcs_zip_path:
# line 6 of jbcs/defaults/main.yml
default: "/opt/apps"
Expand Down
2 changes: 1 addition & 1 deletion roles/jbcs/meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ galaxy_info:
platforms:
- name: EL
versions:
- 8
- "8"

galaxy_tags:
- httpd
Expand Down
45 changes: 3 additions & 42 deletions roles/jbcs/tasks/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
register: local_path
delegate_to: localhost

- name: Check downloaded archive
- name: Check local download archive
ansible.builtin.stat:
path: "{{ local_path.stat.path }}/{{ jbcs_bundle }}"
register: local_archive_path
Expand Down Expand Up @@ -94,7 +94,8 @@

- name: Determine install zipfile from search results
ansible.builtin.set_fact:
rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', '.*/jbcs-httpd24-httpd-' + jbcs_version + '-' + jbcs_distro + '-' + jbcs_arch + '.zip') }}"
rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', \
'.*/' + [ jbcs_bundle_prefix, jbcs_version, jbcs_distro, jbcs_arch ] | join('-') + '.zip') }}"
delegate_to: localhost
run_once: true

Expand Down Expand Up @@ -154,43 +155,3 @@
msg: "{{ httpd.home }} already exists and version unchanged, skipping decompression"
when:
- not new_version_downloaded.changed and path_to_workdir.stat.exists

- name: Post install HTTPD
become: true
ansible.builtin.template:
src: templates/jbcs-httpd24-httpd.service.j2
dest: "/usr/lib/systemd/system/{{ jbcs_service_name }}.service"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
mode: 0640
notify:
- "Reload systemd"

- name: Ensure JBCS configuration is correct
become: true
notify:
- "Restart JBCS"
loop:
- name: 00-base.conf
dest: "{{ httpd.home }}/httpd/conf.modules.d"
- name: httpd.conf
dest: "{{ httpd.home }}/httpd/conf"
ansible.builtin.template:
src: "templates/{{ item.name }}.j2"
dest: "{{ item.dest }}/{{ item.name }}"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
mode: 0640

- name: Ensure JBCS module configuration is correct
become: true
ansible.builtin.command: "mv {{ item }} {{ item }}.bak"
args:
removes: "{{ item }}"
creates: "{{ item }}.bak"
chdir: "{{ httpd.home }}/httpd/conf.d/"
failed_when: false
changed_when: false
loop:
- manual.conf
- welcome.conf
7 changes: 7 additions & 0 deletions roles/jbcs/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
- name: Import install tasks
ansible.builtin.include_tasks: install.yml

- name: Import patch tasks
ansible.builtin.include_tasks: patch.yml
when: jbcs_patch

- name: Import post install tasks
ansible.builtin.include_tasks: post_install.yml

- name: Import SSL configuration tasks
ansible.builtin.include_tasks: ssl.yml

Expand Down
128 changes: 128 additions & 0 deletions roles/jbcs/tasks/patch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
---
- name: Download JBCS patch from RHN using JBoss Network API
delegate_to: localhost
run_once: true
when:
- not jbcs_installed is defined
- not jbcs_offline_install
- rhn_username is defined and rhn_password is defined
block:
- name: Retrieve product download using JBoss Network API
middleware_automation.common.product_search:
client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}"
product_type: SECURITY
product_version: "{{ jbcs_version.split('-')[0] }}"
product_category: "core.service.apachehttp"
register: rhn_products
delegate_to: localhost
run_once: true

- name: Determine patch zipfiles from search results
ansible.builtin.set_fact:
rhn_filtered_products: "{{ rhn_products.results | map(attribute='file_path') | \
select('match', '^[^/]*/' + jbcs_patch_bundle + '$') | \
map('regex_replace', '[^/]*/' + jbcs_bundle_prefix + '-' + jbcs_version + '-SP([1-9][0-9]*)-.*', '\\1' ) | \
list | unique }}"
delegate_to: localhost
run_once: true

- name: Sort patch versions
ansible.builtin.set_fact:
latest_patch_version: "{{ 'SP' + (rhn_filtered_products | middleware_automation.common.version_sort | last) }}"
delegate_to: localhost
run_once: true

- name: Determine latest patch version
ansible.builtin.set_fact:
rhn_filtered_products: "{{ rhn_products.results | selectattr('file_path', 'match', \
'[^/]*/' + [ jbcs_bundle_prefix, jbcs_version, latest_patch_version, jbcs_distro, jbcs_arch ] | join('-') + '.zip$') }}"
delegate_to: localhost
run_once: true

- name: Determine patch archive filename
ansible.builtin.set_fact:
jbcs_patch_bundle: "{{ (rhn_filtered_products | first).file_path | basename }}"
delegate_to: localhost
run_once: true

- name: Download JBCS patch
middleware_automation.common.product_download:
client_id: "{{ rhn_username }}"
client_secret: "{{ rhn_password }}"
product_id: "{{ (rhn_filtered_products | first).id }}"
dest: "{{ local_path.stat.path }}/{{ jbcs_patch_bundle }}"
no_log: "{{ omit_rhn_output | default(true) }}"
delegate_to: localhost
run_once: true

- name: Use provided JBCS patch archive for offline install
delegate_to: localhost
run_once: true
when:
- not jbcs_installed is defined
- jbcs_offline_install
block:
- name: TODO
ansible.builtin.debug:
msg: "Offline install patch not implemented"
delegate_to: localhost
run_once: true

- name: Check local download archive
ansible.builtin.stat:
path: "{{ local_path.stat.path }}/{{ jbcs_patch_bundle }}"
register: local_archive_path
delegate_to: localhost

## check remote archive
- name: Set download archive path
ansible.builtin.set_fact:
archive: "{{ jbcs_zip_path }}/{{ jbcs_patch_bundle }}"

- name: Check download archive path
become: true
ansible.builtin.stat:
path: "{{ archive }}"
register: archive_path

## copy and unpack
- name: Copy archive to target nodes
ansible.builtin.copy:
src: "{{ local_path.stat.path }}/{{ jbcs_patch_bundle }}"
dest: "{{ archive }}"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
mode: 0640
register: new_version_downloaded
when:
- not archive_path.stat.exists
- local_archive_path.stat is defined
- local_archive_path.stat.exists
become: true

- name: "Check target directory: {{ httpd.home }}"
ansible.builtin.stat:
path: "{{ httpd.home }}"
register: path_to_workdir
become: true

- name: Extract JBCS patch archive on target
ansible.builtin.unarchive:
remote_src: true
src: "{{ archive }}"
dest: /opt/jbcs/
creates: "{{ httpd.home }}"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
become: true
when:
- new_version_downloaded.changed or not path_to_workdir.stat.exists
notify:
- Restart JBCS

- name: Inform decompression was not executed
ansible.builtin.debug:
msg: "{{ httpd.home }} already exists and version unchanged, skipping decompression"
when:
- not new_version_downloaded.changed and path_to_workdir.stat.exists
40 changes: 40 additions & 0 deletions roles/jbcs/tasks/post_install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
- name: Post install HTTPD
become: true
ansible.builtin.template:
src: templates/jbcs-httpd24-httpd.service.j2
dest: "/usr/lib/systemd/system/{{ jbcs_service_name }}.service"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
mode: 0640
notify:
- "Reload systemd"

- name: Ensure JBCS configuration is correct
become: true
notify:
- "Restart JBCS"
loop:
- name: 00-base.conf
dest: "{{ httpd.home }}/httpd/conf.modules.d"
- name: httpd.conf
dest: "{{ httpd.home }}/httpd/conf"
ansible.builtin.template:
src: "templates/{{ item.name }}.j2"
dest: "{{ item.dest }}/{{ item.name }}"
owner: "{{ httpd.user.name }}"
group: "{{ httpd.group.name }}"
mode: 0640

- name: Ensure JBCS module configuration is correct
become: true
ansible.builtin.command: "mv {{ item }} {{ item }}.bak"
args:
removes: "{{ item }}"
creates: "{{ item }}.bak"
chdir: "{{ httpd.home }}/httpd/conf.d/"
failed_when: false
changed_when: false
loop:
- manual.conf
- welcome.conf
Loading