From 82dd143ce861a621eb3796fff1dc1a5a1d973356 Mon Sep 17 00:00:00 2001 From: Douglas Viroel Date: Tue, 15 Jun 2021 14:46:11 -0300 Subject: [PATCH] Add tripleo-yum-config ansible module This patch adds the tripleo-yum-config module and also updates its readme file with both ansible and pip information. Change-Id: I893aac72ee50b389c4d3173fa01bb8d6f74ff38f --- tripleo-yum-config/README.md | 23 ++- tripleo-yum-config/example_playbook.yaml | 33 +++ tripleo-yum-config/setup.cfg | 6 +- tripleo-yum-config/tripleo_yum_config.py | 245 +++++++++++++++++++++++ 4 files changed, 300 insertions(+), 7 deletions(-) create mode 100644 tripleo-yum-config/example_playbook.yaml create mode 100644 tripleo-yum-config/tripleo_yum_config.py diff --git a/tripleo-yum-config/README.md b/tripleo-yum-config/README.md index a24c7b9..6627d75 100644 --- a/tripleo-yum-config/README.md +++ b/tripleo-yum-config/README.md @@ -12,24 +12,24 @@ repos, yum modules and yum global configuration file. It is possible to use *tripleo-yum-config* as a standalone module by cloning its repository and invoking in command line: * **repo** - + This subcommand lets you enable or disable a repo and sets its configuration options. The *tripleo-yum-config* module will search for the provided repo name in all *.repo* files at REPO_DIR_PATH. Optionally, you can provide a dir path where your repo files live or specify the full path of the repo file. By default REPO_DIR_PATH is set to */etc/yum.repod.d/*. - + Examples: ``` sudo python -m tripleo_yum_config repo appstream --enable --set-opts baseurl=http://newbaseurl exclude="package*" sudo python -m tripleo_yum_config repo epel --disable --config-dir-path=/path/to/yum.repos.d ``` * **module** - + This subcommand lets you enable, disable, remove, install or reset a module. Depending on the selected operation and module, the optional parameters 'stream' or 'profile' will also need to be provided: 1. when enabling a module, the *stream* version will be required if the module has zero or more than one default stream. 2. when installing a module, the *profile* will be required if the enabled stream has no default profile set. - + Examples: ``` sudo python -m tripleo_yum_config module remove tomcat @@ -38,12 +38,12 @@ its repository and invoking in command line: sudo python -m tripleo_yum_config module install nginx --profile common ``` * **global** - + This subcommand lets you set any global yum/dnf configuration value under *[main]* section. If no configuration file is found by the module, a new one is created and populated. Optionally you can also provide the path to the configuration file. By default CONFIG_FILE_PATH is set to */etc/yum.conf* - + Example: ``` sudo python -m tripleo_yum_config global --set-opts keepcache=1 cachedir="/var/cache/dnf" @@ -72,3 +72,14 @@ invoke *tripleo-yum-config --help* to see all the available commands. ``` tripleo-yum-config --help ``` + +## Ansible Module + +An ansible module [tripleo_yum_config](https://opendev.org/openstack/tripleo-repos/src/branch/master/tripleo-yum-config/tripleo_yum_config.py) +is available for you when you install tripleo-yum-config, either by using +setup.py or pip. The module is installed at the relative path +*share/ansible/plugins/modules*, which may land on a different directory, +depending on how you are installing this package. Check your ansible +configuration to see if the directory is included in your ansible library path. +An [example playbook](https://opendev.org/openstack/tripleo-repos/src/branch/master/tripleo-yum-config/example_playbook.yaml) +is available to assist on module usage. diff --git a/tripleo-yum-config/example_playbook.yaml b/tripleo-yum-config/example_playbook.yaml new file mode 100644 index 0000000..e305147 --- /dev/null +++ b/tripleo-yum-config/example_playbook.yaml @@ -0,0 +1,33 @@ +--- +- name: Example usage for tripleo_yum_config python module + hosts: localhost + tasks: + - name: Enable fake yum repo and set exclude dirs + become: true + tripleo_yum_config: + type: repo + name: appstream + enabled: true + set_options: + exclude: + - nodejs* + - mariadb* + + - name: Enable and install nginx module + become: true + tripleo_yum_config: + type: module + name: nginx + enabled: true + operation: install + profile: common + stream: mainline + + - name: Set yum global options in dnf.conf + become: true + tripleo_yum_config: + type: global + file_path: /etc/dnf/dnf.conf + set_options: + skip_if_unavailable: "False" + keepcache: "0" diff --git a/tripleo-yum-config/setup.cfg b/tripleo-yum-config/setup.cfg index 07ea395..3c053ce 100644 --- a/tripleo-yum-config/setup.cfg +++ b/tripleo-yum-config/setup.cfg @@ -1,7 +1,7 @@ [metadata] name = tripleo-yum-config author = Douglas Viroel -author_email = dviroel@redhat.com +author_email = openstack-discuss@lists.openstack.org description = Updates yum configuration files (repo, modules, global configuration). long_description = file: README.md LICENSE long_description_content_type = text/markdown @@ -22,3 +22,7 @@ python_requires = >=3.6 [options.entry_points] console_scripts = tripleo-yum-config = tripleo_yum_config.__main__:cli_entrypoint + +[files] +data_files = + share/ansible/plugins/modules/ = tripleo_yum_config.py diff --git a/tripleo-yum-config/tripleo_yum_config.py b/tripleo-yum-config/tripleo_yum_config.py new file mode 100644 index 0000000..ed55d0a --- /dev/null +++ b/tripleo-yum-config/tripleo_yum_config.py @@ -0,0 +1,245 @@ +#!/usr/bin/python +# Copyright 2021 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from ansible.module_utils.basic import AnsibleModule + +import tripleo_yum_config.dnf_manager as dnf_mgr +import tripleo_yum_config.yum_config as cfg + +DOCUMENTATION = r''' +--- +module: tripleo_yum_config + +short_description: Update yum configuration files for TripleO deployments. + +version_added: "2.9" + +description: + - Update specific options for different yum configuration files like + yum repos, yum modules and yum global configuration. + +options: + type: + description: + - The type of yum configuration to be changed. + required: true + type: str + choices: [repo, module, global] + name: + description: + - Name of the repo or module to be changed. This options is + mandatory only for repo and module types. + required: false + type: str + enabled: + description: + - Change the yum repo or module to enabled or disabled. + - This options is ignored for yum global configuration. + required: false + type: bool + operation: + description: + - Operation to be execute within a dnf module. + required: false + type: str + choices: [install, remove, reset] + stream: + description: + - Sets a module stream. This options is recommended when enabling a + module that doesn't have a default stream. + required: false + type: str + profile: + description: + - Sets a module profile. This options is recommended when installing + a module that doesn't have a default profile. + required: false + type: str + set_options: + description: + - Dictionary with options to be updated. All dictionary values must + be string or list of strings. + required: false + type: dict + file_path: + description: + - Absolute path of the configuration file to be changed. + required: false + type: str + dir_path: + description: + - Absolute path of the directory that contains the configuration + file to be changed. + required: false + type: str + +author: + - Douglas Viroel (@viroel) +''' + +EXAMPLES = r''' +# Set yum 'appstream' repo to enabled and exclude a list of packages +- name: Enable appstream repo and exclude nodejs and mariadb packages + become: true + become_user: root + tripleo_yum_config: + type: repo + name: appstream + enabled: true + set_options: + exclude: + - nodejs* + - mariadb* + +# Enable and install a yum/dnf module +- name: Enable nginx module + become: true + become_user: root + tripleo_yum_config: + type: module + name: tomcat + enabled: false + stream: "1.18" + +- name: Enable nginx module + become: true + become_user: root + tripleo_yum_config: + type: module + name: nginx + operation: install + profile: common + +# Set yum global configuration options +- name: Set yum global options + become: true + become_user: root + tripleo_yum_config: + type: global + file_path: /etc/dnf/dnf.conf + set_options: + skip_if_unavailable: "False" + keepcache: "0" +''' + + +def run_module(): + # define available arguments/parameters a user can pass to the module + supported_config_types = ['repo', 'module', 'global'] + supported_module_operations = ['install', 'remove', 'reset'] + module_args = dict( + type=dict(type='str', required=True, choices=supported_config_types), + name=dict(type='str', required=False), + enabled=dict(type='bool', required=False), + operation=dict(type='str', required=False, + choices=supported_module_operations), + stream=dict(type='str', required=False), + profile=dict(type='str', required=False), + set_options=dict(type='dict', required=False), + file_path=dict(type='str', required=False), + dir_path=dict(type='str', required=False), + ) + + result = dict( + changed=False, + msg='' + ) + + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=True + ) + + m_type = module.params.get('type') + m_name = module.params.get('name') + m_set_opts = module.params.get('set_options', {}) + m_enabled = module.params.get('enabled') + m_file_path = module.params.get('file_path') + m_dir_path = module.params.get('dir_path') + + # Sanity checks + if m_type in ['repo', 'module'] and m_name is None: + result['msg'] = ( + "The parameter 'name' is mandatory when 'type' is set to 'repo' " + "or 'module'.") + module.fail_json(**result) + + # 'set_options' expects a dict that can hold, as value, strings and list + # of strings. List of strings will be converted to a comma-separated list. + invalid_set_opts_msg = ( + "The provided value for 'set_options' parameter has an invalid " + "format. All dict values must be string or a list of strings.") + if m_set_opts: + for k, v in m_set_opts.items(): + if isinstance(v, list): + if not all(isinstance(elem, str) for elem in v): + result['msg'] = invalid_set_opts_msg + module.fail_json(**result) + m_set_opts[k] = ','.join(v) + elif not isinstance(v, str): + result['msg'] = invalid_set_opts_msg + module.fail_json(**result) + + if module.check_mode: + # Checks were already made above + module.exit_json(**result) + + # Module execution + try: + if m_type == 'repo': + config_obj = cfg.TripleOYumRepoConfig( + file_path=m_file_path, + dir_path=m_dir_path) + config_obj.update_section(m_name, m_set_opts, enable=m_enabled) + + elif m_type == 'module': + dnf_mod_mgr = dnf_mgr.DnfModuleManager() + m_stream = module.params.get('stream') + m_profile = module.params.get('profile') + if m_enabled is True: + dnf_mod_mgr.enable_module(m_name, + stream=m_stream, + profile=m_profile) + elif m_enabled is False: + dnf_mod_mgr.disable_module(m_name, + stream=m_stream, + profile=m_profile) + m_operation = module.params.get('operation') + if m_operation: + dnf_method = getattr(dnf_mod_mgr, m_operation + "_module") + dnf_method(m_name, stream=m_stream, profile=m_profile) + + elif m_type == 'global': + config_obj = cfg.TripleOYumGlobalConfig(file_path=m_file_path) + config_obj.update_section('main', m_set_opts) + + except Exception as exc: + result['msg'] = str(exc) + module.fail_json(**result) + + # Successful module execution + result['changed'] = True + result['msg'] = ( + "Yum {} configuration was successfully updated.".format(m_type) + ) + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main()