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
This commit is contained in:
parent
51f1fea8b3
commit
133af96666
@ -36,7 +36,6 @@
|
|||||||
- .*\.rst
|
- .*\.rst
|
||||||
- tools/run-ansible-sanity.sh
|
- tools/run-ansible-sanity.sh
|
||||||
- tests/sanity/.*
|
- tests/sanity/.*
|
||||||
- contrib/.*
|
|
||||||
- .zuul.yaml
|
- .zuul.yaml
|
||||||
vars:
|
vars:
|
||||||
zuul_work_dir: src/opendev.org/openstack/ansible-collections-openstack
|
zuul_work_dir: src/opendev.org/openstack/ansible-collections-openstack
|
||||||
@ -264,7 +263,6 @@
|
|||||||
- ^.*\.md$
|
- ^.*\.md$
|
||||||
- ^.*\.rst$
|
- ^.*\.rst$
|
||||||
- ^changelogs/.*$
|
- ^changelogs/.*$
|
||||||
- ^contrib/.*$
|
|
||||||
- ^docs/.*$
|
- ^docs/.*$
|
||||||
- ^meta/.*$
|
- ^meta/.*$
|
||||||
- ^requirements.*$
|
- ^requirements.*$
|
||||||
|
@ -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
|
|
@ -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()
|
|
@ -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()
|
|
@ -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: []
|
|
@ -31,6 +31,5 @@ build_ignore:
|
|||||||
- .env
|
- .env
|
||||||
- .vscode
|
- .vscode
|
||||||
- ansible_collections_openstack.egg-info
|
- ansible_collections_openstack.egg-info
|
||||||
- contrib
|
|
||||||
- changelogs
|
- changelogs
|
||||||
version: 2.0.0-dev
|
version: 2.0.0-dev
|
||||||
|
@ -31,5 +31,4 @@ build_ignore:
|
|||||||
- .env
|
- .env
|
||||||
- .vscode
|
- .vscode
|
||||||
- ansible_collections_openstack.egg-info
|
- ansible_collections_openstack.egg-info
|
||||||
- contrib
|
|
||||||
- changelogs
|
- changelogs
|
||||||
|
Loading…
Reference in New Issue
Block a user