From 922032cb9facfcad48ae4c4b6701993340d02374 Mon Sep 17 00:00:00 2001 From: Jakob Meng Date: Tue, 6 Dec 2022 11:48:49 +0100 Subject: [PATCH] Dropped obsolete module templates Module templates have little benefit because * they are not documented anywhere, * their structure is not suitable for our modules, hence not a single module is written according to the templates, * contributers better base their own modules on existing modules because we have modules for most OpenStack components, * they are outdated, e.g. normalizing is a relict of openstacksdk<0.99.0 and results, * they are bloated, e.g. *_info module is doing preliminary checks and creating filters in separate functions which proved in other modules to be much better readable when inlined, * they are hard to understand, e.g. argument_spec definition is a huge Jinja2 template which does nothing except for copying arguments from one place to another, * they are not tested. Change-Id: I460b75c09a361e712bbfb002c1ad1d03b3dff8ee (cherry picked from commit 133af9666691ec458e265f66931e5ebc3742f764) --- .zuul.yaml | 2 - contrib/generate_module.sh | 5 - contrib/module_info_template.py.j2 | 110 --------------------- contrib/module_template.py.j2 | 149 ----------------------------- contrib/module_template_vars.yaml | 81 ---------------- galaxy.yml | 1 - galaxy.yml.in | 1 - 7 files changed, 349 deletions(-) delete mode 100755 contrib/generate_module.sh delete mode 100644 contrib/module_info_template.py.j2 delete mode 100644 contrib/module_template.py.j2 delete mode 100644 contrib/module_template_vars.yaml diff --git a/.zuul.yaml b/.zuul.yaml index d1b781e1..42800b36 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -36,7 +36,6 @@ - .*\.rst - tools/run-ansible-sanity.sh - tests/sanity/.* - - contrib/.* - .zuul.yaml vars: zuul_work_dir: src/opendev.org/openstack/ansible-collections-openstack @@ -436,7 +435,6 @@ - ^.*\.md$ - ^.*\.rst$ - ^changelogs/.*$ - - ^contrib/.*$ - ^docs/.*$ - ^meta/.*$ - ^requirements.*$ diff --git a/contrib/generate_module.sh b/contrib/generate_module.sh deleted file mode 100755 index abec2c30..00000000 --- a/contrib/generate_module.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# For resource changing module -ansible localhost -c local -m template -a "src=module_template.py.j2 dest=my_module.py" -e @module_template_vars.yaml -# For resource info collection module -ansible localhost -c local -m template -a "src=module_info_template.py.j2 dest=my_module_info.py" -e @module_template_vars.yaml diff --git a/contrib/module_info_template.py.j2 b/contrib/module_info_template.py.j2 deleted file mode 100644 index a16251ac..00000000 --- a/contrib/module_info_template.py.j2 +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/python -# coding: utf-8 -*- - -# Copyright (c) 2020, {{ author_name }} <{{ author_mail }}> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -DOCUMENTATION = ''' ---- -module: {{ module_name }} -short_description: {{ module_short_description }} -author: OpenStack Ansible SIG -description: - - {{ module_long_description }} -options: - {{ options|to_nice_yaml(indent=2,sort_keys=false)|indent(width=2)|trim }} - -requirements: - - "python >= 3.6" - - "openstacksdk" - -extends_documentation_fragment: - - openstack.cloud.openstack -''' - -RETURN = ''' -{{ module_returns_example|to_nice_yaml(indent=2,sort_keys=false) }} -''' - -EXAMPLES = ''' -# What modules does for example -- {{ module_name }}: - name: - - name1 - - name2 - timeout: 200 -''' - -from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule - - -class {{ module_name.split("_")|map("capitalize")|list|join("") }}Module(OpenStackModule): - - argument_spec = dict( -{% for k, v in options.items() %} -{{ k | indent( width=8, indentfirst=True) }}=dict(type='{{ v.type }}' -{%- if 'required' in v %}, required={{ v.required }}{% endif %} -{%- if 'elements' in v %}, elements={{ v.elements }}{% endif %} -{%- if 'default' in v %}, default={% if v.type == 'str' %}"{{ v.default }}"{% else %}{{ v.default }}{% endif %}{% endif %} -{%- if 'aliases' in v %}, aliases={{ v.aliases }}{% endif %} -{%- if 'choices' in v %}, choices={{ v.choices }}{% endif %}), -{% endfor %} - ), - - # Optional arguments requirements - module_kwargs = dict( - required_if=[ - ['action', 'rebuild', ['image']], # if need to rebuild image (only), the 'image' is required - ["state", "present", ["username", "user_roles"]], # for creating user 'user_roles' is required - ["state", "absent", ["username"]], # for state 'absent' only username is required - ], - required_by=dict( # for weather and population 'city' is required to set - weather=('city'), - population=('city'), - ), - mutually_exclusive=[ - ['use_cloud1', 'use_cloud2'] # can't run on both, choose only one to set - ], - required_together=[ - ['remove_image', 'image_name'] # if need to remove image, must to specify which one - ], - required_one_of_args=[["password", "password_hash"]], # one of these args must be set - supports_check_mode={{ check_mode_support }}, # good practice is to support check_mode - ) - - # you main funciton is here - def run(self): - # do any arguments check if needed - data = self.preliminary_checks() - # check if we need to prepare various filters for results - filters = self.prepare_filters() - # run SDK call to get information about requested resource - result = self.conn.compute.resource_list( - filters=filters, - detailed=self.params['detailed'], - # any other parameters - ) - # process results if they require a change - result = self.normalize_result() - self.results.update({'resource_name': result}) - - def preliminary_checks(self): - # you checks before running like arguments and options checks, etc - return data - - def prepare_filters(self): - # process filters if they require additional checks - return filters - - def normalize_result(self): - # process filters if they require additional checks - return result - - -def main(): - module = {{ module_name.split("_")|map("capitalize")|list|join("") }}Module() - module() - - -if __name__ == '__main__': - main() diff --git a/contrib/module_template.py.j2 b/contrib/module_template.py.j2 deleted file mode 100644 index ddbcf37a..00000000 --- a/contrib/module_template.py.j2 +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/python -# coding: utf-8 -*- - -# Copyright (c) 2020, {{ author_name }} <{{ author_mail }}> -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -DOCUMENTATION = ''' ---- -module: {{ module_name }} -short_description: {{ module_short_description }} -author: OpenStack Ansible SIG -description: - - {{ module_long_description }} -options: - {{ options|to_nice_yaml(indent=2,sort_keys=false)|indent(width=2)|trim }} - -requirements: - - "python >= 3.6" - - "openstacksdk" - -extends_documentation_fragment: - - openstack.cloud.openstack -''' - -RETURN = ''' -{{ module_returns_example|to_nice_yaml(indent=2,sort_keys=false) }} -''' - -EXAMPLES = ''' -# What modules does for example -- {{ module_name }}: - action: pause - auth: - auth_url: https://identity.example.com - username: admin - password: admin - project_name: admin - server: vm1 - timeout: 200 -''' - -from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule - - -class {{ module_name.split("_")|map("capitalize")|list|join("") }}Module(OpenStackModule): - - argument_spec = dict( -{% for k, v in options.items() %} -{{ k | indent( width=8, indentfirst=True) }}=dict(type='{{ v.type }}' -{%- if 'required' in v %}, required={{ v.required }}{% endif %} -{%- if 'elements' in v %}, elements={{ v.elements }}{% endif %} -{%- if 'default' in v %}, default={% if v.type == 'str' %}"{{ v.default }}"{% else %}{{ v.default }}{% endif %}{% endif %} -{%- if 'aliases' in v %}, aliases={{ v.aliases }}{% endif %} -{%- if 'choices' in v %}, choices={{ v.choices }}{% endif %}), -{% endfor %} - ), - - # Optional arguments requirements - module_kwargs = dict( - required_if=[ - ['action', 'rebuild', ['image']], # if need to rebuild image (only), the 'image' is required - ["state", "present", ["username", "user_roles"]], # for creating user 'user_roles' is required - ["state", "absent", ["username"]], # for state 'absent' only username is required - ], - required_by=dict( # for weather and population 'city' is required to set - weather=('city'), - population=('city'), - ), - mutually_exclusive=[ - ['use_cloud1', 'use_cloud2'] # can't run on both, choose only one to set - ], - required_together=[ - ['remove_image', 'image_name'] # if need to remove image, must to specify which one - ], - required_one_of_args=[["password", "password_hash"]], # one of these args must be set - supports_check_mode={{ check_mode_support }}, # good practice is to support check_mode - ) - - # you main funciton is here - def run(self): - # do any arguments check if needed - data = self.preliminary_checks() - # check if we need to run or the resource is in desired state already - must_run = self.check_mode_test() - # if the resource is good - if not must_run: - # updated returned results if need - self.results.update({"returning_data": some_data}) - # returning {changed: False, ...} because we didn't change resource - self.exit_json(self.results) - # do something if must to run the module - self.execute() - - def preliminary_checks(self): - # you checks before running like arguments and options checks, etc - return data - - def check_mode_test(self): - # check the idempotency - does module should do anything or - # it's already in the desired state? - return must_run - - def execute(self): - # doing here what should be done, using OpenstackSDK - # for example actions for resource: - # self.params['action'] = "rebuild" - action_name = self.params['action'] + "_resource" # action_name='rebuild_resource' - try: - # find a method "rebuild_resource" in openstack SDK compute: - func_name = getattr(self.conn.compute, action_name) - # found self.conn.compute.rebuild_resource - except AttributeError: - self.fail_json( - msg="Method %s wasn't found in OpenstackSDK compute" % action_name) - summary = func_name(data) # summary = self.conn.compute.rebuild_resource(data) - self.results.update({"returning_data": summary}) - # that's it, exiting, results will be returned from module automatically - - # another option for states - def execute_with_action_map(self): - actions_map = { - 'start': self._start_resource, - 'stop': self._stop_resource, - 'restart': self._restart_resource, - 'absent': self._absent_resource, - } - summary = actions_map(self.params['action'])() # summary = self.start_resource() - self.results.update({"changed": True, "data2return": summary}) - - def _start_resource(self, some_other_data): - pass - - def _stop_resource(self, some_other_data): - pass - - def _restart_resource(self, some_other_data): - pass - - def _absent_resource(self, some_other_data): - pass - - -def main(): - module = {{ module_name.split("_")|map("capitalize")|list|join("") }}Module() - module() - - -if __name__ == '__main__': - main() diff --git a/contrib/module_template_vars.yaml b/contrib/module_template_vars.yaml deleted file mode 100644 index 83578776..00000000 --- a/contrib/module_template_vars.yaml +++ /dev/null @@ -1,81 +0,0 @@ -##### PLEASE READ BEFORE ##### - -# Module format and documentation -# https://docs.ansible.com/ansible/latest/dev_guide/developing_modules_documenting.html#module-format-and-documentation - - -module_name: server_manage -author_name: 'Happy Ansible User' -author_mail: dontwriteme@example.com -module_short_description: "Doing something very useful" -module_long_description: "Here is the place to release your inner writer" -check_mode_support: True # good practice to support check_mode: -# https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html#check-mode-dry-run - -module_returns_example: - image: - description: Image inspection results for the image that was pulled, pushed, or built. - returned: always # or 'success' in case of success only - type: dict - sample: - Image Name: Sample Image - Image ID: e6471d00796a13de8142c15d7ad3a44f - Nested: - images list: - - data 1 - - image 1234 - boolean_1: True - -options: - optional_string: - description: - - This variable is set for having string argument, for example 'action' - type: str - required: true - default: "my_lovely_action" - choices: - - allowed_option1 - - allowed_option1 - optional_boolean: - description: - - This variable is set for having a boolean argument, for example whether - to wait for resource creation or not - type: bool - required: false # may be omitted if false - # and no default because not required - optional_integer: - description: - - This variable is set for having a integer argument, for example how many - seconds to wait for the resource to come alive - required: true - default: 60 - type: int - aliases: # sometimes we allow to pass the same option with different name - - old_optional_integer_name - - different_option_name - optional_list: - description: - - This variable is set for having a list argument, for example files need - to create with the resource - type: list - elements: str # type of elements of the list, can be dict, str, int, list - optional_dictionary: - description: - - This variable is set for having a dictionary argument, for example to - set environment variables or to pass more complex data to SDK - required: true - default: {} - type: dict - suboptions: - suboption_1: - description: - - suboption_1 description, what it does - type: str - aliases: - - suboption_1_another_name - suboption_2: - description: - - suboption_2 description, what it does - type: list - elements: str - default: [] diff --git a/galaxy.yml b/galaxy.yml index 4b49271e..43298f2d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -31,6 +31,5 @@ build_ignore: - .env - .vscode - ansible_collections_openstack.egg-info - - contrib - changelogs version: 1.10.0 diff --git a/galaxy.yml.in b/galaxy.yml.in index a1da51a4..6edfaba4 100644 --- a/galaxy.yml.in +++ b/galaxy.yml.in @@ -31,5 +31,4 @@ build_ignore: - .env - .vscode - ansible_collections_openstack.egg-info - - contrib - changelogs