From 8b98452cbb2b313bb319fe86a0d2c19936c15307 Mon Sep 17 00:00:00 2001 From: Dmitry Tantsur Date: Wed, 19 Aug 2020 12:48:12 +0200 Subject: [PATCH] Refactor ironic authentication into a new module_utils module This change merely moves the code to one location. The next logical step would be to make IronicModule inherit the common ansible module. Change-Id: Iec0ca1e33de6ebc36d7664941eafe1d77203d8f2 --- plugins/module_utils/ironic.py | 68 ++++++++++++++++++++++++ plugins/modules/baremetal_inspect.py | 39 ++++---------- plugins/modules/baremetal_node.py | 38 ++++--------- plugins/modules/baremetal_node_action.py | 39 ++++---------- 4 files changed, 100 insertions(+), 84 deletions(-) create mode 100644 plugins/module_utils/ironic.py diff --git a/plugins/module_utils/ironic.py b/plugins/module_utils/ironic.py new file mode 100644 index 00000000..a7ab19ef --- /dev/null +++ b/plugins/module_utils/ironic.py @@ -0,0 +1,68 @@ +# This code is part of Ansible, but is an independent component. +# This particular file snippet, and this file snippet only, is BSD licensed. +# Modules you write using this snippet, which is embedded dynamically by Ansible +# still belong to the author of the module, and may assign their own license +# to the complete work. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import openstack_full_argument_spec + + +def ironic_argument_spec(**kwargs): + spec = dict( + auth_type=dict(required=False), + ironic_url=dict(required=False), + ) + spec.update(kwargs) + return openstack_full_argument_spec(**spec) + + +# TODO(dtantsur): inherit the collection's base module +class IronicModule(AnsibleModule): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._update_ironic_auth() + + def _update_ironic_auth(self): + """Validate and update authentication parameters for ironic.""" + if ( + self.params['auth_type'] in [None, 'None', 'none'] + and self.params['ironic_url'] is None + and not self.params['cloud'] + and not (self.params['auth'] + and self.params['auth'].get('endpoint')) + ): + self.fail_json(msg=("Authentication appears to be disabled, " + "Please define either ironic_url, or cloud, " + "or auth.endpoint")) + + if ( + self.params['ironic_url'] + and self.params['auth_type'] in [None, 'None', 'none'] + and not (self.params['auth'] + and self.params['auth'].get('endpoint')) + ): + self.params['auth'] = dict( + endpoint=self.params['ironic_url'] + ) diff --git a/plugins/modules/baremetal_inspect.py b/plugins/modules/baremetal_inspect.py index d85191d1..f7d90d1c 100644 --- a/plugins/modules/baremetal_inspect.py +++ b/plugins/modules/baremetal_inspect.py @@ -75,10 +75,14 @@ EXAMPLES = ''' name: "testnode1" ''' -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec, - openstack_module_kwargs, - openstack_cloud_from_module) +from ansible_collections.openstack.cloud.plugins.module_utils.ironic import ( + IronicModule, + ironic_argument_spec, +) +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import ( + openstack_module_kwargs, + openstack_cloud_from_module +) def _choose_id_value(module): @@ -90,37 +94,14 @@ def _choose_id_value(module): def main(): - argument_spec = openstack_full_argument_spec( - auth_type=dict(required=False), + argument_spec = ironic_argument_spec( uuid=dict(required=False), name=dict(required=False), mac=dict(required=False), - ironic_url=dict(required=False), timeout=dict(default=1200, type='int', required=False), ) module_kwargs = openstack_module_kwargs() - module = AnsibleModule(argument_spec, **module_kwargs) - - if ( - module.params['auth_type'] in [None, 'None', 'none'] - and module.params['ironic_url'] is None - and not module.params['cloud'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.fail_json(msg="Authentication appears to be disabled, " - "Please define either ironic_url, or cloud, " - "or auth.endpoint") - - if ( - module.params['ironic_url'] - and module.params['auth_type'] in [None, 'None', 'none'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.params['auth'] = dict( - endpoint=module.params['ironic_url'] - ) + module = IronicModule(argument_spec, **module_kwargs) sdk, cloud = openstack_cloud_from_module(module) try: diff --git a/plugins/modules/baremetal_node.py b/plugins/modules/baremetal_node.py index e8c51067..e5031d80 100644 --- a/plugins/modules/baremetal_node.py +++ b/plugins/modules/baremetal_node.py @@ -164,10 +164,15 @@ try: except ImportError: HAS_JSONPATCH = False -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec, - openstack_module_kwargs, - openstack_cloud_from_module) + +from ansible_collections.openstack.cloud.plugins.module_utils.ironic import ( + IronicModule, + ironic_argument_spec, +) +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import ( + openstack_module_kwargs, + openstack_cloud_from_module +) def _parse_properties(module): @@ -225,14 +230,13 @@ def _exit_node_not_updated(module, server): def main(): - argument_spec = openstack_full_argument_spec( + argument_spec = ironic_argument_spec( uuid=dict(required=False), name=dict(required=False), driver=dict(required=False), driver_info=dict(type='dict', required=True), nics=dict(type='list', required=True, elements="dict"), properties=dict(type='dict', default={}), - ironic_url=dict(required=False), chassis_uuid=dict(required=False), skip_update_of_masked_password=dict( required=False, @@ -243,30 +247,10 @@ def main(): state=dict(required=False, default='present', choices=['present', 'absent']) ) module_kwargs = openstack_module_kwargs() - module = AnsibleModule(argument_spec, **module_kwargs) + module = IronicModule(argument_spec, **module_kwargs) if not HAS_JSONPATCH: module.fail_json(msg='jsonpatch is required for this module') - if ( - module.params['auth_type'] in [None, 'None', 'none'] - and module.params['ironic_url'] is None - and not module.params['cloud'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.fail_json(msg="Authentication appears to be disabled, " - "Please define either ironic_url, or cloud, " - "or auth.endpoint") - - if ( - module.params['ironic_url'] - and module.params['auth_type'] in [None, 'None', 'none'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.params['auth'] = dict( - endpoint=module.params['ironic_url'] - ) node_id = _choose_id_value(module) diff --git a/plugins/modules/baremetal_node_action.py b/plugins/modules/baremetal_node_action.py index ae0bef97..267e4308 100644 --- a/plugins/modules/baremetal_node_action.py +++ b/plugins/modules/baremetal_node_action.py @@ -132,10 +132,15 @@ EXAMPLES = ''' delegate_to: localhost ''' -from ansible.module_utils.basic import AnsibleModule -from ansible_collections.openstack.cloud.plugins.module_utils.openstack import (openstack_full_argument_spec, - openstack_module_kwargs, - openstack_cloud_from_module) + +from ansible_collections.openstack.cloud.plugins.module_utils.ironic import ( + IronicModule, + ironic_argument_spec, +) +from ansible_collections.openstack.cloud.plugins.module_utils.openstack import ( + openstack_module_kwargs, + openstack_cloud_from_module +) def _choose_id_value(module): @@ -227,12 +232,11 @@ def _check_set_power_state(module, cloud, node): def main(): - argument_spec = openstack_full_argument_spec( + argument_spec = ironic_argument_spec( uuid=dict(required=False), name=dict(required=False), instance_info=dict(type='dict', required=False), config_drive=dict(type='raw', required=False), - ironic_url=dict(required=False), state=dict(required=False, default='present'), maintenance=dict(required=False), maintenance_reason=dict(required=False), @@ -242,28 +246,7 @@ def main(): timeout=dict(required=False, type='int', default=1800), ) module_kwargs = openstack_module_kwargs() - module = AnsibleModule(argument_spec, **module_kwargs) - - if ( - module.params['auth_type'] in [None, 'None', 'none'] - and module.params['ironic_url'] is None - and not module.params['cloud'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.fail_json(msg="Authentication appears to be disabled, " - "Please define either ironic_url, or cloud, " - "or auth.endpoint") - - if ( - module.params['ironic_url'] - and module.params['auth_type'] in [None, 'None', 'none'] - and not (module.params['auth'] - and module.params['auth'].get('endpoint')) - ): - module.params['auth'] = dict( - endpoint=module.params['ironic_url'] - ) + module = IronicModule(argument_spec, **module_kwargs) if ( module.params['config_drive']