diff --git a/.gitignore b/.gitignore index ac4edb7..179d5e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,34 @@ -SOURCES/ad_integration-1.0.2.tar.gz -SOURCES/ansible-posix-1.5.1.tar.gz -SOURCES/ansible-sshd-v0.18.1.tar.gz -SOURCES/auto-maintenance-d6a8e0167e9ed8d089093b7ead1e298241b534e1.tar.gz -SOURCES/certificate-1.1.9.tar.gz -SOURCES/cockpit-1.4.3.tar.gz -SOURCES/community-general-6.4.0.tar.gz -SOURCES/containers-podman-1.10.1.tar.gz -SOURCES/crypto_policies-1.2.7.tar.gz -SOURCES/firewall-1.4.2.tar.gz -SOURCES/ha_cluster-1.8.7.tar.gz -SOURCES/journald-1.0.0.tar.gz -SOURCES/kdump-1.2.6.tar.gz -SOURCES/kernel_settings-1.1.11.tar.gz -SOURCES/logging-1.11.5.tar.gz -SOURCES/metrics-1.8.1.tar.gz -SOURCES/nbde_client-1.2.10.tar.gz -SOURCES/nbde_server-1.3.3.tar.gz -SOURCES/network-1.11.2.tar.gz -SOURCES/podman-1.1.2.tar.gz -SOURCES/postfix-1.3.3.tar.gz -SOURCES/rhc-1.1.3.tar.gz -SOURCES/selinux-1.5.6.tar.gz -SOURCES/ssh-1.1.12.tar.gz -SOURCES/storage-1.9.6.tar.gz -SOURCES/timesync-1.7.2.tar.gz -SOURCES/tlog-1.2.11.tar.gz -SOURCES/vpn-1.5.3.tar.gz +SOURCES/ad_integration-1.4.2.tar.gz +SOURCES/ansible-posix-1.5.4.tar.gz +SOURCES/ansible-sshd-v0.23.2.tar.gz +SOURCES/auto-maintenance-11ad785c9bb72611244e7909450ca4247e12db4d.tar.gz +SOURCES/bootloader-1.0.3.tar.gz +SOURCES/certificate-1.3.3.tar.gz +SOURCES/cockpit-1.5.5.tar.gz +SOURCES/community-general-8.3.0.tar.gz +SOURCES/containers-podman-1.12.0.tar.gz +SOURCES/crypto_policies-1.3.2.tar.gz +SOURCES/fapolicyd-1.1.1.tar.gz +SOURCES/firewall-1.7.4.tar.gz +SOURCES/ha_cluster-1.14.0.tar.gz +SOURCES/journald-1.2.3.tar.gz +SOURCES/kdump-1.4.4.tar.gz +SOURCES/kernel_settings-1.2.2.tar.gz +SOURCES/keylime_server-1.1.2.tar.gz +SOURCES/logging-1.12.4.tar.gz +SOURCES/metrics-1.10.1.tar.gz +SOURCES/nbde_client-1.2.17.tar.gz +SOURCES/nbde_server-1.4.3.tar.gz +SOURCES/network-1.15.1.tar.gz +SOURCES/podman-1.4.7.tar.gz +SOURCES/postfix-1.4.3.tar.gz +SOURCES/postgresql-1.3.5.tar.gz +SOURCES/rhc-1.6.0.tar.gz +SOURCES/selinux-1.7.4.tar.gz +SOURCES/snapshot-1.3.1.tar.gz +SOURCES/ssh-1.3.2.tar.gz +SOURCES/storage-1.16.2.tar.gz +SOURCES/systemd-1.1.2.tar.gz +SOURCES/timesync-1.8.2.tar.gz +SOURCES/tlog-1.3.3.tar.gz +SOURCES/vpn-1.6.3.tar.gz diff --git a/.rhel-system-roles.metadata b/.rhel-system-roles.metadata deleted file mode 100644 index 2c4f09a..0000000 --- a/.rhel-system-roles.metadata +++ /dev/null @@ -1,28 +0,0 @@ -c531e83edf95f96389a6c1c10ea80ccd2b42cc75 SOURCES/ad_integration-1.0.2.tar.gz -f36cb7b1662ecda55c27f5bc15e0a22a1f11a361 SOURCES/ansible-posix-1.5.1.tar.gz -71c988d6ad9b916727cd93b8e2a2154183f5035a SOURCES/ansible-sshd-v0.18.1.tar.gz -a59d5ba01d5e536e800bc847528f16c16b961375 SOURCES/auto-maintenance-d6a8e0167e9ed8d089093b7ead1e298241b534e1.tar.gz -0e3826af628625ef7b16e3f57b6156128fd982c0 SOURCES/certificate-1.1.9.tar.gz -05148744a2d69d469dc3c678bb1a9fb9747dea26 SOURCES/cockpit-1.4.3.tar.gz -687a4e36e9d8f73a8a44a448da1c205eb0ce5f1c SOURCES/community-general-6.4.0.tar.gz -ccb070885fd455bb6e7f2b8ca050d40d30609fec SOURCES/containers-podman-1.10.1.tar.gz -47e3a2db8790c98fd5c09ab1887318b6ba56ce49 SOURCES/crypto_policies-1.2.7.tar.gz -1c414411b4960040eebcef2ddd528eea0b47f05f SOURCES/firewall-1.4.2.tar.gz -7cfd7d6fa2164fcb757a316e123cbe048f8f0ac9 SOURCES/ha_cluster-1.8.7.tar.gz -97edc58624de8ccb3f4b628a48811094a0dc1513 SOURCES/journald-1.0.0.tar.gz -439ea600c242c914c90933f287f3caf8c7869c12 SOURCES/kdump-1.2.6.tar.gz -49f4bc8f273339cde0cdecccffa7b902359b2601 SOURCES/kernel_settings-1.1.11.tar.gz -7fe83b26f954e55a282a4d5398e3064a7783a83a SOURCES/logging-1.11.5.tar.gz -e217af697b4e3205177360726f579d01b145be77 SOURCES/metrics-1.8.1.tar.gz -cf27267d3d54f1537ddda89f6d4db7abbe55b357 SOURCES/nbde_client-1.2.10.tar.gz -274986399c55eb35f281173621e75eb2d7ae00e6 SOURCES/nbde_server-1.3.3.tar.gz -857b1c3ea5a1a48dc964fb5c139861ba01c9e732 SOURCES/network-1.11.2.tar.gz -fe48a68775bcb87daf3f62ab58a1998ffaa4e6be SOURCES/podman-1.1.2.tar.gz -9244301089661fecca31dfee431b32d4876063be SOURCES/postfix-1.3.3.tar.gz -2340277be032405d0ed2be00ff3971837180c5cb SOURCES/rhc-1.1.3.tar.gz -bac983e0dcc5041a4c7d4d25849ed31aaf462df7 SOURCES/selinux-1.5.6.tar.gz -1bb35bc413249ce3209e471687afd60e0e25dddb SOURCES/ssh-1.1.12.tar.gz -0eea1b45136cb807740fa12435b02eccdb35a7ac SOURCES/storage-1.9.6.tar.gz -fefc5b4bd9635bb8fe70a9af9fc178cb5d3e8193 SOURCES/timesync-1.7.2.tar.gz -07c42ba749c110a87469a5c477579582c4d0c538 SOURCES/tlog-1.2.11.tar.gz -5b5ee7283092a16e9ec1aba47ee651274f784416 SOURCES/vpn-1.5.3.tar.gz diff --git a/SOURCES/CHANGELOG.md b/SOURCES/CHANGELOG.md index fa7c8dc..c8a77fc 100644 --- a/SOURCES/CHANGELOG.md +++ b/SOURCES/CHANGELOG.md @@ -1,17 +1,105 @@ Changelog ========= - -[1.21.2] - 2023-06-12 +[1.23.0] - 2024-01-15 ---------------------------- ### New Features -- none +- [RHEL for Edge support in system roles](https://issues.redhat.com/browse/RHEL-15872) +- [ad_integration - feat: Add sssd custom settings](https://issues.redhat.com/browse/RHEL-17667) +- [ad_integration - Enable AD dynamic DNS updates](https://issues.redhat.com/browse/RHEL-1119) +- [ad_integration - feat: add ad_integration_preserve_authselect_profile](https://issues.redhat.com/browse/RHEL-21383) +- [ad_integration - feat: Add SSSD parameters support](https://issues.redhat.com/browse/RHEL-21134) +- [bootloader - Create bootloader role (MVP)](https://issues.redhat.com/browse/RHEL-3241) +- [fapolicyd - feat: Import code for fapolicyd system role](https://issues.redhat.com/browse/RHEL-16542) +- [ha_cluster - [RFE] HA Cluster system role should be able to enable Resilient Storage repository](https://issues.redhat.com/browse/RHEL-14090) +- [ha_cluster - [FutureFeature] Allow ha_cluster role to configure fencing topology](https://issues.redhat.com/browse/RHEL-4624) +- [ha_cluster - [FutureFeature] Allow ha_cluster role to configure all qdevice options](https://issues.redhat.com/browse/RHEL-3264) +- [ha_cluster - Setting cluster members attributes](https://issues.redhat.com/browse/RHEL-22108) +- [journald - feat: Add support for ForwardToSyslog](https://issues.redhat.com/browse/RHEL-21123) +- [logging - feat: Add support for the global config option preserveFQDN with a new logg…](https://issues.redhat.com/browse/RHEL-15933) +- [logging - feat: Add support for general queue and general action parameters](https://issues.redhat.com/browse/RHEL-15440) +- [metrics - [RFE] Metrics system role support for configuring PMIE webhooks](https://issues.redhat.com/browse/RHEL-18170) +- [network - Add blackhole type route](https://issues.redhat.com/browse/RHEL-21491) +- [postgresql - feat: Enable support for Postgresql 16](https://issues.redhat.com/browse/RHEL-18963) +- [rhc - support RHEL 7 managed nodes](https://issues.redhat.com/browse/RHEL-16977) +- [rhc - new rhc_insights.ansible_host parameter](https://issues.redhat.com/browse/RHEL-16975) +- [rhc - new rhc_insights.display_name parameter](https://issues.redhat.com/browse/RHEL-16965) +- [snapshot - New Role for storage snapshot management (lvm, etc.)](https://issues.redhat.com/browse/RHEL-16553) +- [sshd - ansible-sshd Manage SSH certificates](https://issues.redhat.com/browse/RHEL-5985) +- [storage - feat: Support for creating volumes without a FS](https://issues.redhat.com/browse/RHEL-16213) +- [storage - Basic support for creating shared logical volumes (RHEL 8)](https://issues.redhat.com/browse/RHEL-14022) ### Bug Fixes -- [rhc - activation key registration fails if system is already registered](https://bugzilla.redhat.com/show_bug.cgi?id=2214283) -- [rhc - system role does not apply Insights tags](https://bugzilla.redhat.com/show_bug.cgi?id=2214287) +- [ha_cluster - high-availability firewall service is not added on qdevice node](https://issues.redhat.com/browse/RHEL-17874) +- [ha_cluster - Timeout issue between SBD with delay-start and systemd unit](https://issues.redhat.com/browse/RHEL-4684) +- [kdump - fix: retry read of kexec_crash_size](https://issues.redhat.com/browse/RHEL-3354) +- [keylime_server - won't detect registrar start failure](https://issues.redhat.com/browse/RHEL-21946) +- [logging - fix: check that logging_max_message_size is set, not rsyslog_max_message_size](https://issues.redhat.com/browse/RHEL-15038) +- [nbde_server - fix: Allow tangd socket override directory to be managed outside of the role](https://issues.redhat.com/browse/RHEL-25509) +- [network - Ansible RHEL network system role issue with ipv6.routing-rules the prefix length for 'from' cannot be zero"](https://issues.redhat.com/browse/RHEL-16501) +- [podman - fix: cast secret data to string in order to allow JSON valued strings](https://issues.redhat.com/browse/RHEL-22310) +- [podman - fix: name of volume quadlet service should be basename-volume.service](https://issues.redhat.com/browse/RHEL-21402) +- [podman - fix: add no_log: true for tasks that can log secret data](https://issues.redhat.com/browse/RHEL-19242) +- [podman - fix: user linger needed before secrets](https://issues.redhat.com/browse/RHEL-22229) +- [postgresql - PostgreSQL system role: unable to install PostgreSQL version 15 on RHEL 9](https://issues.redhat.com/browse/RHEL-21400) +- [selinux - fix: Use `ignore_selinux_state` module option](https://issues.redhat.com/browse/RHEL-15871) +- [selinux - fix: Print an error message when module to be created doesn't exist](https://issues.redhat.com/browse/RHEL-19044) +- [selinux - fix: no longer use "item" as a loop variable](https://issues.redhat.com/browse/RHEL-19042) + +[1.22.0] - 2023-08-15 +---------------------------- + +### New Features + +- [ALL - fingerprint in config files managed by roles](https://bugzilla.redhat.com/show_bug.cgi?id=2186910) +- [ad_integration - add ad_integration_force_rejoin](https://bugzilla.redhat.com/show_bug.cgi?id=2211723) +- [certificate - add mode parameter to change permissions for cert files](https://bugzilla.redhat.com/show_bug.cgi?id=2218204) +- [firewall - missing module in linux-system-roles.firewall to create an ipset](https://bugzilla.redhat.com/show_bug.cgi?id=2140880) +- [firewall - fix: reload on resetting to defaults](https://bugzilla.redhat.com/show_bug.cgi?id=2224648) +- [firewall - should have option to disable conflicting services](https://bugzilla.redhat.com/show_bug.cgi?id=2222809) +- [ha_cluster - Add possibility to load SBD watchdog kernel modules](https://bugzilla.redhat.com/show_bug.cgi?id=2190478) +- [ha_cluster - cluster and quorum can have distinct passwords](https://bugzilla.redhat.com/show_bug.cgi?id=2216485) +- [ha_cluster - support for resource and operation defaults](https://bugzilla.redhat.com/show_bug.cgi?id=2190483) +- [kdump - support auto_reset_crashkernel, dracut_args, deprecate /etc/sysconfig/kdump](https://bugzilla.redhat.com/show_bug.cgi?id=2211272) +- [keylime_server - system role for managing keylime servers](https://bugzilla.redhat.com/show_bug.cgi?id=2224387) +- [network - Support configuring auto-dns setting](https://bugzilla.redhat.com/show_bug.cgi?id=2211273) +- [network - Support no-aaaa DNS option](https://bugzilla.redhat.com/show_bug.cgi?id=2218595) +- [podman - allow container networking configuration](https://bugzilla.redhat.com/show_bug.cgi?id=2220963) +- [podman - support for healthchecks and healthcheck actions](https://bugzilla.redhat.com/show_bug.cgi?id=2220961) +- [podman - support quadlet units](https://bugzilla.redhat.com/show_bug.cgi?id=2220962) +- [postgresql - [RFE] system role for PostgreSQL management](https://bugzilla.redhat.com/show_bug.cgi?id=2151371) +- [rhc - implement rhc_proxy.scheme](https://bugzilla.redhat.com/show_bug.cgi?id=2211778) +- [rhc - [RFE] New role for Red Hat subscription management, insights management [rhel-8.9.0]](https://bugzilla.redhat.com/show_bug.cgi?id=2179016) +- [ssh - add ssh_backup option with default true](https://bugzilla.redhat.com/show_bug.cgi?id=2216759) +- [storage - RFE for the storage system role to support configuring the stripe size for RAID LVM volumes](https://bugzilla.redhat.com/show_bug.cgi?id=2141961) +- [storage - [RFE] user-specified mount point owner and permissions](https://bugzilla.redhat.com/show_bug.cgi?id=2181661) +- [systemd - system role for managing systemd units](https://bugzilla.redhat.com/show_bug.cgi?id=2224388) + +### Bug Fixes + +- [ALL - facts being gathered unnecessarily](https://bugzilla.redhat.com/show_bug.cgi?id=2223036) +- [ad_integration - leaks credentials when in check_mode](https://bugzilla.redhat.com/show_bug.cgi?id=2233183) +- [certificate - rhel-system-roles.certificate does not re-issue after updating key_size](https://bugzilla.redhat.com/show_bug.cgi?id=2186057) +- [firewall - fix: reload on resetting to defaults](https://bugzilla.redhat.com/show_bug.cgi?id=2224648) +- [firewall - Check mode fails with replacing previous rules](https://issues.redhat.com/browse/RHEL-899) +- [firewall - Check mode fails when creating new firewall service](https://bugzilla.redhat.com/show_bug.cgi?id=2222433) +- [firewall - Ansible RHEL firewall system role not idempotent when configuring the interface using the role in rhel9](https://issues.redhat.com/browse/RHEL-918) +- [firewall - Don't install python(3)-firewall it's a dependency of firewalld](https://bugzilla.redhat.com/show_bug.cgi?id=2216521) +- [firewall - fix: files: overwrite firewalld.conf on previous replaced](https://issues.redhat.com/browse/RHEL-1496) +- [kdump - use failure_action instead of default on EL9 and later](https://issues.redhat.com/browse/RHEL-907) +- [kdump - role: "Write new authorized_keys if needed" task idempotency issues](https://bugzilla.redhat.com/show_bug.cgi?id=2232391) +- [kdump - system role fails if kdump_ssh_user doesn't have a .ssh/authorized_keys file in home directory](https://bugzilla.redhat.com/show_bug.cgi?id=2232392) +- [kdump - fix: ensure .ssh directory exists for kdump_ssh_user on kdump_ssh_server](https://issues.redhat.com/browse/RHEL-1398) +- [kdump - fix: Ensure authorized_keys management works with multiple hosts](https://issues.redhat.com/browse/RHEL-1500) +- [podman - Podman system role: Unable to use podman_registries_conf to set unqualified-search-registries](https://bugzilla.redhat.com/show_bug.cgi?id=2226077) +- [rhc - system role does not apply Insights tags](https://bugzilla.redhat.com/show_bug.cgi?id=2209441) +- [storage - Cannot set chunk size for RAID: Unsupported parameters for (blivet) module: pools.raid_chunk_size](https://bugzilla.redhat.com/show_bug.cgi?id=2193057) +- [storage - RAID volume pre cleanup - remove existing data from member disks as needed before creation](https://bugzilla.redhat.com/show_bug.cgi?id=2224094) +- [storage - Storage: mounted devices that are in use cannot be resized](https://bugzilla.redhat.com/show_bug.cgi?id=2168738) +- [storage - fix: use stat.pw_name, stat.gr_name instead of owner, group](https://issues.redhat.com/browse/RHEL-1498) +- [tlog - use the proxy provider - the files provider is deprecated in sssd](https://bugzilla.redhat.com/show_bug.cgi?id=2191702) [1.21.1] - 2023-03-16 ---------------------------- diff --git a/SOURCES/ansible-packaging.inc b/SOURCES/ansible-packaging.inc new file mode 100644 index 0000000..7cdb972 --- /dev/null +++ b/SOURCES/ansible-packaging.inc @@ -0,0 +1,21 @@ +# Helper macros originally from macros.ansible by Igor Raits +# This file is for maintaining the compatibility with macros and other +# functionality (generators) provided by ansible-packaging on Fedora. + +Provides: ansible-collection(%{collection_namespace}.%{collection_name}) = %{collection_version} + +# ansible-galaxy is available by ansible-core on RHEL 8.6 and newer at buildtime. +%define ansible_collection_build() ansible-galaxy collection build +%define ansible_collection_install() ansible-galaxy collection install -n -p %{buildroot}%{_datadir}/ansible/collections %{collection_namespace}-%{collection_name}-%{version}.tar.gz + +%define ansible_roles_dir %{_datadir}/ansible/roles +%define ansible_collections_dir %{_datadir}/ansible/collections/ansible_collections + +# TODO: Officially deprecate this macro and add the following line to the macro +# def after the new approach has gotten more testing and adoption: +# %%{warn: %%{ansible_collection_files} is deprecated. Use %%files -f %%{ansible_collection_filelist} instead.} +%define ansible_collection_files %{shrink: +%{ansible_collections_dir}/%{collection_namespace}/ +} + +%define ansible_collection_filelist %{__ansible_builddir}/ansible_collection_files diff --git a/SOURCES/extrasources.inc b/SOURCES/extrasources.inc index d2d3175..d056b78 100644 --- a/SOURCES/extrasources.inc +++ b/SOURCES/extrasources.inc @@ -1,10 +1,10 @@ -Source801: https://galaxy.ansible.com/download/ansible-posix-1.5.1.tar.gz -Source901: https://galaxy.ansible.com/download/community-general-6.4.0.tar.gz -Source902: https://galaxy.ansible.com/download/containers-podman-1.10.1.tar.gz +Source801: https://galaxy.ansible.com/download/ansible-posix-1.5.4.tar.gz +Source901: https://galaxy.ansible.com/download/community-general-8.3.0.tar.gz +Source902: https://galaxy.ansible.com/download/containers-podman-1.12.0.tar.gz -Provides: bundled(ansible-collection(ansible.posix)) = 1.5.1 -Provides: bundled(ansible-collection(community.general)) = 6.4.0 -Provides: bundled(ansible-collection(containers.podman)) = 1.10.1 +Provides: bundled(ansible-collection(ansible.posix)) = 1.5.4 +Provides: bundled(ansible-collection(community.general)) = 8.3.0 +Provides: bundled(ansible-collection(containers.podman)) = 1.12.0 Source996: CHANGELOG.rst Source998: collection_readme.sh diff --git a/SOURCES/redhat_subscription.py b/SOURCES/redhat_subscription.py deleted file mode 100644 index 2995e5a..0000000 --- a/SOURCES/redhat_subscription.py +++ /dev/null @@ -1,1187 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright (c) James Laska (jlaska@redhat.com) -# -# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) -# SPDX-License-Identifier: GPL-3.0-or-later - -from __future__ import absolute_import, division, print_function -__metaclass__ = type - - -DOCUMENTATION = ''' ---- -module: redhat_subscription -short_description: Manage registration and subscriptions to RHSM using C(subscription-manager) -description: - - Manage registration and subscription to the Red Hat Subscription Management entitlement platform using the C(subscription-manager) command, - registering using D-Bus if possible. -author: "Barnaby Court (@barnabycourt)" -notes: - - In order to register a system, subscription-manager requires either a username and password, or an activationkey and an Organization ID. - - Since 2.5 values for I(server_hostname), I(server_insecure), I(rhsm_baseurl), - I(server_proxy_hostname), I(server_proxy_port), I(server_proxy_user) and - I(server_proxy_password) are no longer taken from the C(/etc/rhsm/rhsm.conf) - config file and default to None. -requirements: - - subscription-manager - - Optionally the C(dbus) Python library; this is usually included in the OS - as it is used by C(subscription-manager). -extends_documentation_fragment: - - community.general.attributes -attributes: - check_mode: - support: none - diff_mode: - support: none -options: - state: - description: - - whether to register and subscribe (C(present)), or unregister (C(absent)) a system - choices: [ "present", "absent" ] - default: "present" - type: str - username: - description: - - access.redhat.com or Red Hat Satellite or Katello username - type: str - password: - description: - - access.redhat.com or Red Hat Satellite or Katello password - type: str - token: - description: - - sso.redhat.com API access token. - type: str - version_added: 6.3.0 - server_hostname: - description: - - Specify an alternative Red Hat Subscription Management or Red Hat Satellite or Katello server - type: str - server_insecure: - description: - - Enable or disable https server certificate verification when connecting to C(server_hostname) - type: str - server_prefix: - description: - - Specify the prefix when registering to the Red Hat Subscription Management or Red Hat Satellite or Katello server. - type: str - version_added: 3.3.0 - server_port: - description: - - Specify the port when registering to the Red Hat Subscription Management or Red Hat Satellite or Katello server. - type: str - version_added: 3.3.0 - rhsm_baseurl: - description: - - Specify CDN baseurl - type: str - rhsm_repo_ca_cert: - description: - - Specify an alternative location for a CA certificate for CDN - type: str - server_proxy_hostname: - description: - - Specify an HTTP proxy hostname. - type: str - server_proxy_scheme: - description: - - Specify an HTTP proxy scheme, for example C(http) or C(https). - type: str - version_added: 6.2.0 - server_proxy_port: - description: - - Specify an HTTP proxy port. - type: str - server_proxy_user: - description: - - Specify a user for HTTP proxy with basic authentication - type: str - server_proxy_password: - description: - - Specify a password for HTTP proxy with basic authentication - type: str - auto_attach: - description: - - Upon successful registration, auto-consume available subscriptions - - Added in favor of deprecated autosubscribe in 2.5. - type: bool - aliases: [autosubscribe] - activationkey: - description: - - supply an activation key for use with registration - type: str - org_id: - description: - - Organization ID to use in conjunction with activationkey - type: str - environment: - description: - - Register with a specific environment in the destination org. Used with Red Hat Satellite or Katello - type: str - pool: - description: - - | - Specify a subscription pool name to consume. Regular expressions accepted. Use I(pool_ids) instead if - possible, as it is much faster. Mutually exclusive with I(pool_ids). - default: '^$' - type: str - pool_ids: - description: - - | - Specify subscription pool IDs to consume. Prefer over I(pool) when possible as it is much faster. - A pool ID may be specified as a C(string) - just the pool ID (ex. C(0123456789abcdef0123456789abcdef)), - or as a C(dict) with the pool ID as the key, and a quantity as the value (ex. - C(0123456789abcdef0123456789abcdef: 2). If the quantity is provided, it is used to consume multiple - entitlements from a pool (the pool must support this). Mutually exclusive with I(pool). - default: [] - type: list - elements: raw - consumer_type: - description: - - The type of unit to register, defaults to system - type: str - consumer_name: - description: - - Name of the system to register, defaults to the hostname - type: str - consumer_id: - description: - - | - References an existing consumer ID to resume using a previous registration - for this system. If the system's identity certificate is lost or corrupted, - this option allows it to resume using its previous identity and subscriptions. - The default is to not specify a consumer ID so a new ID is created. - type: str - force_register: - description: - - Register the system even if it is already registered - type: bool - default: false - release: - description: - - Set a release version - type: str - syspurpose: - description: - - Set syspurpose attributes in file C(/etc/rhsm/syspurpose/syspurpose.json) - and synchronize these attributes with RHSM server. Syspurpose attributes help attach - the most appropriate subscriptions to the system automatically. When C(syspurpose.json) file - already contains some attributes, then new attributes overwrite existing attributes. - When some attribute is not listed in the new list of attributes, the existing - attribute will be removed from C(syspurpose.json) file. Unknown attributes are ignored. - type: dict - suboptions: - usage: - description: Syspurpose attribute usage - type: str - role: - description: Syspurpose attribute role - type: str - service_level_agreement: - description: Syspurpose attribute service_level_agreement - type: str - addons: - description: Syspurpose attribute addons - type: list - elements: str - sync: - description: - - When this option is true, then syspurpose attributes are synchronized with - RHSM server immediately. When this option is false, then syspurpose attributes - will be synchronized with RHSM server by rhsmcertd daemon. - type: bool - default: false -''' - -EXAMPLES = ''' -- name: Register as user (joe_user) with password (somepass) and auto-subscribe to available content. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - auto_attach: true - -- name: Same as above but subscribe to a specific pool by ID. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - pool_ids: 0123456789abcdef0123456789abcdef - -- name: Register and subscribe to multiple pools. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - pool_ids: - - 0123456789abcdef0123456789abcdef - - 1123456789abcdef0123456789abcdef - -- name: Same as above but consume multiple entitlements. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - pool_ids: - - 0123456789abcdef0123456789abcdef: 2 - - 1123456789abcdef0123456789abcdef: 4 - -- name: Register and pull existing system data. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - consumer_id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - -- name: Register with activationkey and consume subscriptions matching Red Hat Enterprise Server or Red Hat Virtualization - community.general.redhat_subscription: - state: present - activationkey: 1-222333444 - org_id: 222333444 - pool: '^(Red Hat Enterprise Server|Red Hat Virtualization)$' - -- name: Update the consumed subscriptions from the previous example (remove Red Hat Virtualization subscription) - community.general.redhat_subscription: - state: present - activationkey: 1-222333444 - org_id: 222333444 - pool: '^Red Hat Enterprise Server$' - -- name: Register as user credentials into given environment (against Red Hat Satellite or Katello), and auto-subscribe. - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - environment: Library - auto_attach: true - -- name: Register as user (joe_user) with password (somepass) and a specific release - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - release: 7.4 - -- name: Register as user (joe_user) with password (somepass), set syspurpose attributes and synchronize them with server - community.general.redhat_subscription: - state: present - username: joe_user - password: somepass - auto_attach: true - syspurpose: - usage: "Production" - role: "Red Hat Enterprise Server" - service_level_agreement: "Premium" - addons: - - addon1 - - addon2 - sync: true -''' - -RETURN = ''' -subscribed_pool_ids: - description: List of pool IDs to which system is now subscribed - returned: success - type: dict - sample: { - "8a85f9815ab905d3015ab928c7005de4": "1" - } -''' - -from os.path import isfile -from os import unlink -import re -import shutil -import tempfile -import json - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.common.text.converters import to_native -from ansible.module_utils.six.moves import configparser -from ansible.module_utils import distro - - -SUBMAN_CMD = None - - -class RegistrationBase(object): - - REDHAT_REPO = "/etc/yum.repos.d/redhat.repo" - - def __init__(self, module, username=None, password=None, token=None): - self.module = module - self.username = username - self.password = password - self.token = token - - def configure(self): - raise NotImplementedError("Must be implemented by a sub-class") - - def enable(self): - # Remove any existing redhat.repo - if isfile(self.REDHAT_REPO): - unlink(self.REDHAT_REPO) - - def register(self): - raise NotImplementedError("Must be implemented by a sub-class") - - def unregister(self): - raise NotImplementedError("Must be implemented by a sub-class") - - def unsubscribe(self): - raise NotImplementedError("Must be implemented by a sub-class") - - def update_plugin_conf(self, plugin, enabled=True): - plugin_conf = '/etc/yum/pluginconf.d/%s.conf' % plugin - - if isfile(plugin_conf): - tmpfd, tmpfile = tempfile.mkstemp() - shutil.copy2(plugin_conf, tmpfile) - cfg = configparser.ConfigParser() - cfg.read([tmpfile]) - - if enabled: - cfg.set('main', 'enabled', '1') - else: - cfg.set('main', 'enabled', '0') - - fd = open(tmpfile, 'w+') - cfg.write(fd) - fd.close() - self.module.atomic_move(tmpfile, plugin_conf) - - def subscribe(self, **kwargs): - raise NotImplementedError("Must be implemented by a sub-class") - - -class Rhsm(RegistrationBase): - def __init__(self, module, username=None, password=None, token=None): - RegistrationBase.__init__(self, module, username, password, token) - self.module = module - - def enable(self): - ''' - Enable the system to receive updates from subscription-manager. - This involves updating affected yum plugins and removing any - conflicting yum repositories. - ''' - RegistrationBase.enable(self) - self.update_plugin_conf('rhnplugin', False) - self.update_plugin_conf('subscription-manager', True) - - def configure(self, **kwargs): - ''' - Configure the system as directed for registration with RHSM - Raises: - * Exception - if error occurs while running command - ''' - - args = [SUBMAN_CMD, 'config'] - - # Pass supplied **kwargs as parameters to subscription-manager. Ignore - # non-configuration parameters and replace '_' with '.'. For example, - # 'server_hostname' becomes '--server.hostname'. - options = [] - for k, v in sorted(kwargs.items()): - if re.search(r'^(server|rhsm)_', k) and v is not None: - options.append('--%s=%s' % (k.replace('_', '.', 1), v)) - - # When there is nothing to configure, then it is not necessary - # to run config command, because it only returns current - # content of current configuration file - if len(options) == 0: - return - - args.extend(options) - - self.module.run_command(args, check_rc=True) - - @property - def is_registered(self): - ''' - Determine whether the current system - Returns: - * Boolean - whether the current system is currently registered to - RHSM. - ''' - - args = [SUBMAN_CMD, 'identity'] - rc, stdout, stderr = self.module.run_command(args, check_rc=False) - if rc == 0: - return True - else: - return False - - def _can_connect_to_dbus(self): - """ - Checks whether it is possible to connect to the system D-Bus bus. - - :returns: bool -- whether it is possible to connect to the system D-Bus bus. - """ - - try: - # Technically speaking, subscription-manager uses dbus-python - # as D-Bus library, so this ought to work; better be safe than - # sorry, I guess... - import dbus - except ImportError: - self.module.debug('dbus Python module not available, will use CLI') - return False - - try: - bus = dbus.SystemBus() - msg = dbus.lowlevel.SignalMessage('/', 'com.example', 'test') - bus.send_message(msg) - bus.flush() - - except dbus.exceptions.DBusException as e: - self.module.debug('Failed to connect to system D-Bus bus, will use CLI: %s' % e) - return False - - self.module.debug('Verified system D-Bus bus as usable') - return True - - def register(self, username, password, token, auto_attach, activationkey, org_id, - consumer_type, consumer_name, consumer_id, force_register, environment, - release): - ''' - Register the current system to the provided RHSM or Red Hat Satellite - or Katello server - - Raises: - * Exception - if any error occurs during the registration - ''' - # There is no support for token-based registration in the D-Bus API - # of rhsm, so always use the CLI in that case. - if not token and self._can_connect_to_dbus(): - self._register_using_dbus(username, password, auto_attach, - activationkey, org_id, consumer_type, - consumer_name, consumer_id, - force_register, environment, release) - return - self._register_using_cli(username, password, token, auto_attach, - activationkey, org_id, consumer_type, - consumer_name, consumer_id, - force_register, environment, release) - - def _register_using_cli(self, username, password, token, auto_attach, - activationkey, org_id, consumer_type, consumer_name, - consumer_id, force_register, environment, release): - ''' - Register using the 'subscription-manager' command - - Raises: - * Exception - if error occurs while running command - ''' - args = [SUBMAN_CMD, 'register'] - - # Generate command arguments - if force_register: - args.extend(['--force']) - - if org_id: - args.extend(['--org', org_id]) - - if auto_attach: - args.append('--auto-attach') - - if consumer_type: - args.extend(['--type', consumer_type]) - - if consumer_name: - args.extend(['--name', consumer_name]) - - if consumer_id: - args.extend(['--consumerid', consumer_id]) - - if environment: - args.extend(['--environment', environment]) - - if activationkey: - args.extend(['--activationkey', activationkey]) - elif token: - args.extend(['--token', token]) - else: - if username: - args.extend(['--username', username]) - if password: - args.extend(['--password', password]) - - if release: - args.extend(['--release', release]) - - rc, stderr, stdout = self.module.run_command(args, check_rc=True, expand_user_and_vars=False) - - def _register_using_dbus(self, username, password, auto_attach, - activationkey, org_id, consumer_type, consumer_name, - consumer_id, force_register, environment, release): - ''' - Register using D-Bus (connecting to the rhsm service) - - Raises: - * Exception - if error occurs during the D-Bus communication - ''' - import dbus - - SUBSCRIPTION_MANAGER_LOCALE = 'C' - # Seconds to wait for Registration to complete over DBus; - # 10 minutes should be a pretty generous timeout. - REGISTRATION_TIMEOUT = 600 - - def str2int(s, default=0): - try: - return int(s) - except ValueError: - return default - - distro_id = distro.id() - distro_version = tuple(str2int(p) for p in distro.version_parts()) - - # Stop the rhsm service when using systemd (which means Fedora or - # RHEL 7+): this is because the service may not use new configuration bits - # - with subscription-manager < 1.26.5-1 (in RHEL < 8.2); - # fixed later by https://github.com/candlepin/subscription-manager/pull/2175 - # - sporadically: https://bugzilla.redhat.com/show_bug.cgi?id=2049296 - if distro_id == 'fedora' or distro_version[0] >= 7: - cmd = ['systemctl', 'stop', 'rhsm'] - self.module.run_command(cmd, check_rc=True, expand_user_and_vars=False) - - # While there is a 'force' options for the registration, it is actually - # not implemented (and thus it does not work) - # - in RHEL 7 and earlier - # - in RHEL 8 before 8.8: https://bugzilla.redhat.com/show_bug.cgi?id=2118486 - # - in RHEL 9 before 9.2: https://bugzilla.redhat.com/show_bug.cgi?id=2121350 - # Hence, use it only when implemented, manually unregistering otherwise. - # Match it on RHEL, since we know about it; other distributions - # will need their own logic. - dbus_force_option_works = False - if (distro_id == 'rhel' and - ((distro_version[0] == 8 and distro_version[1] >= 8) or - (distro_version[0] == 9 and distro_version[1] >= 2) or - distro_version[0] > 9)): - dbus_force_option_works = True - - if force_register and not dbus_force_option_works: - self.unregister() - - register_opts = {} - if consumer_type: - register_opts['consumer_type'] = consumer_type - if consumer_name: - register_opts['name'] = consumer_name - if consumer_id: - register_opts['consumerid'] = consumer_id - if environment: - # The option for environments used to be 'environment' in versions - # of RHEL before 8.6, and then it changed to 'environments'; since - # the Register*() D-Bus functions reject unknown options, we have - # to pass the right option depending on the version -- funky. - environment_key = 'environment' - if distro_id == 'fedora' or \ - (distro_id == 'rhel' and - ((distro_version[0] == 8 and distro_version[1] >= 6) or - distro_version[0] >= 9)): - environment_key = 'environments' - register_opts[environment_key] = environment - if force_register and dbus_force_option_works: - register_opts['force'] = True - # Wrap it as proper D-Bus dict - register_opts = dbus.Dictionary(register_opts, signature='sv', variant_level=1) - - connection_opts = {} - # Wrap it as proper D-Bus dict - connection_opts = dbus.Dictionary(connection_opts, signature='sv', variant_level=1) - - bus = dbus.SystemBus() - register_server = bus.get_object('com.redhat.RHSM1', - '/com/redhat/RHSM1/RegisterServer') - address = register_server.Start( - SUBSCRIPTION_MANAGER_LOCALE, - dbus_interface='com.redhat.RHSM1.RegisterServer', - ) - - try: - # Use the private bus to register the system - self.module.debug('Connecting to the private DBus') - private_bus = dbus.connection.Connection(address) - - try: - if activationkey: - args = ( - org_id, - [activationkey], - register_opts, - connection_opts, - SUBSCRIPTION_MANAGER_LOCALE, - ) - private_bus.call_blocking( - 'com.redhat.RHSM1', - '/com/redhat/RHSM1/Register', - 'com.redhat.RHSM1.Register', - 'RegisterWithActivationKeys', - 'sasa{sv}a{sv}s', - args, - timeout=REGISTRATION_TIMEOUT, - ) - else: - args = ( - org_id or '', - username, - password, - register_opts, - connection_opts, - SUBSCRIPTION_MANAGER_LOCALE, - ) - private_bus.call_blocking( - 'com.redhat.RHSM1', - '/com/redhat/RHSM1/Register', - 'com.redhat.RHSM1.Register', - 'Register', - 'sssa{sv}a{sv}s', - args, - timeout=REGISTRATION_TIMEOUT, - ) - - except dbus.exceptions.DBusException as e: - # Sometimes we get NoReply but the registration has succeeded. - # Check the registration status before deciding if this is an error. - if e.get_dbus_name() == 'org.freedesktop.DBus.Error.NoReply': - if not self.is_registered(): - # Host is not registered so re-raise the error - raise - else: - raise - # Host was registered so continue - finally: - # Always shut down the private bus - self.module.debug('Shutting down private DBus instance') - register_server.Stop( - SUBSCRIPTION_MANAGER_LOCALE, - dbus_interface='com.redhat.RHSM1.RegisterServer', - ) - - # Make sure to refresh all the local data: this will fetch all the - # certificates, update redhat.repo, etc. - self.module.run_command([SUBMAN_CMD, 'refresh'], - check_rc=True, expand_user_and_vars=False) - - if auto_attach: - args = [SUBMAN_CMD, 'attach', '--auto'] - self.module.run_command(args, check_rc=True, expand_user_and_vars=False) - - # There is no support for setting the release via D-Bus, so invoke - # the CLI for this. - if release: - args = [SUBMAN_CMD, 'release', '--set', release] - self.module.run_command(args, check_rc=True, expand_user_and_vars=False) - - def unsubscribe(self, serials=None): - ''' - Unsubscribe a system from subscribed channels - Args: - serials(list or None): list of serials to unsubscribe. If - serials is none or an empty list, then - all subscribed channels will be removed. - Raises: - * Exception - if error occurs while running command - ''' - items = [] - if serials is not None and serials: - items = ["--serial=%s" % s for s in serials] - if serials is None: - items = ["--all"] - - if items: - args = [SUBMAN_CMD, 'remove'] + items - rc, stderr, stdout = self.module.run_command(args, check_rc=True) - return serials - - def unregister(self): - ''' - Unregister a currently registered system - Raises: - * Exception - if error occurs while running command - ''' - args = [SUBMAN_CMD, 'unregister'] - rc, stderr, stdout = self.module.run_command(args, check_rc=True) - self.update_plugin_conf('rhnplugin', False) - self.update_plugin_conf('subscription-manager', False) - - def subscribe(self, regexp): - ''' - Subscribe current system to available pools matching the specified - regular expression. It matches regexp against available pool ids first. - If any pool ids match, subscribe to those pools and return. - - If no pool ids match, then match regexp against available pool product - names. Note this can still easily match many many pools. Then subscribe - to those pools. - - Since a pool id is a more specific match, we only fallback to matching - against names if we didn't match pool ids. - - Raises: - * Exception - if error occurs while running command - ''' - # See https://github.com/ansible/ansible/issues/19466 - - # subscribe to pools whose pool id matches regexp (and only the pool id) - subscribed_pool_ids = self.subscribe_pool(regexp) - - # If we found any matches, we are done - # Don't attempt to match pools by product name - if subscribed_pool_ids: - return subscribed_pool_ids - - # We didn't match any pool ids. - # Now try subscribing to pools based on product name match - # Note: This can match lots of product names. - subscribed_by_product_pool_ids = self.subscribe_product(regexp) - if subscribed_by_product_pool_ids: - return subscribed_by_product_pool_ids - - # no matches - return [] - - def subscribe_by_pool_ids(self, pool_ids): - """ - Try to subscribe to the list of pool IDs - """ - available_pools = RhsmPools(self.module) - - available_pool_ids = [p.get_pool_id() for p in available_pools] - - for pool_id, quantity in sorted(pool_ids.items()): - if pool_id in available_pool_ids: - args = [SUBMAN_CMD, 'attach', '--pool', pool_id] - if quantity is not None: - args.extend(['--quantity', to_native(quantity)]) - rc, stderr, stdout = self.module.run_command(args, check_rc=True) - else: - self.module.fail_json(msg='Pool ID: %s not in list of available pools' % pool_id) - return pool_ids - - def subscribe_pool(self, regexp): - ''' - Subscribe current system to available pools matching the specified - regular expression - Raises: - * Exception - if error occurs while running command - ''' - - # Available pools ready for subscription - available_pools = RhsmPools(self.module) - - subscribed_pool_ids = [] - for pool in available_pools.filter_pools(regexp): - pool.subscribe() - subscribed_pool_ids.append(pool.get_pool_id()) - return subscribed_pool_ids - - def subscribe_product(self, regexp): - ''' - Subscribe current system to available pools matching the specified - regular expression - Raises: - * Exception - if error occurs while running command - ''' - - # Available pools ready for subscription - available_pools = RhsmPools(self.module) - - subscribed_pool_ids = [] - for pool in available_pools.filter_products(regexp): - pool.subscribe() - subscribed_pool_ids.append(pool.get_pool_id()) - return subscribed_pool_ids - - def update_subscriptions(self, regexp): - changed = False - consumed_pools = RhsmPools(self.module, consumed=True) - pool_ids_to_keep = [p.get_pool_id() for p in consumed_pools.filter_pools(regexp)] - pool_ids_to_keep.extend([p.get_pool_id() for p in consumed_pools.filter_products(regexp)]) - - serials_to_remove = [p.Serial for p in consumed_pools if p.get_pool_id() not in pool_ids_to_keep] - serials = self.unsubscribe(serials=serials_to_remove) - - subscribed_pool_ids = self.subscribe(regexp) - - if subscribed_pool_ids or serials: - changed = True - return {'changed': changed, 'subscribed_pool_ids': subscribed_pool_ids, - 'unsubscribed_serials': serials} - - def update_subscriptions_by_pool_ids(self, pool_ids): - changed = False - consumed_pools = RhsmPools(self.module, consumed=True) - - existing_pools = {} - serials_to_remove = [] - for p in consumed_pools: - pool_id = p.get_pool_id() - quantity_used = p.get_quantity_used() - existing_pools[pool_id] = quantity_used - - quantity = pool_ids.get(pool_id, 0) - if quantity is not None and quantity != quantity_used: - serials_to_remove.append(p.Serial) - - serials = self.unsubscribe(serials=serials_to_remove) - - missing_pools = {} - for pool_id, quantity in sorted(pool_ids.items()): - quantity_used = existing_pools.get(pool_id, 0) - if quantity is None and quantity_used == 0 or quantity not in (None, 0, quantity_used): - missing_pools[pool_id] = quantity - - self.subscribe_by_pool_ids(missing_pools) - - if missing_pools or serials: - changed = True - return {'changed': changed, 'subscribed_pool_ids': list(missing_pools.keys()), - 'unsubscribed_serials': serials} - - def sync_syspurpose(self): - """ - Try to synchronize syspurpose attributes with server - """ - args = [SUBMAN_CMD, 'status'] - rc, stdout, stderr = self.module.run_command(args, check_rc=False) - - -class RhsmPool(object): - ''' - Convenience class for housing subscription information - ''' - - def __init__(self, module, **kwargs): - self.module = module - for k, v in kwargs.items(): - setattr(self, k, v) - - def __str__(self): - return str(self.__getattribute__('_name')) - - def get_pool_id(self): - return getattr(self, 'PoolId', getattr(self, 'PoolID')) - - def get_quantity_used(self): - return int(getattr(self, 'QuantityUsed')) - - def subscribe(self): - args = "subscription-manager attach --pool %s" % self.get_pool_id() - rc, stdout, stderr = self.module.run_command(args, check_rc=True) - if rc == 0: - return True - else: - return False - - -class RhsmPools(object): - """ - This class is used for manipulating pools subscriptions with RHSM - """ - - def __init__(self, module, consumed=False): - self.module = module - self.products = self._load_product_list(consumed) - - def __iter__(self): - return self.products.__iter__() - - def _load_product_list(self, consumed=False): - """ - Loads list of all available or consumed pools for system in data structure - - Args: - consumed(bool): if True list consumed pools, else list available pools (default False) - """ - args = "subscription-manager list" - if consumed: - args += " --consumed" - else: - args += " --available" - lang_env = dict(LANG='C', LC_ALL='C', LC_MESSAGES='C') - rc, stdout, stderr = self.module.run_command(args, check_rc=True, environ_update=lang_env) - - products = [] - for line in stdout.split('\n'): - # Remove leading+trailing whitespace - line = line.strip() - # An empty line implies the end of a output group - if len(line) == 0: - continue - # If a colon ':' is found, parse - elif ':' in line: - (key, value) = line.split(':', 1) - key = key.strip().replace(" ", "") # To unify - value = value.strip() - if key in ['ProductName', 'SubscriptionName']: - # Remember the name for later processing - products.append(RhsmPool(self.module, _name=value, key=value)) - elif products: - # Associate value with most recently recorded product - products[-1].__setattr__(key, value) - # FIXME - log some warning? - # else: - # warnings.warn("Unhandled subscription key/value: %s/%s" % (key,value)) - return products - - def filter_pools(self, regexp='^$'): - ''' - Return a list of RhsmPools whose pool id matches the provided regular expression - ''' - r = re.compile(regexp) - for product in self.products: - if r.search(product.get_pool_id()): - yield product - - def filter_products(self, regexp='^$'): - ''' - Return a list of RhsmPools whose product name matches the provided regular expression - ''' - r = re.compile(regexp) - for product in self.products: - if r.search(product._name): - yield product - - -class SysPurpose(object): - """ - This class is used for reading and writing to syspurpose.json file - """ - - SYSPURPOSE_FILE_PATH = "/etc/rhsm/syspurpose/syspurpose.json" - - ALLOWED_ATTRIBUTES = ['role', 'usage', 'service_level_agreement', 'addons'] - - def __init__(self, path=None): - """ - Initialize class used for reading syspurpose json file - """ - self.path = path or self.SYSPURPOSE_FILE_PATH - - def update_syspurpose(self, new_syspurpose): - """ - Try to update current syspurpose with new attributes from new_syspurpose - """ - syspurpose = {} - syspurpose_changed = False - for key, value in new_syspurpose.items(): - if key in self.ALLOWED_ATTRIBUTES: - if value is not None: - syspurpose[key] = value - elif key == 'sync': - pass - else: - raise KeyError("Attribute: %s not in list of allowed attributes: %s" % - (key, self.ALLOWED_ATTRIBUTES)) - current_syspurpose = self._read_syspurpose() - if current_syspurpose != syspurpose: - syspurpose_changed = True - # Update current syspurpose with new values - current_syspurpose.update(syspurpose) - # When some key is not listed in new syspurpose, then delete it from current syspurpose - # and ignore custom attributes created by user (e.g. "foo": "bar") - for key in list(current_syspurpose): - if key in self.ALLOWED_ATTRIBUTES and key not in syspurpose: - del current_syspurpose[key] - self._write_syspurpose(current_syspurpose) - return syspurpose_changed - - def _write_syspurpose(self, new_syspurpose): - """ - This function tries to update current new_syspurpose attributes to - json file. - """ - with open(self.path, "w") as fp: - fp.write(json.dumps(new_syspurpose, indent=2, ensure_ascii=False, sort_keys=True)) - - def _read_syspurpose(self): - """ - Read current syspurpuse from json file. - """ - current_syspurpose = {} - try: - with open(self.path, "r") as fp: - content = fp.read() - except IOError: - pass - else: - current_syspurpose = json.loads(content) - return current_syspurpose - - -def main(): - - # Load RHSM configuration from file - rhsm = Rhsm(None) - - # Note: the default values for parameters are: - # 'type': 'str', 'default': None, 'required': False - # So there is no need to repeat these values for each parameter. - module = AnsibleModule( - argument_spec={ - 'state': {'default': 'present', 'choices': ['present', 'absent']}, - 'username': {}, - 'password': {'no_log': True}, - 'token': {'no_log': True}, - 'server_hostname': {}, - 'server_insecure': {}, - 'server_prefix': {}, - 'server_port': {}, - 'rhsm_baseurl': {}, - 'rhsm_repo_ca_cert': {}, - 'auto_attach': {'aliases': ['autosubscribe'], 'type': 'bool'}, - 'activationkey': {'no_log': True}, - 'org_id': {}, - 'environment': {}, - 'pool': {'default': '^$'}, - 'pool_ids': {'default': [], 'type': 'list', 'elements': 'raw'}, - 'consumer_type': {}, - 'consumer_name': {}, - 'consumer_id': {}, - 'force_register': {'default': False, 'type': 'bool'}, - 'server_proxy_hostname': {}, - 'server_proxy_scheme': {}, - 'server_proxy_port': {}, - 'server_proxy_user': {}, - 'server_proxy_password': {'no_log': True}, - 'release': {}, - 'syspurpose': { - 'type': 'dict', - 'options': { - 'role': {}, - 'usage': {}, - 'service_level_agreement': {}, - 'addons': {'type': 'list', 'elements': 'str'}, - 'sync': {'type': 'bool', 'default': False} - } - } - }, - required_together=[['username', 'password'], - ['server_proxy_hostname', 'server_proxy_port'], - ['server_proxy_user', 'server_proxy_password']], - mutually_exclusive=[['activationkey', 'username'], - ['activationkey', 'token'], - ['token', 'username'], - ['activationkey', 'consumer_id'], - ['activationkey', 'environment'], - ['activationkey', 'auto_attach'], - ['pool', 'pool_ids']], - required_if=[['state', 'present', ['username', 'activationkey', 'token'], True]], - ) - - rhsm.module = module - state = module.params['state'] - username = module.params['username'] - password = module.params['password'] - token = module.params['token'] - server_hostname = module.params['server_hostname'] - server_insecure = module.params['server_insecure'] - server_prefix = module.params['server_prefix'] - server_port = module.params['server_port'] - rhsm_baseurl = module.params['rhsm_baseurl'] - rhsm_repo_ca_cert = module.params['rhsm_repo_ca_cert'] - auto_attach = module.params['auto_attach'] - activationkey = module.params['activationkey'] - org_id = module.params['org_id'] - if activationkey and not org_id: - module.fail_json(msg='org_id is required when using activationkey') - environment = module.params['environment'] - pool = module.params['pool'] - pool_ids = {} - for value in module.params['pool_ids']: - if isinstance(value, dict): - if len(value) != 1: - module.fail_json(msg='Unable to parse pool_ids option.') - pool_id, quantity = list(value.items())[0] - else: - pool_id, quantity = value, None - pool_ids[pool_id] = quantity - consumer_type = module.params["consumer_type"] - consumer_name = module.params["consumer_name"] - consumer_id = module.params["consumer_id"] - force_register = module.params["force_register"] - server_proxy_hostname = module.params['server_proxy_hostname'] - server_proxy_port = module.params['server_proxy_port'] - server_proxy_user = module.params['server_proxy_user'] - server_proxy_password = module.params['server_proxy_password'] - release = module.params['release'] - syspurpose = module.params['syspurpose'] - - global SUBMAN_CMD - SUBMAN_CMD = module.get_bin_path('subscription-manager', True) - - syspurpose_changed = False - if syspurpose is not None: - try: - syspurpose_changed = SysPurpose().update_syspurpose(syspurpose) - except Exception as err: - module.fail_json(msg="Failed to update syspurpose attributes: %s" % to_native(err)) - - # Ensure system is registered - if state == 'present': - - # Register system - if rhsm.is_registered and not force_register: - if syspurpose and 'sync' in syspurpose and syspurpose['sync'] is True: - try: - rhsm.sync_syspurpose() - except Exception as e: - module.fail_json(msg="Failed to synchronize syspurpose attributes: %s" % to_native(e)) - if pool != '^$' or pool_ids: - try: - if pool_ids: - result = rhsm.update_subscriptions_by_pool_ids(pool_ids) - else: - result = rhsm.update_subscriptions(pool) - except Exception as e: - module.fail_json(msg="Failed to update subscriptions for '%s': %s" % (server_hostname, to_native(e))) - else: - module.exit_json(**result) - else: - if syspurpose_changed is True: - module.exit_json(changed=True, msg="Syspurpose attributes changed.") - else: - module.exit_json(changed=False, msg="System already registered.") - else: - try: - rhsm.enable() - rhsm.configure(**module.params) - rhsm.register(username, password, token, auto_attach, activationkey, org_id, - consumer_type, consumer_name, consumer_id, force_register, - environment, release) - if syspurpose and 'sync' in syspurpose and syspurpose['sync'] is True: - rhsm.sync_syspurpose() - if pool_ids: - subscribed_pool_ids = rhsm.subscribe_by_pool_ids(pool_ids) - elif pool != '^$': - subscribed_pool_ids = rhsm.subscribe(pool) - else: - subscribed_pool_ids = [] - except Exception as e: - module.fail_json(msg="Failed to register with '%s': %s" % (server_hostname, to_native(e))) - else: - module.exit_json(changed=True, - msg="System successfully registered to '%s'." % server_hostname, - subscribed_pool_ids=subscribed_pool_ids) - - # Ensure system is *not* registered - if state == 'absent': - if not rhsm.is_registered: - module.exit_json(changed=False, msg="System already unregistered.") - else: - try: - rhsm.unsubscribe() - rhsm.unregister() - except Exception as e: - module.fail_json(msg="Failed to unregister: %s" % to_native(e)) - else: - module.exit_json(changed=True, msg="System successfully unregistered from %s." % server_hostname) - - -if __name__ == '__main__': - main() diff --git a/SOURCES/vendoring-build.inc b/SOURCES/vendoring-build.inc new file mode 100644 index 0000000..9ca374d --- /dev/null +++ b/SOURCES/vendoring-build.inc @@ -0,0 +1,102 @@ +# maps the source file to the roles that use that file +# value can be string or space delimited list of strings +# role name `__collection` means - do not vendor into +# role, just vendor directly into the collection +declare -A plugin_map=( + [ansible/posix/plugins/modules/selinux.py]=selinux + [ansible/posix/plugins/modules/seboolean.py]=selinux + [ansible/posix/plugins/modules/mount.py]=storage + [ansible/posix/plugins/modules/rhel_facts.py]=__collection + [ansible/posix/plugins/modules/rhel_rpm_ostree.py]=__collection + [ansible/posix/plugins/module_utils/mount.py]=storage + [community/general/plugins/modules/ini_file.py]="tlog ad_integration" + [community/general/plugins/modules/modprobe.py]=ha_cluster + [community/general/plugins/modules/redhat_subscription.py]=rhc + [community/general/plugins/modules/rhsm_release.py]=rhc + [community/general/plugins/modules/rhsm_repository.py]=rhc + [community/general/plugins/modules/seport.py]=selinux + [community/general/plugins/modules/sefcontext.py]=selinux + [community/general/plugins/modules/selogin.py]=selinux + [containers/podman/plugins/modules/podman_container_info.py]=podman + [containers/podman/plugins/modules/podman_image.py]=podman + [containers/podman/plugins/modules/podman_play.py]=podman + [containers/podman/plugins/modules/podman_secret.py]=podman + [containers/podman/plugins/module_utils/podman/common.py]=podman +) + +declare -a modules mod_utils collection_plugins +declare -A dests +# vendor in plugin files - fix documentation, fragments +for src in "${!plugin_map[@]}"; do + roles="${plugin_map["$src"]}" + if [ "$roles" = __collection ]; then + collection_plugins+=("$src") + else + case "$src" in + */plugins/modules/*) srcdir=plugins/modules; subdir=library; modules+=("$src") ;; + */plugins/module_utils/*) srcdir=plugins/module_utils; mod_utils+=("$src") ;; + */plugins/action/*) srcdir=plugins/action ;; + esac + fi + for role in $roles; do + if [ "$role" = __collection ]; then + dest="%{collection_build_path}/plugins${src/#*plugins/}" + dests["$dest"]=__collection + else + case "$src" in + */plugins/module_utils/*) subdir="module_utils/${role}_lsr" ;; + esac + dest="$role/${src/#*${srcdir}/${subdir}}" + dests["$dest"]="$role" + fi + destdir="$(dirname "$dest")" + if [ ! -d "$destdir" ]; then + mkdir -p "$destdir" + fi + cp -pL ".external/$src" "$dest" + sed -e ':a;N;$!ba;s/description:\n\( *\)/description:\n\1- WARNING: Do not use this plugin directly! It is only for role internal use.\n\1/' \ + -e '/^extends_documentation_fragment:/,/^[^ -]/{/^extends/d;/^[ -]/d}' \ + -i "$dest" + done +done + +# remove the temporary .external directory after vendoring +rm -rf .external + +# fix python imports to point from the old name to the new name +for dest in "${!dests[@]}"; do + role="${dests["$dest"]}" + for module in "${modules[@]}"; do + python_name="$(dirname "$module")" + python_name="${python_name////[.]}" + sed -e "s/ansible_collections[.]${python_name}[.]/ansible.modules./" -i "$dest" + done + for mod_util in "${mod_utils[@]}"; do + # some mod_utils have subdirs, some do not + split=(${mod_util//// }) + python_name="ansible_collections[.]${split[0]}[.]${split[1]}[.]plugins[.]module_utils[.]" + sed -e "s/${python_name}/ansible.module_utils.${role}_lsr./" -i "$dest" + done + for plugin in "${collection_plugins[@]}"; do + python_name="$(dirname "$plugin")" + dest_python_name="%{collection_namespace}/%{collection_name}/plugins${python_name/#*plugins/}" + src_python_name="ansible_collections.${python_name////[.]}" + dest_python_name="ansible_collections.${dest_python_name////.}" + sed -e "s/${src_python_name}/${dest_python_name}/" -i "$dest" + done +done + +# Replacing "linux-system-roles.rolename" with "rhel-system-roles.rolename" in each role +# Replacing "fedora.linux_system_roles." with "redhat.rhel_system_roles" in each role +# This is for the "roles calling other roles" case +# for podman, change the FQCN - using a non-FQCN module name doesn't seem to work, +# even for the legacy role format +for rolename in %{rolenames}; do + find "$rolename" -type f -exec \ + sed -e "s/linux-system-roles[.]${rolename}\\>/%{roleinstprefix}${rolename}/g" \ + -e "s/fedora[.]linux_system_roles[.]/%{collection_namespace}.%{collection_name}./g" \ + -e "s/containers[.]podman[.]/%{collection_namespace}.%{collection_name}./g" \ + -e "s/community[.]general[.]/%{collection_namespace}.%{collection_name}./g" \ + -e "s/ansible[.]posix[.]/%{collection_namespace}.%{collection_name}./g" \ + -i {} \; +done diff --git a/SOURCES/vendoring-prep.inc b/SOURCES/vendoring-prep.inc new file mode 100644 index 0000000..66ea974 --- /dev/null +++ b/SOURCES/vendoring-prep.inc @@ -0,0 +1,12 @@ +# Untar vendored collection tarballs to corresponding directories +for file in %{SOURCE801} %{SOURCE901} %{SOURCE902}; do + if [[ "$(basename $file)" =~ ([^-]+)-([^-]+)-(.+).tar.gz ]]; then + ns=${BASH_REMATCH[1]} + name=${BASH_REMATCH[2]} + ver=${BASH_REMATCH[3]} + mkdir -p .external/$ns/$name + pushd .external/$ns/$name > /dev/null + tar xfz "$file" + popd > /dev/null + fi +done diff --git a/SPECS/rhel-system-roles.spec b/SPECS/rhel-system-roles.spec index 79f7066..638c43f 100644 --- a/SPECS/rhel-system-roles.spec +++ b/SPECS/rhel-system-roles.spec @@ -1,27 +1,16 @@ -# NOTE: Even though ansible-core is in 8.6, it is only available -# at *runtime*, not at *buildtime* - so we can't have -# ansible-core as a build_dep on RHEL8 -%if 0%{?fedora} || 0%{?rhel} >= 9 -%bcond_without ansible +# NOTE: ansible-core is in rhel-8.6 and newer, but not installable +# in buildroot as it depended on modular Python. +# It has been installable at buildtime in 8.8 and newer. %if 0%{?fedora} BuildRequires: ansible-packaging %else +%if 0%{?rhel} >= 8 BuildRequires: ansible-core >= 2.11.0 %endif -%else -%bcond_with ansible %endif %bcond_with collection_artifact -%if 0%{?fedora} || 0%{?rhel} >= 8 -%bcond_without html -%else -# pandoc is not supported in rhel 7 and older, -# which is needed for converting .md to .html. -%bcond_with html -%endif - %if 0%{?rhel} Name: rhel-system-roles %else @@ -29,8 +18,8 @@ Name: linux-system-roles %endif Url: https://github.com/linux-system-roles Summary: Set of interfaces for unified system management -Version: 1.21.2 -Release: 1%{?dist} +Version: 1.23.0 +Release: 2.21%{?dist} License: GPLv3+ and MIT and BSD and Python %global _pkglicensedir %{_licensedir}/%{name} @@ -44,25 +33,10 @@ License: GPLv3+ and MIT and BSD and Python %endif %global collection_version %{version} +# this is where we stage the collection files for building +%global collection_dest_path .collections +%global collection_build_path %{collection_dest_path}/ansible_collections/%{collection_namespace}/%{collection_name} -# Helper macros originally from macros.ansible by Igor Raits -# On RHEL, not available, so we must define those macros locally -# On Fedora, provided by ansible-packager -# Not used (yet). Could be made to point to AH in RHEL - but what about CentOS Stream? -#%%{!?ansible_collection_url:%%define ansible_collection_url() https://galaxy.ansible.com/%%{collection_namespace}/%%{collection_name}} -%if 0%{?rhel} -Provides: ansible-collection(%{collection_namespace}.%{collection_name}) = %{collection_version} -%global ansible_collection_files %{_datadir}/ansible/collections/ansible_collections/%{collection_namespace}/ -%define ansible_roles_dir %{_datadir}/ansible/roles -%if %{without ansible} -# Untar and copy everything instead of galaxy-installing the built artifact when ansible is not available -%define ansible_collection_build() tar -cf %{_tmppath}/%{collection_namespace}-%{collection_name}-%{version}.tar.gz . -%define ansible_collection_install() mkdir -p %{buildroot}%{ansible_collection_files}%{collection_name}; (cd %{buildroot}%{ansible_collection_files}%{collection_name}; tar -xf %{_tmppath}/%{collection_namespace}-%{collection_name}-%{version}.tar.gz) -%else -%define ansible_collection_build() ansible-galaxy collection build -%define ansible_collection_install() ansible-galaxy collection install -n -p %{buildroot}%{_datadir}/ansible/collections %{collection_namespace}-%{collection_name}-%{version}.tar.gz -%endif -%endif # be compatible with the usual Fedora Provides: Provides: ansible-collection-%{collection_namespace}-%{collection_name} = %{collection_version}-%{release} @@ -107,83 +81,101 @@ Requires: (ansible-core >= 2.11.0 or ansible >= 2.9.0) %%global rolestodir %%{?rolestodir} %%{roletodir%{1}} } -%global mainid d6a8e0167e9ed8d089093b7ead1e298241b534e1 +%global mainid 11ad785c9bb72611244e7909450ca4247e12db4d Source: %{url}/auto-maintenance/archive/%{mainid}/auto-maintenance-%{mainid}.tar.gz # BEGIN AUTOGENERATED SOURCES %global rolename1 postfix -%deftag 1 1.3.3 +%deftag 1 1.4.3 %global rolename2 selinux -%deftag 2 1.5.6 +%deftag 2 1.7.4 %global rolename3 timesync -%deftag 3 1.7.2 +%deftag 3 1.8.2 %global rolename4 kdump -%deftag 4 1.2.6 +%deftag 4 1.4.4 %global rolename5 network -%deftag 5 1.11.2 +%deftag 5 1.15.1 %global rolename6 storage -%deftag 6 1.9.6 +%deftag 6 1.16.2 %global rolename7 metrics -%deftag 7 1.8.1 +%deftag 7 1.10.1 %global rolename8 tlog -%deftag 8 1.2.11 +%deftag 8 1.3.3 %global rolename9 kernel_settings -%deftag 9 1.1.11 +%deftag 9 1.2.2 %global rolename10 logging -%deftag 10 1.11.5 +%deftag 10 1.12.4 %global rolename11 nbde_server -%deftag 11 1.3.3 +%deftag 11 1.4.3 %global rolename12 nbde_client -%deftag 12 1.2.10 +%deftag 12 1.2.17 %global rolename13 certificate -%deftag 13 1.1.9 +%deftag 13 1.3.3 %global rolename14 crypto_policies -%deftag 14 1.2.7 +%deftag 14 1.3.2 %global forgeorg15 https://github.com/willshersystems %global repo15 ansible-sshd %global rolename15 sshd -%deftag 15 v0.18.1 +%deftag 15 v0.23.2 %global rolename16 ssh -%deftag 16 1.1.12 +%deftag 16 1.3.2 %global rolename17 ha_cluster -%deftag 17 1.8.7 +%deftag 17 1.14.0 %global rolename18 vpn -%deftag 18 1.5.3 +%deftag 18 1.6.3 %global rolename19 firewall -%deftag 19 1.4.2 +%deftag 19 1.7.4 %global rolename20 cockpit -%deftag 20 1.4.3 +%deftag 20 1.5.5 %global rolename21 podman -%deftag 21 1.1.2 +%deftag 21 1.4.7 %global rolename22 ad_integration -%deftag 22 1.0.2 +%deftag 22 1.4.2 %global rolename23 rhc -%deftag 23 1.1.3 +%deftag 23 1.6.0 %global rolename24 journald -%deftag 24 1.0.0 +%deftag 24 1.2.3 + +%global rolename25 postgresql +%deftag 25 1.3.5 + +%global rolename26 systemd +%deftag 26 1.1.2 + +%global rolename27 keylime_server +%deftag 27 1.1.2 + +%global rolename28 fapolicyd +%deftag 28 1.1.1 + +%global rolename29 bootloader +%deftag 29 1.0.3 + +%global rolename30 snapshot +%deftag 30 1.3.1 Source1: %{archiveurl1} Source2: %{archiveurl2} @@ -209,32 +201,45 @@ Source21: %{archiveurl21} Source22: %{archiveurl22} Source23: %{archiveurl23} Source24: %{archiveurl24} +Source25: %{archiveurl25} +Source26: %{archiveurl26} +Source27: %{archiveurl27} +Source28: %{archiveurl28} +Source29: %{archiveurl29} +Source30: %{archiveurl30} # END AUTOGENERATED SOURCES # Includes with definitions/tags that differ between RHEL and Fedora -Source2301: redhat_subscription.py Source1001: extrasources.inc %include %{SOURCE1001} +# Includes with ansible_collection_build/_install that differ between RHEL versions +Source1002: ansible-packaging.inc + +%include %{SOURCE1002} + +Source1003: vendoring-prep.inc +Source1004: vendoring-build.inc + Source995: CHANGELOG.md BuildArch: noarch - -%if %{with html} -# Requirements for md2html.sh to build the documentation -%if 0%{?fedora} || 0%{?rhel} >= 9 -BuildRequires: rubygem-kramdown-parser-gfm -%else -BuildRequires: pandoc -BuildRequires: asciidoc -BuildRequires: highlight -%endif -%endif +# there is no ansible on i686, so when we get a builder that uses +# this arch, the build fails with +# No matching package to install: 'ansible-core >= 2.11.0' +# unfortunately, this causes the src rpm build tasks to be reported +# with the arch of the builder :-( which causes problems with internal +# test infrastructure - while we get those issues sorted out, revert +# this change - this means that centpkg builds may fail and may have +# to be retried +# ExcludeArch: i686 # Requirements for galaxy_transform.py BuildRequires: python3 BuildRequires: python%{python3_pkgversion}-ruamel-yaml +# Requirements for release_collection.py +BuildRequires: python3-setuptools # We must put %%description within the if block to avoid empty lines showing up. %if 0%{?rhel} @@ -276,23 +281,11 @@ end %prep # BEGIN AUTOGENERATED SETUP -%setup -q -a1 -a2 -a3 -a4 -a5 -a6 -a7 -a8 -a9 -a10 -a11 -a12 -a13 -a14 -a15 -a16 -a17 -a18 -a19 -a20 -a21 -a22 -a23 -a24 -n %{getarchivedir 0} +%setup -q -a1 -a2 -a3 -a4 -a5 -a6 -a7 -a8 -a9 -a10 -a11 -a12 -a13 -a14 -a15 -a16 -a17 -a18 -a19 -a20 -a21 -a22 -a23 -a24 -a25 -a26 -a27 -a28 -a29 -a30 -n %{getarchivedir 0} # END AUTOGENERATED SETUP -%if 0%{?rhel} -# Untar vendored collection tarballs to corresponding directories -for file in %{SOURCE801} %{SOURCE901} %{SOURCE902}; do - if [[ "$(basename $file)" =~ ([^-]+)-([^-]+)-(.+).tar.gz ]]; then - ns=${BASH_REMATCH[1]} - name=${BASH_REMATCH[2]} - ver=${BASH_REMATCH[3]} - mkdir -p .external/$ns/$name - pushd .external/$ns/$name > /dev/null - tar xfz "$file" - popd > /dev/null - fi -done -%endif +# vendoring prep steps, if any +%include %{SOURCE1003} declare -A ROLESTODIR=(%{rolestodir}) for rolename in %{rolenames}; do @@ -307,6 +300,8 @@ for rolename in %{rolenames}; do fi fi mv "$dir_from_archive" ${rolename} + # Move a hidden .README.html to a not hidden README.html + mv $rolename/.README.html $rolename/README.html done %if 0%{?rhel} @@ -320,11 +315,12 @@ cd ../.. cd %{rolename15} find -P tests examples -name \*.yml | while read file; do - sed -r -i -e "s/ansible-sshd/linux-system-roles.sshd/" \ + sed -r -i -e "s/willshersystems:ansible-sshd/system_role:sshd/" \ + -e "s/ansible-sshd/linux-system-roles.sshd/" \ -e "s/ willshersystems.sshd/ linux-system-roles.sshd/" "$file" done -sed -r -i -e "s/ willshersystems.sshd/ linux-system-roles.sshd/" README.md -sed -r -i -e "s/min_ansible_version: 2.8/min_ansible_version: 2.9/" meta/main.yml +sed -r -i -e "s/ willshersystems.sshd/ linux-system-roles.sshd/" README.md README.html +sed -r -i -e 's/min_ansible_version: 2.8/min_ansible_version: "2.9"/' meta/main.yml cd .. cd %{rolename7} @@ -340,110 +336,8 @@ if [ "$rolesdir" != "$realrolesdir" ]; then fi cd .. -%if 0%{?rhel} -# Unpack tar.gz to retrieve to be vendored modules and place them in the roles library. -# ansible.posix: -# - library: -# - Module selinux and seboolean for the selinux role -# - Module mount for the storage role -declare -A module_map=( ["selinux.py"]="selinux" ["seboolean.py"]="selinux" ["mount.py"]="storage" ) -for module in "${!module_map[@]}"; do - role="${module_map[${module}]}" - if [ ! -d $role/library ]; then - mkdir $role/library - fi - cp -pL .external/ansible/posix/plugins/modules/$module $role/library/$module - sed -i -e ':a;N;$!ba;s/description:\n\( *\)/description:\n\1- WARNING: Do not use this module directly! It is only for role internal use.\n\1/' -e "s/ansible_collections.ansible.posix.plugins.module_utils/ansible.module_utils.${role}_lsr/" $role/library/$module -done - -# ansible.posix: -# - module_utils: -# - Module_util mount for the storage role -module_map=( ["mount.py"]="storage" ) -for module in "${!module_map[@]}"; do - role="${module_map[${module}]}" - if [ ! -d $role/module_utils/${role}_lsr ]; then - mkdir -p $role/module_utils/${role}_lsr - fi - cp -pL .external/ansible/posix/plugins/module_utils/$module $role/module_utils/${role}_lsr/$module -done - -# community.general: -# - library: -# - Module seport, sefcontext and selogin for the selinux role rolename2 -# - Module ini_file for role tlog -# - rhc modules -module_map=( ["seport.py"]="selinux" ["sefcontext.py"]="selinux" ["selogin.py"]="selinux" ["ini_file.py"]="tlog" - ["redhat_subscription.py"]="rhc" ["rhsm_release.py"]="rhc" ["rhsm_repository.py"]="rhc" ) -for module in "${!module_map[@]}"; do - role="${module_map[${module}]}" - if [ ! -d $role/library ]; then - mkdir $role/library - fi - # version 5.x seems to be broken? - moduledir=.external/community/general/plugins/modules - if [ ! -f $moduledir/$module ]; then - moduledir=.external/community/general/plugins/modules/system - fi - if [ ! -f $moduledir/$module ]; then - moduledir=.external/community/general/plugins/modules/files - fi - cp -pL $moduledir/$module $role/library/$module - ls -alrtF $role/library/$module - sed -i -e ':a;N;$!ba;s/description:\n\( *\)/description:\n\1- WARNING: Do not use this module directly! It is only for role internal use.\n\1/' $role/library/$module -done - -# Fix until the updated redhat_subscription.py is in community.general -cp %{SOURCE2301} rhc/library/redhat_subscription.py -sed -i -e ':a;N;$!ba;s/description:\n\( *\)/description:\n\1- WARNING: Do not use this module directly! It is only for role internal use.\n\1/' rhc/library/redhat_subscription.py - -# containers.podman: -# - library: -# - Module podman_container_info, podman_image and podman_play for the podman role -module_map=( ["podman_container_info.py"]="podman" ["podman_image.py"]="podman" ["podman_play.py"]="podman" ) -for module in "${!module_map[@]}"; do - role="${module_map[${module}]}" - if [ ! -d $role/library ]; then - mkdir $role/library - fi - moduledir=.external/containers/podman/plugins/modules - cp -pL $moduledir/$module $role/library/$module - ls -alrtF $role/library/$module - sed -i -e ':a;N;$!ba;s/description:\n\( *\)/description:\n\1- WARNING: Do not use this module directly! It is only for role internal use.\n\1/' \ - -e "s/ansible_collections.containers.podman.plugins.module_utils.podman/ansible.module_utils.${role}_lsr/" \ - $role/library/$module -done - -# containers.podman: -# - module_utils: -# - Module_util common for the podman role -module_map=( ["common.py"]="podman" ) -for module in "${!module_map[@]}"; do - role="${module_map[${module}]}" - if [ ! -d $role/module_utils/${role}_lsr ]; then - mkdir -p $role/module_utils/${role}_lsr - fi - cp -pL .external/containers/podman/plugins/module_utils/podman/$module $role/module_utils/${role}_lsr/$module -done - -# remove the temporary .external directory after vendoring -rm -rf .external - -# Replacing "linux-system-roles.rolename" with "rhel-system-roles.rolename" in each role -# Replacing "fedora.linux_system_roles." with "redhat.rhel_system_roles" in each role -# This is for the "roles calling other roles" case -# for podman, change the FQCN - using a non-FQCN module name doesn't seem to work, -# even for the legacy role format -# replace community.general for rhc -for rolename in %{rolenames}; do - find $rolename -type f -exec \ - sed -e "s/linux-system-roles[.]${rolename}\\>/%{roleinstprefix}${rolename}/g" \ - -e "s/fedora[.]linux_system_roles[.]/%{collection_namespace}.%{collection_name}./g" \ - -e "s/containers[.]podman[.]/%{collection_namespace}.%{collection_name}./g" \ - -e "s/community[.]general[.]/%{collection_namespace}.%{collection_name}./g" \ - -i {} \; -done -%endif +# vendoring build steps, if any +%include %{SOURCE1004} # Removing symlinks in tests/roles for rolename in %{rolenames}; do @@ -465,29 +359,67 @@ rm %{rolename5}/tests/ensure_provider_tests.py # Drop storage tests/scripts rm -rf %{rolename6}/tests/scripts +# fix system_roles fingerprint in "external" roles +python3 lsr_fingerprint.py + # transform ambiguous #!/usr/bin/env python shebangs to python3 to stop brp-mangle-shebangs complaining find -type f -executable -name '*.py' -exec \ sed -i -r -e '1s@^(#! */usr/bin/env python)(\s|$)@#\13\2@' '{}' + %build -%if %{with html} -readmes="" -for role in %{rolenames}; do - readmes="${readmes} $role/README.md" -done -sh md2html.sh $readmes -%endif +# remove upstream-only documentation - for example, documentation +# about collection dependencies is not needed in Fedora and EL RPMs +# since the dependencies are already provided +sed -e '/# Requirements/,/^#/s/^See below$/None/' \ + -e '/# Collection requirements/,/^#/ {/# Collection requirements/d;/^#/!d}' \ + -i */README.md +sed -e '/id="requirements">Requirements<\/h/,/^/,/^/d;/^/{for(x=NR-2;x<=NR+1;x++)d[x];} \ + {a[NR]=$0} \ + END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' \ + $role/README.html > $role/README.html.tmp + mv $role/README.html.tmp $role/README.html +done + +# sshd README is not in the same format +sed -e '/# Optional requirements/,/# Role variables/ {/# Optional/d;/# Role variables/!d}' \ + -i sshd/README.md +sed -e '/id="optional-requirements">/,/^/d;/^/{for(x=NR-2;x<=NR+1;x++)d[x];} \ + {a[NR]=$0} \ + END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' \ + sshd/README.html > sshd/README.html.tml +mv sshd/README.html.tml sshd/README.html + +matchstr="actions/workflows/" +for role in %{rolenames}; do + # in the first 14 lines of README.md, remove any line that looks like a + # github action badge. README.html doesn't have these lines. + sed -e "1,14 {\\,${matchstr},d; /\!\[/d}" -i $role/README.md +done + +if [ ! -d %{collection_dest_path} ]; then + mkdir %{collection_dest_path} +fi %if 0%{?rhel} # Convert the upstream collection readme to the downstream one %{SOURCE998} lsr_role2collection/collection_readme.md -./galaxy_transform.py "%{collection_namespace}" "%{collection_name}" "%{collection_version}" \ +%{python3} ./galaxy_transform.py "%{collection_namespace}" "%{collection_name}" "%{collection_version}" \ "Red Hat Enterprise Linux System Roles Ansible Collection" \ "https://linux-system-roles.github.io" \ "https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/administration_and_configuration_tasks_using_system_roles_in_rhel" \ "https://access.redhat.com/articles/3050101" \ - "https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%20Linux%208&component=rhel-system-roles" \ + "https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&summary=Your%20request%20summary&issuetype=1&priority=10200&labels=Partner-Feature-Request&components=12380283" \ > galaxy.yml.tmp # we vendor-in all of the dependencies on rhel, so remove them rm -f lsr_role2collection/collection_requirements.txt @@ -515,39 +447,32 @@ extra_mapping="--extra-mapping fedora.linux_system_roles:%{collection_namespace} %else extra_mapping="" %endif -LANG=C.utf-8 LC_ALL=C.utf-8 python3 release_collection.py --galaxy-yml galaxy.yml \ - --src-path $(pwd) --dest-path $(pwd)/.collections $includes --force --no-update \ +LANG=C.utf-8 LC_ALL=C.utf-8 %{python3} release_collection.py --galaxy-yml galaxy.yml \ + --src-path $(pwd) --dest-path $(pwd)/%{collection_dest_path} $includes --keep --no-update \ --src-owner %{name} --skip-git --skip-check --skip-changelog $extra_mapping --debug -# Remove table of contents from logging README.md -# It is not needed for html and AH/Galaxy -sed -i -e 's/^\(## Table of Contents\)/## Background\n\1/' \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/roles/logging/README.md -sed -i -e '/^## Table of Contents/,/^## Background/d' \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/roles/logging/README.md - # Remove internal links from readme files # They are not rendered properly on AH. for role in %{rolenames}; do sed -r -i -e 's/\[([^[]+)\]\(#[^)]+\)/\1/g' \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/roles/$role/README.md + %{collection_build_path}/roles/$role/README.md done # Remove test only collection dependencies # NOTE: These should not be in meta/collection-requirements.yml, they should be # in tests/collection-requirements.yml, but they can't be moved yet sed -i -e '/community[.]mysql:/d' -e '/community[.]postgresql:/d' \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/galaxy.yml + %{collection_build_path}/galaxy.yml cp %{SOURCE995} \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/docs/CHANGELOG.md + %{collection_build_path}/docs/CHANGELOG.md %if 0%{?rhel} cp %{SOURCE996} \ - .collections/ansible_collections/%{collection_namespace}/%{collection_name}/CHANGELOG.rst + %{collection_build_path}/CHANGELOG.rst %endif # Build the collection -pushd .collections/ansible_collections/%{collection_namespace}/%{collection_name}/ +pushd %{collection_build_path} %ansible_collection_build popd @@ -574,10 +499,8 @@ for role in %{rolenames}; do "%{buildroot}%{_pkgdocdir}/$role" ln -sr "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/README.md" \ "%{buildroot}%{_pkgdocdir}/$role" -%if %{with html} ln -sr "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/README.html" \ "%{buildroot}%{_pkgdocdir}/$role" -%endif if [ -f "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/COPYING" ]; then ln -sr "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/COPYING" \ "%{buildroot}%{_pkglicensedir}/$role.COPYING" @@ -587,16 +510,20 @@ for role in %{rolenames}; do "%{buildroot}%{_pkglicensedir}/$role.LICENSE" fi if [ -d "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/examples" ]; then - for file in "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/examples/"*.yml ; do - basename=$(basename "$file" .yml) - newname="$basename" - if [[ "$newname" != example-* ]]; then - newname="example-$newname" + for file in "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/examples/"* ; do + if [[ "$file" == *.yml ]]; then + basename=$(basename "$file" .yml) + newname="$basename" + if [[ "$newname" != example-* ]]; then + newname="example-$newname" + fi + if [[ "$newname" != *-playbook ]]; then + newname="${newname}-playbook" + fi + cp "$file" "%{buildroot}%{_pkgdocdir}/$role/${newname}.yml" + else + cp "$file" "%{buildroot}%{_pkgdocdir}/$role" fi - if [[ "$newname" != *-playbook ]]; then - newname="${newname}-playbook" - fi - cp "$file" "%{buildroot}%{_pkgdocdir}/$role/${newname}.yml" rm "$file" done if [ -f "%{buildroot}%{ansible_roles_dir}/%{roleinstprefix}$role/examples/inventory" ]; then @@ -610,10 +537,16 @@ for role in %{rolenames}; do fi done -rm %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/semaphore +rm -f %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/semaphore rm -r %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/molecule -rm -r %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/.[A-Za-z]* +# remove .dot files/directories, but keep the .ostree directory +for item in %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/.[A-Za-z]*; do + if [ "$(basename "$item")" = .ostree ]; then + continue + fi + rm -r "$item" +done rm %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/tests/.git* # NOTE: sshd/examples/example-root-login.yml is @@ -621,7 +554,7 @@ rm %{buildroot}%{ansible_roles_dir}/%{roleinstprefix}*/tests/.git* # must be updated if changing the file path # Install the collection -pushd .collections/ansible_collections/%{collection_namespace}/%{collection_name}/ +pushd %{collection_build_path} %ansible_collection_install popd @@ -632,7 +565,7 @@ ln -sr %{buildroot}%{ansible_collection_files}%{collection_name}/README.md \ %{buildroot}%{_pkgdocdir}/collection for rolename in %{rolenames}; do - for file in CHANGELOG.md README.md; do + for file in CHANGELOG.md README.md README.html; do if [ -f %{buildroot}%{ansible_collection_files}%{collection_name}/roles/${rolename}/$file ]; then if [ ! -d %{buildroot}%{_pkgdocdir}/collection/roles/${rolename} ]; then mkdir -p %{buildroot}%{_pkgdocdir}/collection/roles/${rolename} @@ -643,20 +576,11 @@ for rolename in %{rolenames}; do done done -%if %{with html} -# converting README.md to README.html for collection in %%{buildroot}%%{_pkgdocdir}/collection -readmes="%{buildroot}%{_pkgdocdir}/collection/README.md" -for role in %{rolenames}; do - readmes="${readmes} %{buildroot}%{_pkgdocdir}/collection/roles/${role}/README.md" -done -sh md2html.sh $readmes -%endif - %if %{with collection_artifact} # Copy collection artifact to /usr/share/ansible/collections/ for collection-artifact -pushd .collections/ansible_collections/%{collection_namespace}/%{collection_name}/ - mv %{collection_namespace}-%{collection_name}-%{version}.tar.gz \ - %{buildroot}%{_datadir}/ansible/collections/ +pushd %{collection_build_path} +mv %{collection_namespace}-%{collection_name}-%{version}.tar.gz \ + %{buildroot}%{_datadir}/ansible/collections/ popd %endif @@ -753,9 +677,256 @@ find %{buildroot}%{ansible_roles_dir} -mindepth 1 -maxdepth 1 | \ %endif %changelog -* Mon Jun 12 2023 Rich Megginson - 1.21.2-1 -- Resolves:rhbz#2214283 : rhc - activation key registration fails if system is already registered -- Resolves:rhbz#2214287 : rhc - system role does not apply Insights tags +* Mon Feb 26 2024 Rich Megginson - 1.23.0-2.21 +- Resolves: RHEL-3241 : bootloader - Create bootloader role (MVP) + fix issue with path on arches other than x86_64, and EFI systems +- Resolves: RHEL-15872 : RHEL for Edge support in system roles + cockpit - fixed issue with test cleanup + postgresql - fixed issue with test cleanup + +* Wed Feb 21 2024 Rich Megginson - 1.23.0-2.20 +- Resolves: RHEL-16965 : rhc - new rhc_insights.display_name parameter +- Resolves: RHEL-16553 : snapshot - New Role for storage snapshot management (lvm, etc.) + fixes error handling + +* Tue Feb 20 2024 Rich Megginson - 1.23.0-2.19 +- Resolves: RHEL-16553 : snapshot - New Role for storage snapshot management (lvm, etc.) + fixes idempotency, check mode, cleanup, basic-smoke-test + +* Tue Feb 20 2024 Rich Megginson - 1.23.0-2.18 +- Resolves: RHEL-22229 : podman - user linger needed before secrets + fixed issue with ANSIBLE_GATHERING=explicit +- Resolves: RHEL-5985 ansible-sshd - Manage SSH certificates + fixed issue with RHEL7 tests + +* Thu Feb 15 2024 Rich Megginson - 1.23.0-2.17 +- Resolves: RHEL-25509 : nbde_server - fix: Allow tangd socket override directory to be managed outside of the role +- Resolves: RHEL-21491 : network - Add blackhole type route to rhel-system-roles.network +- Fixed issues with ANSIBLE_GATHERING=explicit in several roles +- Fixed test cleanup issues in several roles + +* Tue Feb 13 2024 Rich Megginson - 1.23.0-2.16 +- Resolves: RHEL-16553 : snapshot - New Role for storage snapshot management (lvm, etc.) + this is the MVP candidate for the snapshot role + +* Mon Feb 12 2024 Rich Megginson - 1.23.0-2.15 +- Resolves: RHEL-22108 : ha_cluster - Setting cluster members' attributes + +* Sun Feb 11 2024 Rich Megginson - 1.23.0-2.14 +- Resolves: RHEL-3241 : bootloader - Create bootloader role (MVP) +- Resolves: RHEL-21400 : postgresql - PostgreSQL system role: unable to install PostgreSQL version 15 on RHEL 9 + +* Fri Feb 9 2024 Rich Megginson - 1.23.0-2.13 +- Resolves: RHEL-16975 : rhc - rhc: new rhc_insights.ansible_host parameter + Rename test playbook from .yaml to .yml + +* Thu Feb 8 2024 Rich Megginson - 1.23.0-2.12 +- Resolves: RHEL-22229 : podman - user linger needed before secrets + +* Wed Jan 31 2024 Rich Megginson - 1.23.0-2.11 +- Resolves: RHEL-21400 : postgresql - PostgreSQL system role: unable to install PostgreSQL version 15 on RHEL 9 +- Resolves: RHEL-23309 : storage - tests_lvm_auto_size_cap_nvme_generated failed at "Assert expected size is actual size" + +* Sat Jan 27 2024 Rich Megginson - 1.23.0-2.10 +- Resolves: RHEL-14022 : storage - Basic support for creating shared logical volumes + GFS2 support in blivet is enabled + +* Fri Jan 26 2024 Rich Megginson - 1.23.0-2.9 +- Resolves: RHEL-21383 : ad_integration - feat: add ad_integration_preserve_authselect_profile +- Resolves: RHEL-21134 : ad_integration - feat: Add SSSD parameters support +- Resolves: RHEL-21123 : journald - feat: Add support for ForwardToSyslog +- Resolves: RHEL-22310 : podman - fix: cast secret data to string in order to allow JSON valued strings +- Resolves: RHEL-21402 : podman - fix: name of volume quadlet service should be basename-volume.service +- Resolves: RHEL-21400 : postgresql - PostgreSQL system role: unable to install PostgreSQL version 15 on RHEL 9 +- Resolves: RHEL-16975 : rhc - rhc: new rhc_insights.ansible_host parameter + +* Wed Jan 24 2024 Rich Megginson - 1.23.0-2.8 +- Resolves: RHEL-16553 : snapshot - New Role for storage snapshot management (lvm, etc.) + +* Fri Jan 19 2024 Rich Megginson - 1.23.0-2.7 +- Add ExcludeArch i686 to fix build issues with ansible-core +- Resolves: RHEL-21946 : keylime_server - won't detect registrar start failure + +* Thu Jan 18 2024 Rich Megginson - 1.23.0-2.6 +- Resolves: RHEL-21537 : storage - lvmlockd process is not running - test only + +* Mon Jan 15 2024 Rich Megginson - 1.23.0-2.5 +- Resolves: RHEL-3241 : bootloader - Create bootloader role (MVP) + +* Tue Dec 12 2023 Rich Megginson - 1.23.0-2.4 +- Resolves: RHEL-15872 : RHEL for Edge support in system roles + updated several roles with ostree improvements + metrics role support for ostree +- Resolves: RHEL-16542 : fapolicyd - feat: Import code for fapolicyd system role + several role improvements +- Resolves: RHEL-4684 : ha_cluster - fix: set sbd.service timeout based on SBD_START_DELAY +- Resolves: RHEL-19047 : logging - fix: avoid conf of RatelimitBurst when RatelimitInterval is zero +- Resolves: RHEL-18170 : metrics - [RFE] Metrics system role support for configuring PMIE webhooks +- Resolves: RHEL-19242 : podman - fix: add no_log: true for tasks that can log secret data +- Resolves: RHEL-18963 : postgresql - feat: enable using postgresql 16 +- Resolves: RHEL-16977 : rhc - rhc: support RHEL 7 managed nodes +- Resolves: RHEL-19042 : selinux - fix: no longer use "item" as a loop variable +- Resolves: RHEL-19044 : selinux - fix: Print an error message when module to be created doesn't exist +- Resolves: RHEL-14022 : storage - Basic support for creating shared logical volumes + +* Fri Dec 1 2023 Rich Megginson - 1.23.0-2.3 +- Resolves: RHEL-17874 : ha_cluster - high-availability firewall service is not added on qdevice node + +* Thu Nov 30 2023 Rich Megginson - 1.23.0-2.2 +- Resolves: RHEL-15872 : RHEL for Edge support in system roles + vpn - fixed issue with test cleanup + +* Thu Nov 30 2023 Rich Megginson - 1.23.0-2.1 +- Resolves: RHEL-15872 : - RHEL for Edge support in system roles + except for nbde_client, rhc, metrics +- Resolves: RHEL-17667 : ad_integration - feat: Add sssd custom settings +- Resolves: RHEL-16542 : fapolicyd - feat: Import code for fapolicyd system role +- Resolves: RHEL-14090 : ha_cluster - [RFE] HA Cluster system role should be able to enable Resilient Storage repository +- Resolves: RHEL-4624 : ha_cluster - [FutureFeature] Allow ha_cluster role to configure fencing topology +- Resolves: RHEL-3264 : ha_cluster - [FutureFeature] Allow ha_cluster role to configure all qdevice options +- Resolves: RHEL-3354 : kdump - fix: retry read of kexec_crash_size +- Resolves: RHEL-15933 : logging - feat: Add support for the global config option preserveFQDN with a new logg… +- Resolves: RHEL-15440 : logging - feat: Add support for general queue and general action parameters +- Resolves: RHEL-15038 : logging - fix: check that logging_max_message_size is set, not rsyslog_max_message_size +- Resolves: RHEL-16501 : network - Ansible RHEL network system role issue with ipv6.routing-rules the prefix length for 'from' cannot be zero" +- Resolves: RHEL-15871 : selinux - fix: Use `ignore_selinux_state` module option +- Resolves: RHEL-16213 : storage - feat: Support for creating volumes without a FS + +* Thu Nov 9 2023 Sergei Petrosian - 1.23.0-2 +- RHEL-1119: ad_integration: Support for dynamic DNS Updates + Update to a new version with fixed tests + +* Wed Sep 20 2023 Sergei Petrosian - 1.23.0-1 +- Resolves: RHEL-5345 spec - Remove with_html, instead use built-in .README.html +- Resolves: RHEL-5985 ansible-sshd - Manage SSH certificates +- rhbz#2224648: Remove ad_integration patch and use the latest ad_integration + version instead. Vendor community-general.ini_files for +- RHEL-1119: ad_integration: Support for dynamic DNS Updates +- Change link to open new issue in galaxy.yml from deprecated BZ to Jira + +* Tue Aug 15 2023 Rich Megginson - 1.22.0-1 +- Resolves:rhbz#2233183 : ad_integration - red hat "rhel system role" ad_integration leaks credentials when in check_mode +- Resolves:rhbz#2232391 : kdump - role: "Write new authorized_keys if needed" task idempotency issues +- Resolves:rhbz#2232392 : kdump - system role fails if kdump_ssh_user doesn't have a .ssh/authorized_keys file in home directory +- Resolves RHEL-1398 : kdump - fix: ensure .ssh directory exists for kdump_ssh_user on kdump_ssh_server +- Resolves RHEL-1500 : kdump - fix: Ensure authorized_keys management works with multiple hosts +- Resolves:rhbz#2224648 : firewall - fix: reload on resetting to defaults +- Resolves RHEL-1496 : firewall - fix: files: overwrite firewalld.conf on previous replaced +- Resolves RHEL-1498 : storage - fix: use stat.pw_name, stat.gr_name instead of owner, group + sshd README remove upstream only docs + first RC for 1.22.0 rhel 8.9 and 9.3 + fix firewall reload test gather facts + +* Thu Aug 10 2023 Rich Megginson - 1.22.0-0.21 +- Resolves:rhbz#2220962 : podman - support quadlet units + support for rootless quadlets, secrets + +* Wed Aug 09 2023 Rich Megginson - 1.22.0-0.20 +- Resolves:rhbz#2140880 : firewall - missing module in linux-system-roles.firewall to create an ipset + +* Tue Aug 01 2023 Rich Megginson - 1.22.0-0.19 +- Resolves RHEL-866 : podman - use getsubids to look for subuid, subgid for IdM support +- Resolves RHEL-858 : podman - allow to not pull images, continue if image pull fails +- Resolves:rhbz#2224648 : firewall - fix: reload on resetting to defaults +- Resolves:rhbz#2226077 : podman - Podman system role: Unable to use podman_registries_conf to set unqualified-search-registries +- Resolves RHEL-918 : firewall - Ansible RHEL firewall system role not idempotent when configuring the interface using the role in rhel9 +- Resolves RHEL-907 : kdump - use failure_action instead of default on EL9 and later +- Resolves RHEL-899 : firewall - Check mode fails with replacing previous rules +- Resolves:rhbz#2227823 : rhc - baseurl in rhsm.conf is empty when rhc_baseurl is not specified + +* Wed Jul 26 2023 Rich Megginson - 1.22.0-0.18 +- Resolves:rhbz#2224388 : systemd - system role for managing systemd units + +* Tue Jul 25 2023 Rich Megginson - 1.22.0-0.17 +- Resolves:rhbz#2224387 : keylime_server - system role for managing keylime servers + +* Fri Jul 21 2023 Rich Megginson - 1.22.0-0.16 +- Resolves:rhbz#2220963 : podman - allow container networking configuration +- Resolves:rhbz#2220961 : podman - support for healthchecks and healthcheck actions +- Resolves:rhbz#2220962 : podman - support quadlet units +- Resolves:rhbz#2224388 : systemd - system role for managing systemd units +- Resolves:rhbz#2223036 : ALL - facts being gathered unnecessarily +- Resolves:rhbz#2186057 : certificate - rhel-system-roles.certificate does not re-issue after updating key_size +- Resolves:rhbz#2222433 : firewall - Check mode fails when creating new firewall service +- Resolves:rhbz#2222809 : firewall - should have option to disable conflicting services +- Resolves:rhbz#2222808 : firewall - when firewalld.service is masked, firewall role fails +- Resolves:rhbz#2224094 : storage - RAID volume pre cleanup - remove existing data from member disks as needed before creation + +* Mon Jul 10 2023 Rich Megginson - 1.22.0-0.15 +- Resolves:rhbz#2218204 : certificate - add mode parameter to change permissions for cert files +- Resolves:rhbz#2218595 : network - Support no-aaaa DNS option + +* Sun Jul 09 2023 Rich Megginson - 1.22.0-0.14 +- Resolves:rhbz#2218899 : storage - [RHEL8] Unexpected behavior when creating ext4 filesystem with invalid parameter + +* Fri Jun 23 2023 Rich Megginson - 1.22.0-0.13 +- Resolves:rhbz#2216759 : ssh - add ssh_backup option with default true +- Resolves:rhbz#2216521 : firewall - Don't install python(3)-firewall it's a dependency of firewalld + +* Thu Jun 22 2023 Rich Megginson - 1.22.0-0.12 +- Resolves:rhbz#2168738 : storage - Storage: mounted devices that are in use cannot be resized + +* Tue Jun 20 2023 Rich Megginson - 1.22.0-0.11 +- Resolves:rhbz#2211272 : kdump - support auto_reset_crashkernel, dracut_args, deprecate /etc/sysconfig/kdump + +* Wed Jun 07 2023 Rich Megginson - 1.22.0-0.10 +- Resolves:rhbz#2211723 : ad_integration - add ad_integration_force_rejoin + +* Tue Jun 06 2023 Rich Megginson - 1.22.0-0.9 +- Resolves:rhbz#2211273 : network - Support configuring auto-dns setting +- Resolves:rhbz#2211778 : rhc - implement rhc_proxy.scheme +- Resolves:rhbz#2141961 : storage - RFE for the storage system role to support configuring the stripe size for RAID LVM volumes +- Resolves:rhbz#2211271 : selinux - use restorecon -T 0 on supported platforms +- Resolves:rhbz#2211247 : storage - Failed to commit changes to disk: Failed to format device: Input/output error + +* Tue May 30 2023 Rich Megginson - 1.22.0-0.8 +- Resolves:rhbz#2181661 : storage - [RFE] user-specified mount point owner and permissions +- Resolves:rhbz#2193057 : storage - Cannot set chunk size for RAID: Unsupported parameters for (blivet) module: pools.raid_chunk_size +- Resolves:rhbz#2211247 : storage - Failed to commit changes to disk: Failed to format device: Input/output error + +* Tue May 23 2023 Rich Megginson - 1.22.0-0.7 +- remove upstream only docs from README.md files +- python3-setuptools is now required for release_collection.py +- fix ruamel issue described at https://github.com/linux-system-roles/auto-maintenance/pull/272 +- Resolves:rhbz#2209441 : rhc - system role does not apply Insights tags +- Resolves:rhbz#2191702 : tlog - use the proxy provider - the files provider is deprecated in sssd +- Resolves:rhbz#2190500 : roles should support running with gather_facts: false +- READMEs for all roles contain only downstream applicable docs +- All roles/tests now work with ansible-core 2.15 +- Fix some roles to work with remove-cloud-init + +* Thu May 04 2023 Rich Megginson - 1.22.0-0.6 +- Resolves:rhbz#2186910 : fingerprint in config files managed by roles +- Resolves:rhbz#2190478 : ha_cluster - Add possibility to load SBD watchdog kernel modules +- Resolves:rhbz#2190483 : ha_cluster - support for resource and operation defaults +- Resolves:rhbz#2151371 : postgresql - [RFE] system role for PostgreSQL management +- Resolves:rhbz#2179016 : rhc - [RFE] New role for Red Hat subscription management, insights management [rhel-8.9.0] +- Resolves:rhbz#2190480 : ha_cluster - use pcs to setup qdevice certificates if available +- Resolves:rhbz#2186198 : spec: Remove doc fragments from vendored modules +- Resolves:rhbz#2190500 : roles should support running with gather_facts: false +- Resolves:rhbz#2175326 : use ansible-galaxy collection build/install instead of tar +- Resolves:rhbz#2186908 : rhc - RHC system role: activation key registration fails if system is already registered +- Resolves:rhbz#2190499 : selinux - failing test - sshd/tests_firewall_selinux.yml - No package matching 'firewalld' found available, installed or updated + +* Wed May 3 2023 Rich Megginson - 1.22.0-0.5 +- fix issue with postgresql tests + +* Tue May 2 2023 Rich Megginson - 1.22.0-0.4 +- fix issue with ha_cluster vendoring modprobe +- move vendoring into included files + +* Thu Apr 27 2023 Rich Megginson - 1.22.0-0.3 +- fix issues in some tests with ANSIBLE_GATHERING=explicit +- add testing for fingerprints in config files +- fix podman jinja 2.7 issue +- sshd - skip firewall testing if not supported + +* Thu Apr 6 2023 Rich Megginson - 1.22.0-0.2 +- initial 8.9/9.3 + +* Thu Apr 6 2023 Sergei Petrosian - 1.21.1-2 +- Resolves: rhbz#2185002 : Remove doc fragments from vendored modules +- Build collection artifact in the same directory on Fedora and RHEL * Thu Mar 16 2023 Rich Megginson - 1.21.1-1 - Resolves:rhbz#2144877 : rhc - new role for subscription management/registration/insights