From 0f893027c47560777f5295a338238a820c6c954b Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Thu, 15 Feb 2018 08:20:49 -0600 Subject: [PATCH] Add a module_utils OpenStack Cloud constructor (#20974) Start using this to construct shade OpenStack Cloud objects in a consistent manner. This will let us centralize things like dealing with password arguments and whatnot. It also allows us to introduce the ability to pass a fully formed config dict directly to the module. Migrate all OpenStack modules to use openstack_cloud_from_module. Have it return the shade library since it's responsible for importing shade and shade is needed for the exceptions. Only pull specific OpenStack arguments for the constructor Rather than passing **module.params to the shade constructor, pull out only the values that make sense. This should prevent the issues with module parameters stepping on shade parameters. Replace module.params.pop with module.params.get We don't need to pop these anymore since the shade constructor is now using opt-in values. Using real urls is ungood. Use example.com domains. Also, get rid of the antiquated port numbers. --- contrib/inventory/openstack.yml | 20 +++---- lib/ansible/module_utils/openstack.py | 54 ++++++++++++++++--- .../modules/cloud/openstack/os_auth.py | 14 +---- .../cloud/openstack/os_flavor_facts.py | 39 ++++++-------- .../modules/cloud/openstack/os_floating_ip.py | 23 +++----- .../modules/cloud/openstack/os_group.py | 18 ++----- .../modules/cloud/openstack/os_image.py | 15 ++---- .../modules/cloud/openstack/os_image_facts.py | 15 ++---- .../modules/cloud/openstack/os_ironic.py | 16 ++---- .../cloud/openstack/os_ironic_inspect.py | 19 ++----- .../modules/cloud/openstack/os_ironic_node.py | 23 +++----- .../modules/cloud/openstack/os_keypair.py | 13 +---- .../cloud/openstack/os_keystone_domain.py | 13 +---- .../openstack/os_keystone_domain_facts.py | 14 +---- .../cloud/openstack/os_keystone_endpoint.py | 22 +++----- .../cloud/openstack/os_keystone_role.py | 17 ++---- .../cloud/openstack/os_keystone_service.py | 19 +------ .../modules/cloud/openstack/os_network.py | 25 ++------- .../cloud/openstack/os_networks_facts.py | 19 ++----- .../modules/cloud/openstack/os_nova_flavor.py | 13 +---- .../cloud/openstack/os_nova_host_aggregate.py | 18 +------ .../modules/cloud/openstack/os_object.py | 14 +---- .../modules/cloud/openstack/os_port.py | 22 +++----- .../modules/cloud/openstack/os_port_facts.py | 17 ++---- .../modules/cloud/openstack/os_project.py | 30 ++++------- .../cloud/openstack/os_project_facts.py | 14 +---- .../modules/cloud/openstack/os_quota.py | 29 ++++------ .../modules/cloud/openstack/os_recordset.py | 18 +------ .../modules/cloud/openstack/os_router.py | 23 +++----- .../cloud/openstack/os_security_group.py | 13 +---- .../cloud/openstack/os_security_group_rule.py | 13 +---- .../modules/cloud/openstack/os_server.py | 32 ++++------- .../cloud/openstack/os_server_action.py | 38 +++++-------- .../cloud/openstack/os_server_facts.py | 14 ++--- .../cloud/openstack/os_server_group.py | 17 ++---- .../cloud/openstack/os_server_volume.py | 16 ++---- .../modules/cloud/openstack/os_stack.py | 29 ++++------ .../modules/cloud/openstack/os_subnet.py | 22 ++------ .../cloud/openstack/os_subnets_facts.py | 19 ++----- .../modules/cloud/openstack/os_user.py | 18 ++----- .../modules/cloud/openstack/os_user_facts.py | 14 +---- .../modules/cloud/openstack/os_user_group.py | 14 +---- .../modules/cloud/openstack/os_user_role.py | 31 ++++------- .../modules/cloud/openstack/os_volume.py | 16 ++---- .../modules/cloud/openstack/os_zone.py | 18 +------ .../utils/module_docs_fragments/openstack.py | 20 +++---- .../modules/cloud/openstack/test_os_server.py | 3 ++ 47 files changed, 270 insertions(+), 673 deletions(-) diff --git a/contrib/inventory/openstack.yml b/contrib/inventory/openstack.yml index 84c5eefd79..8d0cb291b4 100644 --- a/contrib/inventory/openstack.yml +++ b/contrib/inventory/openstack.yml @@ -1,18 +1,10 @@ clouds: - mordred: - cloud: hp + vexxhost: + profile: vexxhost auth: - username: mordred@example.com - password: my-wonderful-password - project_name: mordred-tenant - region_name: region-b.geo-1 - monty: - cloud: hp - auth: - username: monty.taylor@example.com - password: another-wonderful-password - project_name: monty.taylor@example.com-default-tenant - region_name: region-b.geo-1 + project_name: 39e296b2-fc96-42bf-8091-cb742fa13da9 + username: fb886a9b-c37b-442a-9be3-964bed961e04 + password: fantastic-password1 rax: cloud: rackspace auth: @@ -22,7 +14,7 @@ clouds: region_name: DFW,ORD,IAD devstack: auth: - auth_url: http://127.0.0.1:35357/v2.0/ + auth_url: https://devstack.example.com username: stack password: stack project_name: stack diff --git a/lib/ansible/module_utils/openstack.py b/lib/ansible/module_utils/openstack.py index 9cfc6cba0c..434a6561ef 100644 --- a/lib/ansible/module_utils/openstack.py +++ b/lib/ansible/module_utils/openstack.py @@ -76,7 +76,7 @@ def openstack_find_nova_addresses(addresses, ext_tag, key_name=None): def openstack_full_argument_spec(**kwargs): spec = dict( - cloud=dict(default=None), + cloud=dict(default=None, type='raw'), auth_type=dict(default=None), auth=dict(default=None, type='dict', no_log=True), region_name=dict(default=None), @@ -88,12 +88,9 @@ def openstack_full_argument_spec(**kwargs): wait=dict(default=True, type='bool'), timeout=dict(default=180, type='int'), api_timeout=dict(default=None, type='int'), - endpoint_type=dict( - default='public', choices=['public', 'internal', 'admin'] - ), - identity_api_version=dict( - default=None, choices=['2.0', '3'] - ) + interface=dict( + default='public', choices=['public', 'internal', 'admin'], + aliases=['endpoint_type']), ) spec.update(kwargs) return spec @@ -109,3 +106,46 @@ def openstack_module_kwargs(**kwargs): ret[key] = kwargs[key] return ret + + +def openstack_cloud_from_module(module, min_version=None): + from distutils.version import StrictVersion + try: + import shade + except ImportError: + module.fail_json(msg='shade is required for this module') + + if min_version: + if StrictVersion(shade.__version__) < StrictVersion(min_version): + module.fail_json( + msg="To utilize this module, the installed version of" + "the shade library MUST be >={min_version}".format( + min_version=min_version)) + + cloud_config = module.params.pop('cloud', None) + if isinstance(cloud_config, dict): + fail_message = ( + "A cloud config dict was provided to the cloud parameter" + " but also a value was provided for {param}. If a cloud" + " config dict is provided, {param} should be" + " excluded.") + for param in ( + 'auth', 'region_name', 'verify', + 'cacert', 'key', 'api_timeout', 'interface'): + if module.params[param] is not None: + module.fail_json(fail_message.format(param=param)) + if module.params['auth_type'] != 'password': + module.fail_json(fail_message.format(param='auth_type')) + return shade, shade.operator_cloud(**cloud_config) + else: + return shade, shade.operator_cloud( + cloud=cloud_config, + auth_type=module.params['auth_type'], + auth=module.params['auth'], + region_name=module.params['region_name'], + verify=module.params['verify'], + cacert=module.params['cacert'], + key=module.params['key'], + api_timeout=module.params['api_timeout'], + interface=module.params['interface'], + ) diff --git a/lib/ansible/modules/cloud/openstack/os_auth.py b/lib/ansible/modules/cloud/openstack/os_auth.py index 81e8f28a50..f88759f084 100644 --- a/lib/ansible/modules/cloud/openstack/os_auth.py +++ b/lib/ansible/modules/cloud/openstack/os_auth.py @@ -43,15 +43,8 @@ EXAMPLES = ''' import traceback -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - -# this is magic, see lib/ansible/module_common.py from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -60,11 +53,8 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) module.exit_json( changed=False, ansible_facts=dict( diff --git a/lib/ansible/modules/cloud/openstack/os_flavor_facts.py b/lib/ansible/modules/cloud/openstack/os_flavor_facts.py index 4eba8e7518..d01ce36e6e 100644 --- a/lib/ansible/modules/cloud/openstack/os_flavor_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_flavor_facts.py @@ -11,7 +11,6 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} - DOCUMENTATION = ''' --- module: os_flavor_facts @@ -171,16 +170,9 @@ openstack_flavors: sample: true ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -200,33 +192,34 @@ def main(): ) module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] vcpus = module.params['vcpus'] ram = module.params['ram'] ephemeral = module.params['ephemeral'] limit = module.params['limit'] + filters = {} + if vcpus: + filters['vcpus'] = vcpus + if ram: + filters['ram'] = ram + if ephemeral: + filters['ephemeral'] = ephemeral + + if filters: + # Range search added in 1.5.0 + min_version = '1.5.0' + else: + min_version = None + + shade, cloud = openstack_cloud_from_module(module, min_version=min_version) try: - cloud = shade.openstack_cloud(**module.params) if name: flavors = cloud.search_flavors(filters={'name': name}) else: flavors = cloud.list_flavors() - filters = {} - if vcpus: - filters['vcpus'] = vcpus - if ram: - filters['ram'] = ram - if ephemeral: - filters['ephemeral'] = ephemeral if filters: - # Range search added in 1.5.0 - if StrictVersion(shade.__version__) < StrictVersion('1.5.0'): - module.fail_json(msg="Shade >= 1.5.0 needed for this functionality") flavors = cloud.range_search(flavors, filters) if limit is not None: diff --git a/lib/ansible/modules/cloud/openstack/os_floating_ip.py b/lib/ansible/modules/cloud/openstack/os_floating_ip.py index 0465b28682..4f6b69f3ab 100644 --- a/lib/ansible/modules/cloud/openstack/os_floating_ip.py +++ b/lib/ansible/modules/cloud/openstack/os_floating_ip.py @@ -128,16 +128,8 @@ EXAMPLES = ''' server: cattle001 ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule, remove_values -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _get_floating_ip(cloud, floating_ip_address): @@ -167,13 +159,10 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - - if (module.params['nat_destination'] and - StrictVersion(shade.__version__) < StrictVersion('1.8.0')): - module.fail_json(msg="To utilize nat_destination, the installed version of" - "the shade library MUST be >= 1.8.0") + if module.params['nat_destination']: + min_version = '1.8.0' + else: + min_version = None server_name_or_id = module.params['server'] state = module.params['state'] @@ -186,7 +175,7 @@ def main(): timeout = module.params['timeout'] purge = module.params['purge'] - cloud = shade.openstack_cloud(**module.params) + shade, cloud = openstack_cloud_from_module(module, min_version=min_version) try: server = cloud.get_server(server_name_or_id) diff --git a/lib/ansible/modules/cloud/openstack/os_group.py b/lib/ansible/modules/cloud/openstack/os_group.py index a20e065928..4e469b5494 100644 --- a/lib/ansible/modules/cloud/openstack/os_group.py +++ b/lib/ansible/modules/cloud/openstack/os_group.py @@ -99,14 +99,8 @@ group: sample: "default" ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, description, group): @@ -132,16 +126,14 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') + name = module.params.get('name') + description = module.params.get('description') + state = module.params.get('state') - name = module.params.pop('name') - description = module.params.pop('description') domain_id = module.params.pop('domain_id') - state = module.params.pop('state') + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) if domain_id: group = cloud.get_group(name, filters={'domain_id': domain_id}) else: diff --git a/lib/ansible/modules/cloud/openstack/os_image.py b/lib/ansible/modules/cloud/openstack/os_image.py index faf090de3c..5052abcddc 100644 --- a/lib/ansible/modules/cloud/openstack/os_image.py +++ b/lib/ansible/modules/cloud/openstack/os_image.py @@ -108,7 +108,7 @@ EXAMPLES = ''' # Upload an image from a local file named cirros-0.3.0-x86_64-disk.img - os_image: auth: - auth_url: http://localhost/auth/v2.0 + auth_url: https://identity.example.com username: admin password: passme project_name: admin @@ -124,14 +124,8 @@ EXAMPLES = ''' distro: ubuntu ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -155,11 +149,8 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) changed = False if module.params['checksum']: diff --git a/lib/ansible/modules/cloud/openstack/os_image_facts.py b/lib/ansible/modules/cloud/openstack/os_image_facts.py index 46144cabe2..6a55669f28 100644 --- a/lib/ansible/modules/cloud/openstack/os_image_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_image_facts.py @@ -40,7 +40,7 @@ EXAMPLES = ''' - name: Gather facts about a previously created image named image1 os_image_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -127,14 +127,8 @@ openstack_image: type: int ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -145,11 +139,8 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) image = cloud.get_image(module.params['image']) module.exit_json(changed=False, ansible_facts=dict( openstack_image=image)) diff --git a/lib/ansible/modules/cloud/openstack/os_ironic.py b/lib/ansible/modules/cloud/openstack/os_ironic.py index 3488688b56..689530c6fc 100644 --- a/lib/ansible/modules/cloud/openstack/os_ironic.py +++ b/lib/ansible/modules/cloud/openstack/os_ironic.py @@ -148,14 +148,8 @@ try: except ImportError: HAS_JSONPATCH = False -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _parse_properties(module): @@ -169,7 +163,7 @@ def _parse_properties(module): return props -def _parse_driver_info(module): +def _parse_driver_info(shade, module): p = module.params['driver_info'] info = p.get('power') if not info: @@ -226,8 +220,6 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') if not HAS_JSONPATCH: module.fail_json(msg='jsonpatch is required for this module') if (module.params['auth_type'] in [None, 'None'] and @@ -243,8 +235,8 @@ def main(): node_id = _choose_id_value(module) + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) server = cloud.get_machine(node_id) if module.params['state'] == 'present': if module.params['driver'] is None: @@ -252,7 +244,7 @@ def main(): "to set a node to present.") properties = _parse_properties(module) - driver_info = _parse_driver_info(module) + driver_info = _parse_driver_info(shade, module) kwargs = dict( driver=module.params['driver'], properties=properties, diff --git a/lib/ansible/modules/cloud/openstack/os_ironic_inspect.py b/lib/ansible/modules/cloud/openstack/os_ironic_inspect.py index 348e76f452..2137335d53 100644 --- a/lib/ansible/modules/cloud/openstack/os_ironic_inspect.py +++ b/lib/ansible/modules/cloud/openstack/os_ironic_inspect.py @@ -89,16 +89,8 @@ EXAMPLES = ''' name: "testnode1" ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _choose_id_value(module): @@ -121,12 +113,6 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) < StrictVersion('1.0.0'): - module.fail_json(msg="To utilize this module, the installed version of" - "the shade library MUST be >=1.0.0") - if (module.params['auth_type'] in [None, 'None'] and module.params['ironic_url'] is None): module.fail_json(msg="Authentication appears to be disabled, " @@ -138,8 +124,9 @@ def main(): endpoint=module.params['ironic_url'] ) + shade, cloud = openstack_cloud_from_module( + module, min_version='1.0.0') try: - cloud = shade.operator_cloud(**module.params) if module.params['name'] or module.params['uuid']: server = cloud.get_machine(_choose_id_value(module)) diff --git a/lib/ansible/modules/cloud/openstack/os_ironic_node.py b/lib/ansible/modules/cloud/openstack/os_ironic_node.py index 691243e55d..38624e5df2 100644 --- a/lib/ansible/modules/cloud/openstack/os_ironic_node.py +++ b/lib/ansible/modules/cloud/openstack/os_ironic_node.py @@ -122,16 +122,8 @@ os_ironic_node: delegate_to: localhost ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _choose_id_value(module): @@ -245,13 +237,11 @@ def main(): ) module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if (module.params['wait'] and - StrictVersion(shade.__version__) < StrictVersion('1.4.0')): - module.fail_json(msg="To utilize wait, the installed version of" - "the shade library MUST be >=1.4.0") + if module.params['wait']: + min_version = '1.4.0' + else: + min_version = None if (module.params['auth_type'] in [None, 'None'] and module.params['ironic_url'] is None): @@ -269,8 +259,9 @@ def main(): if not node_id: module.fail_json(msg="A uuid or name value must be defined " "to use this module.") + shade, cloud = openstack_cloud_from_module( + module, min_version=min_version) try: - cloud = shade.operator_cloud(**module.params) node = cloud.get_machine(node_id) if node is None: diff --git a/lib/ansible/modules/cloud/openstack/os_keypair.py b/lib/ansible/modules/cloud/openstack/os_keypair.py index bc9eff7dfe..b1aff29a52 100644 --- a/lib/ansible/modules/cloud/openstack/os_keypair.py +++ b/lib/ansible/modules/cloud/openstack/os_keypair.py @@ -88,14 +88,8 @@ private_key: type: string ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(module, keypair): @@ -123,9 +117,6 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] name = module.params['name'] public_key = module.params['public_key'] @@ -134,8 +125,8 @@ def main(): public_key = open(module.params['public_key_file']).read() public_key = public_key.rstrip() + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) keypair = cloud.get_keypair(name) if module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_domain.py b/lib/ansible/modules/cloud/openstack/os_keystone_domain.py index 6b018cb42b..172fef4767 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_domain.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_domain.py @@ -98,14 +98,8 @@ id: sample: "474acfe5-be34-494c-b339-50f06aa143e4" ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, domain): @@ -143,16 +137,13 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] description = module.params['description'] enabled = module.params['enabled'] state = module.params['state'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) domains = cloud.search_domains(filters=dict(name=name)) diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py b/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py index 42d94bb310..e814eb011e 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py @@ -89,14 +89,8 @@ openstack_domains: type: bool ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -112,15 +106,11 @@ def main(): ) module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, opcloud = openstack_cloud_from_module(module) try: name = module.params['name'] filters = module.params['filters'] - opcloud = shade.operator_cloud(**module.params) - if name: # Let's suppose user is passing domain ID try: diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_endpoint.py b/lib/ansible/modules/cloud/openstack/os_keystone_endpoint.py index 532247b642..b87a8b405f 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_endpoint.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_endpoint.py @@ -59,7 +59,7 @@ EXAMPLES = ''' os_keystone_endpoint: cloud: mycloud service: glance - interface: public + endpoint_interface: public url: http://controller:9292 region: RegionOne state: present @@ -68,7 +68,7 @@ EXAMPLES = ''' os_keystone_endpoint: cloud: mycloud service: nova - interface: public + endpoint_interface: public region: RegionOne state: absent ''' @@ -107,14 +107,8 @@ endpoint: from distutils.version import StrictVersion -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, endpoint): @@ -141,7 +135,7 @@ def _system_state_change(module, endpoint): def main(): argument_spec = openstack_full_argument_spec( service=dict(type='str', required=True), - interface=dict(type='str', required=True, choices=['admin', 'public', 'internal']), + endpoint_interface=dict(type='str', required=True, choices=['admin', 'public', 'internal']), url=dict(type='str', required=True), region=dict(type='str'), enabled=dict(type='bool', default=True), @@ -153,14 +147,10 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) < StrictVersion('1.11.0'): - module.fail_json(msg="To utilize this module, the installed version of" - "the shade library MUST be >=1.11.0") + shade, cloud = openstack_cloud_from_module(module, min_version='1.11.0') service_name_or_id = module.params['service'] - interface = module.params['interface'] + interface = module.params['endpoint_interface'] url = module.params['url'] region = module.params['region'] enabled = module.params['enabled'] diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_role.py b/lib/ansible/modules/cloud/openstack/os_keystone_role.py index 0af66ead09..369971a99a 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_role.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_role.py @@ -69,14 +69,8 @@ role: sample: "demo" ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, role): @@ -98,14 +92,11 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - - name = module.params.pop('name') - state = module.params.pop('state') + name = module.params.get('name') + state = module.params.get('state') + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) role = cloud.get_role(name) diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_service.py b/lib/ansible/modules/cloud/openstack/os_keystone_service.py index 2caee8254e..20eff9ef63 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_service.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_service.py @@ -104,16 +104,8 @@ id: sample: "3292f020780b4d5baf27ff7e1d224c44" ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, service): @@ -152,21 +144,14 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) < StrictVersion('1.6.0'): - module.fail_json(msg="To utilize this module, the installed version of" - "the shade library MUST be >=1.6.0") - description = module.params['description'] enabled = module.params['enabled'] name = module.params['name'] state = module.params['state'] service_type = module.params['service_type'] + shade, cloud = openstack_cloud_from_module(module, min_version='1.6.0') try: - cloud = shade.operator_cloud(**module.params) - services = cloud.search_services(name_or_id=name, filters=dict(type=service_type)) diff --git a/lib/ansible/modules/cloud/openstack/os_network.py b/lib/ansible/modules/cloud/openstack/os_network.py index 9fb5a167dd..b63c152955 100644 --- a/lib/ansible/modules/cloud/openstack/os_network.py +++ b/lib/ansible/modules/cloud/openstack/os_network.py @@ -151,16 +151,8 @@ network: sample: 101 ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -179,14 +171,6 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - - if (module.params['project'] and - StrictVersion(shade.__version__) < StrictVersion('1.6.0')): - module.fail_json(msg="To utilize project, the installed version of" - "the shade library MUST be >=1.6.0") - state = module.params['state'] name = module.params['name'] shared = module.params['shared'] @@ -195,10 +179,10 @@ def main(): provider_physical_network = module.params['provider_physical_network'] provider_network_type = module.params['provider_network_type'] provider_segmentation_id = module.params['provider_segmentation_id'] - project = module.params.pop('project') + project = module.params.get('project') + shade, cloud = openstack_cloud_from_module(module, min_version='1.6.0') try: - cloud = shade.openstack_cloud(**module.params) if project is not None: proj = cloud.get_project(project) if proj is None: @@ -220,9 +204,6 @@ def main(): if provider_segmentation_id: provider['segmentation_id'] = provider_segmentation_id - if provider and StrictVersion(shade.__version__) < StrictVersion('1.5.0'): - module.fail_json(msg="Shade >= 1.5.0 required to use provider options") - if project_id is not None: net = cloud.create_network(name, shared, admin_state_up, external, provider, project_id) diff --git a/lib/ansible/modules/cloud/openstack/os_networks_facts.py b/lib/ansible/modules/cloud/openstack/os_networks_facts.py index 46b2dfcf02..9795e38c23 100644 --- a/lib/ansible/modules/cloud/openstack/os_networks_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_networks_facts.py @@ -44,7 +44,7 @@ EXAMPLES = ''' - name: Gather facts about previously created networks os_networks_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -56,7 +56,7 @@ EXAMPLES = ''' - name: Gather facts about a previously created network by name os_networks_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -70,7 +70,7 @@ EXAMPLES = ''' # Note: name and filters parameters are Not mutually exclusive os_networks_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -117,14 +117,8 @@ openstack_networks: type: boolean ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_cloud_from_module def main(): @@ -135,11 +129,8 @@ def main(): ) module = AnsibleModule(argument_spec) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) networks = cloud.search_networks(module.params['name'], module.params['filters']) module.exit_json(changed=False, ansible_facts=dict( diff --git a/lib/ansible/modules/cloud/openstack/os_nova_flavor.py b/lib/ansible/modules/cloud/openstack/os_nova_flavor.py index 6d2d5f6ebc..733c4f5e04 100644 --- a/lib/ansible/modules/cloud/openstack/os_nova_flavor.py +++ b/lib/ansible/modules/cloud/openstack/os_nova_flavor.py @@ -173,14 +173,8 @@ flavor: "aggregate_instance_extra_specs:pinned": false ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(module, flavor): @@ -220,15 +214,12 @@ def main(): ], **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] name = module.params['name'] extra_specs = module.params['extra_specs'] or {} + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) flavor = cloud.get_flavor(name) if module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_nova_host_aggregate.py b/lib/ansible/modules/cloud/openstack/os_nova_host_aggregate.py index 6b78ffa84c..1cca6a9262 100644 --- a/lib/ansible/modules/cloud/openstack/os_nova_host_aggregate.py +++ b/lib/ansible/modules/cloud/openstack/os_nova_host_aggregate.py @@ -69,16 +69,8 @@ RETURN = ''' ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, aggregate): @@ -123,12 +115,6 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) < StrictVersion('1.9.0'): - module.fail_json(msg="To utilize this module, the installed version of" - "the shade library MUST be >=1.9.0") - name = module.params['name'] metadata = module.params['metadata'] availability_zone = module.params['availability_zone'] @@ -138,8 +124,8 @@ def main(): if metadata is not None: metadata.pop('availability_zone', None) + shade, cloud = openstack_cloud_from_module(module, min_version='1.9.0') try: - cloud = shade.operator_cloud(**module.params) aggregates = cloud.search_aggregates(name_or_id=name) if len(aggregates) == 1: diff --git a/lib/ansible/modules/cloud/openstack/os_object.py b/lib/ansible/modules/cloud/openstack/os_object.py index 54db16ddb7..38e867b965 100644 --- a/lib/ansible/modules/cloud/openstack/os_object.py +++ b/lib/ansible/modules/cloud/openstack/os_object.py @@ -69,14 +69,8 @@ EXAMPLES = ''' container: config ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def process_object( @@ -118,12 +112,8 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) - changed = process_object(cloud, **module.params) module.exit_json(changed=changed) diff --git a/lib/ansible/modules/cloud/openstack/os_port.py b/lib/ansible/modules/cloud/openstack/os_port.py index 07f6074b36..7da2e021ed 100644 --- a/lib/ansible/modules/cloud/openstack/os_port.py +++ b/lib/ansible/modules/cloud/openstack/os_port.py @@ -105,7 +105,7 @@ EXAMPLES = ''' - os_port: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -116,7 +116,7 @@ EXAMPLES = ''' - os_port: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -129,7 +129,7 @@ EXAMPLES = ''' - os_port: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -141,7 +141,7 @@ EXAMPLES = ''' - os_port: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/d + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -152,7 +152,7 @@ EXAMPLES = ''' - os_port: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/d + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -201,14 +201,8 @@ admin_state_up: type: bool ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, port, cloud): @@ -329,13 +323,11 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') name = module.params['name'] state = module.params['state'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) if module.params['security_groups']: # translate security_groups to UUID's if names where provided module.params['security_groups'] = [ diff --git a/lib/ansible/modules/cloud/openstack/os_port_facts.py b/lib/ansible/modules/cloud/openstack/os_port_facts.py index 70b8dab26a..26d8edf64f 100644 --- a/lib/ansible/modules/cloud/openstack/os_port_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_port_facts.py @@ -189,14 +189,8 @@ openstack_ports: sample: "51fce036d7984ba6af4f6c849f65ef00" ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -207,14 +201,11 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - - port = module.params.pop('port') - filters = module.params.pop('filters') + port = module.params.get('port') + filters = module.params.get('filters') + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) ports = cloud.search_ports(port, filters) module.exit_json(changed=False, ansible_facts=dict( openstack_ports=ports)) diff --git a/lib/ansible/modules/cloud/openstack/os_project.py b/lib/ansible/modules/cloud/openstack/os_project.py index db3e3dba35..95ba9afe83 100644 --- a/lib/ansible/modules/cloud/openstack/os_project.py +++ b/lib/ansible/modules/cloud/openstack/os_project.py @@ -102,16 +102,8 @@ project: sample: True ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, project): @@ -159,37 +151,35 @@ def main(): **module_kwargs ) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] description = module.params['description'] - domain = module.params.pop('domain_id') + domain = module.params.get('domain_id') enabled = module.params['enabled'] state = module.params['state'] - if domain and StrictVersion(shade.__version__) < StrictVersion('1.8.0'): - module.fail_json(msg="The domain argument requires shade >=1.8.0") + if domain: + min_version = '1.8.0' + else: + min_version = None + shade, cloud = openstack_cloud_from_module( + module, min_version=min_version) try: if domain: - opcloud = shade.operator_cloud(**module.params) try: # We assume admin is passing domain id - dom = opcloud.get_domain(domain)['id'] + dom = cloud.get_domain(domain)['id'] domain = dom except: # If we fail, maybe admin is passing a domain name. # Note that domains have unique names, just like id. try: - dom = opcloud.search_domains(filters={'name': domain})[0]['id'] + dom = cloud.search_domains(filters={'name': domain})[0]['id'] domain = dom except: # Ok, let's hope the user is non-admin and passing a sane id pass - cloud = shade.openstack_cloud(**module.params) - if domain: project = cloud.get_project(name, domain_id=domain) else: diff --git a/lib/ansible/modules/cloud/openstack/os_project_facts.py b/lib/ansible/modules/cloud/openstack/os_project_facts.py index 5c38eb8fca..f6c2f1f6a4 100644 --- a/lib/ansible/modules/cloud/openstack/os_project_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_project_facts.py @@ -107,14 +107,8 @@ openstack_projects: type: bool ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_cloud_from_module def main(): @@ -127,16 +121,12 @@ def main(): module = AnsibleModule(argument_spec) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, opcloud = openstack_cloud_from_module(module) try: name = module.params['name'] domain = module.params['domain'] filters = module.params['filters'] - opcloud = shade.operator_cloud(**module.params) - if domain: try: # We assume admin is passing domain id diff --git a/lib/ansible/modules/cloud/openstack/os_quota.py b/lib/ansible/modules/cloud/openstack/os_quota.py index c319b12ddb..c78e5409d5 100644 --- a/lib/ansible/modules/cloud/openstack/os_quota.py +++ b/lib/ansible/modules/cloud/openstack/os_quota.py @@ -291,15 +291,8 @@ openstack_quotas: ''' -try: - import shade - from keystoneauth1 import exceptions - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _get_volume_quotas(cloud, project): @@ -317,17 +310,17 @@ def _get_compute_quotas(cloud, project): return cloud.get_compute_quotas(project) -def _get_quotas(module, cloud, project): +def _get_quotas(shade, module, cloud, project): quota = {} try: quota['volume'] = _get_volume_quotas(cloud, project) - except exceptions.EndpointNotFound: + except shade.OpenStackCloudURINotFound: module.warn("No public endpoint for volumev2 service was found. Ignoring volume quotas.") try: quota['network'] = _get_network_quotas(cloud, project) - except exceptions.EndpointNotFound: + except shade.OpenStackCloudURINotFound: module.warn("No public endpoint for network service was found. Ignoring network quotas.") quota['compute'] = _get_compute_quotas(cloud, project) @@ -437,12 +430,9 @@ def main(): supports_check_mode=True ) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: cloud_params = dict(module.params) - cloud = shade.operator_cloud(**cloud_params) # In order to handle the different volume types we update module params after. dynamic_types = [ @@ -456,7 +446,8 @@ def main(): module.params[k] = int(v) # Get current quota values - project_quota_output = _get_quotas(module, cloud, cloud_params['name']) + project_quota_output = _get_quotas( + shade, module, cloud, cloud_params['name']) changes_required = False if module.params['state'] == "absent": @@ -485,7 +476,8 @@ def main(): else: module.fail_json(msg=str(e), extra_data=e.extra_data) - project_quota_output = _get_quotas(module, cloud, cloud_params['name']) + project_quota_output = _get_quotas( + shade, module, cloud, cloud_params['name']) changes_required = True elif module.params['state'] == "present": @@ -503,7 +495,8 @@ def main(): quota_call(cloud_params['name'], **quota_change_request[quota_type]) # Get quota state post changes for validation - project_quota_update = _get_quotas(module, cloud, cloud_params['name']) + project_quota_update = _get_quotas( + shade, module, cloud, cloud_params['name']) if project_quota_output == project_quota_update: module.fail_json(msg='Could not apply quota update') diff --git a/lib/ansible/modules/cloud/openstack/os_recordset.py b/lib/ansible/modules/cloud/openstack/os_recordset.py index 7ec2c215c6..f88b7067f1 100644 --- a/lib/ansible/modules/cloud/openstack/os_recordset.py +++ b/lib/ansible/modules/cloud/openstack/os_recordset.py @@ -127,16 +127,8 @@ recordset: sample: ['10.0.0.1'] ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, records, description, ttl, zone, recordset): @@ -173,18 +165,12 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) <= StrictVersion('1.8.0'): - module.fail_json(msg="To utilize this module, the installed version of " - "the shade library MUST be >1.8.0") - zone = module.params.get('zone') name = module.params.get('name') state = module.params.get('state') + shade, cloud = openstack_cloud_from_module(module, min_version='1.9.0') try: - cloud = shade.openstack_cloud(**module.params) recordset_type = module.params.get('recordset_type') recordset_filter = {'type': recordset_type} diff --git a/lib/ansible/modules/cloud/openstack/os_router.py b/lib/ansible/modules/cloud/openstack/os_router.py index 760ea3133e..fe5a6cb0d5 100644 --- a/lib/ansible/modules/cloud/openstack/os_router.py +++ b/lib/ansible/modules/cloud/openstack/os_router.py @@ -215,16 +215,8 @@ router: type: list ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module ROUTER_INTERFACE_OWNERS = set([ @@ -401,13 +393,10 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - - if (module.params['project'] and - StrictVersion(shade.__version__) <= StrictVersion('1.9.0')): - module.fail_json(msg="To utilize project, the installed version of" - "the shade library MUST be > 1.9.0") + if module.params['project']: + min_version = '1.10.0' + else: + min_version = None state = module.params['state'] name = module.params['name'] @@ -417,8 +406,8 @@ def main(): if module.params['external_fixed_ips'] and not network: module.fail_json(msg='network is required when supplying external_fixed_ips') + shade, cloud = openstack_cloud_from_module(module, min_version=min_version) try: - cloud = shade.openstack_cloud(**module.params) if project is not None: proj = cloud.get_project(project) if proj is None: diff --git a/lib/ansible/modules/cloud/openstack/os_security_group.py b/lib/ansible/modules/cloud/openstack/os_security_group.py index cfa17902ac..03d11e1bc4 100644 --- a/lib/ansible/modules/cloud/openstack/os_security_group.py +++ b/lib/ansible/modules/cloud/openstack/os_security_group.py @@ -60,14 +60,8 @@ EXAMPLES = ''' description: updated description for the foo security group ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(module, secgroup): @@ -103,15 +97,12 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] state = module.params['state'] description = module.params['description'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) secgroup = cloud.get_security_group(name) if module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_security_group_rule.py b/lib/ansible/modules/cloud/openstack/os_security_group_rule.py index e6c6fac150..9ad9ff67f6 100644 --- a/lib/ansible/modules/cloud/openstack/os_security_group_rule.py +++ b/lib/ansible/modules/cloud/openstack/os_security_group_rule.py @@ -167,14 +167,8 @@ security_group_id: returned: state == present ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _ports_match(protocol, module_min, module_max, rule_min, rule_max): @@ -297,16 +291,13 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] security_group = module.params['security_group'] remote_group = module.params['remote_group'] changed = False + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) secgroup = cloud.get_security_group(security_group) if remote_group: diff --git a/lib/ansible/modules/cloud/openstack/os_server.py b/lib/ansible/modules/cloud/openstack/os_server.py index c4748beb79..e939433c32 100644 --- a/lib/ansible/modules/cloud/openstack/os_server.py +++ b/lib/ansible/modules/cloud/openstack/os_server.py @@ -199,7 +199,7 @@ EXAMPLES = ''' os_server: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -224,7 +224,7 @@ EXAMPLES = ''' os_server: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: username password: Equality7-2521 project_name: username-project1 @@ -291,7 +291,7 @@ EXAMPLES = ''' - name: launch an instance with a string os_server: auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -306,7 +306,7 @@ EXAMPLES = ''' os_server: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -324,7 +324,7 @@ EXAMPLES = ''' os_server: state: present auth: - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -407,20 +407,14 @@ EXAMPLES = ''' ''' -try: - import shade - from shade import meta - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import (openstack_find_nova_addresses, - openstack_full_argument_spec, openstack_module_kwargs) +from ansible.module_utils.openstack import ( + openstack_find_nova_addresses, openstack_cloud_from_module, + openstack_full_argument_spec, openstack_module_kwargs) def _exit_hostvars(module, cloud, server, changed=True): - hostvars = meta.get_hostvars_from_server(cloud, server) + hostvars = cloud.get_openstack_vars(server) module.exit_json( changed=changed, server=server, id=server.id, openstack=hostvars) @@ -727,9 +721,6 @@ def main(): ) module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] image = module.params['image'] boot_volume = module.params['boot_volume'] @@ -748,11 +739,8 @@ def main(): "if state == 'present'" ) + shade, cloud = openstack_cloud_from_module(module) try: - cloud_params = dict(module.params) - cloud_params.pop('userdata', None) - cloud = shade.openstack_cloud(**cloud_params) - if state == 'present': _get_server_state(module, cloud) _create_server(module, cloud) diff --git a/lib/ansible/modules/cloud/openstack/os_server_action.py b/lib/ansible/modules/cloud/openstack/os_server_action.py index de41d9015c..378e659e8f 100644 --- a/lib/ansible/modules/cloud/openstack/os_server_action.py +++ b/lib/ansible/modules/cloud/openstack/os_server_action.py @@ -66,7 +66,7 @@ EXAMPLES = ''' - os_server_action: action: pause auth: - auth_url: https://mycloud.openstack.blueboxgrid.com:5001/v2.0 + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -74,15 +74,8 @@ EXAMPLES = ''' timeout: 200 ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs - +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module _action_map = {'stop': 'SHUTOFF', 'start': 'ACTIVE', @@ -97,7 +90,7 @@ _action_map = {'stop': 'SHUTOFF', _admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock'] -def _wait(timeout, cloud, server, action, module): +def _wait(timeout, cloud, server, action, module, shade): """Wait for the server to reach the desired state for the given action.""" for count in shade._utils._iterate_timeout( @@ -139,19 +132,16 @@ def main(): if module._name == 'os_server_actions': module.deprecate("The 'os_server_actions' module is being renamed 'os_server_action'", version=2.8) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - action = module.params['action'] wait = module.params['wait'] timeout = module.params['timeout'] image = module.params['image'] + if action in _admin_actions: + shade, cloud = openstack_cloud_from_module(module) + else: + shade, cloud = openstack_cloud_from_module(module) try: - if action in _admin_actions: - cloud = shade.operator_cloud(**module.params) - else: - cloud = shade.openstack_cloud(**module.params) server = cloud.get_server(module.params['server']) if not server: module.fail_json(msg='Could not find server %s' % server) @@ -166,7 +156,7 @@ def main(): cloud.nova_client.servers.stop(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) if action == 'start': @@ -175,7 +165,7 @@ def main(): cloud.nova_client.servers.start(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) if action == 'pause': @@ -184,7 +174,7 @@ def main(): cloud.nova_client.servers.pause(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) elif action == 'unpause': @@ -193,7 +183,7 @@ def main(): cloud.nova_client.servers.unpause(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) elif action == 'lock': @@ -212,7 +202,7 @@ def main(): cloud.nova_client.servers.suspend(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) elif action == 'resume': @@ -221,7 +211,7 @@ def main(): cloud.nova_client.servers.resume(server=server.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) elif action == 'rebuild': @@ -233,7 +223,7 @@ def main(): # rebuild doesn't set a state, just do it cloud.nova_client.servers.rebuild(server=server.id, image=image.id) if wait: - _wait(timeout, cloud, server, action, module) + _wait(timeout, cloud, server, action, module, shade) module.exit_json(changed=True) except shade.OpenStackCloudException as e: diff --git a/lib/ansible/modules/cloud/openstack/os_server_facts.py b/lib/ansible/modules/cloud/openstack/os_server_facts.py index 34caa4ca3a..64b5f5d103 100644 --- a/lib/ansible/modules/cloud/openstack/os_server_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_server_facts.py @@ -57,14 +57,8 @@ EXAMPLES = ''' import fnmatch -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -76,17 +70,15 @@ def main(): module_kwargs = openstack_module_kwargs() module = AnsibleModule(argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) openstack_servers = cloud.list_servers( detailed=module.params['detailed']) if module.params['server']: # filter servers by name pattern = module.params['server'] + # TODO(mordred) This is handled by shade now openstack_servers = [server for server in openstack_servers if fnmatch.fnmatch(server['name'], pattern) or fnmatch.fnmatch(server['id'], pattern)] module.exit_json(changed=False, ansible_facts=dict( diff --git a/lib/ansible/modules/cloud/openstack/os_server_group.py b/lib/ansible/modules/cloud/openstack/os_server_group.py index 89a9e76707..d6a29490ac 100644 --- a/lib/ansible/modules/cloud/openstack/os_server_group.py +++ b/lib/ansible/modules/cloud/openstack/os_server_group.py @@ -54,7 +54,7 @@ EXAMPLES = ''' - os_server_group: state: present auth: - auth_url: https://api.cloud.catalyst.net.nz:5000/v2.0 + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -66,7 +66,7 @@ EXAMPLES = ''' - os_server_group: state: absent auth: - auth_url: https://api.cloud.catalyst.net.nz:5000/v2.0 + auth_url: https://identity.example.com username: admin password: admin project_name: admin @@ -104,14 +104,8 @@ user_id: type: string ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, server_group): @@ -136,15 +130,12 @@ def main(): **module_kwargs ) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] policies = module.params['policies'] state = module.params['state'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) server_group = cloud.get_server_group(name) if module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_server_volume.py b/lib/ansible/modules/cloud/openstack/os_server_volume.py index 710107410b..532c26bf60 100644 --- a/lib/ansible/modules/cloud/openstack/os_server_volume.py +++ b/lib/ansible/modules/cloud/openstack/os_server_volume.py @@ -65,15 +65,8 @@ EXAMPLES = ''' device: /dev/vdb ''' -try: - import shade - from shade import meta - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, device): @@ -102,15 +95,12 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] wait = module.params['wait'] timeout = module.params['timeout'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) server = cloud.get_server(module.params['server']) volume = cloud.get_volume(module.params['volume']) dev = cloud.get_volume_attach_device(volume, server.id) @@ -128,7 +118,7 @@ def main(): server = cloud.get_server(module.params['server']) # refresh volume = cloud.get_volume(module.params['volume']) # refresh - hostvars = meta.get_hostvars_from_server(cloud, server) + hostvars = cloud.get_openstack_vars(server) module.exit_json( changed=True, diff --git a/lib/ansible/modules/cloud/openstack/os_stack.py b/lib/ansible/modules/cloud/openstack/os_stack.py index cfde6c0800..f53d33fc5a 100644 --- a/lib/ansible/modules/cloud/openstack/os_stack.py +++ b/lib/ansible/modules/cloud/openstack/os_stack.py @@ -158,19 +158,11 @@ stack: 'updated_time': null}" ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module -def _create_stack(module, stack, cloud): +def _create_stack(module, stack, cloud, shade): try: stack = cloud.create_stack(module.params['name'], tags=module.params['tag'], @@ -190,7 +182,7 @@ def _create_stack(module, stack, cloud): module.fail_json(msg=str(e)) -def _update_stack(module, stack, cloud): +def _update_stack(module, stack, cloud, shade): try: stack = cloud.update_stack( module.params['name'], @@ -238,15 +230,12 @@ def main(): supports_check_mode=True, **module_kwargs) + # stack API introduced in 1.8.0 + min_version = '1.8.0' tag = module.params['tag'] if tag is not None: # stack tag API was introduced in 1.26.0 - if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.26.0')): - module.fail_json(msg='shade 1.26.0 or higher is required for this module') - else: - # stack API introduced in 1.8.0 - if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.8.0')): - module.fail_json(msg='shade 1.8.0 or higher is required for this module') + min_version = '1.26.0' state = module.params['state'] name = module.params['name'] @@ -256,8 +245,8 @@ def main(): if not module.params[p]: module.fail_json(msg='%s required with present state' % p) + shade, cloud = openstack_cloud_from_module(module, min_version='1.26.0') try: - cloud = shade.openstack_cloud(**module.params) stack = cloud.get_stack(name) if module.check_mode: @@ -266,9 +255,9 @@ def main(): if state == 'present': if not stack: - stack = _create_stack(module, stack, cloud) + stack = _create_stack(module, stack, cloud, shade) else: - stack = _update_stack(module, stack, cloud) + stack = _update_stack(module, stack, cloud, shade) changed = True module.exit_json(changed=changed, stack=stack, diff --git a/lib/ansible/modules/cloud/openstack/os_subnet.py b/lib/ansible/modules/cloud/openstack/os_subnet.py index 2daf4d7085..296622d8e3 100644 --- a/lib/ansible/modules/cloud/openstack/os_subnet.py +++ b/lib/ansible/modules/cloud/openstack/os_subnet.py @@ -157,16 +157,8 @@ EXAMPLES = ''' ipv6_address_mode: dhcpv6-stateless ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _can_update(subnet, module, cloud): @@ -270,9 +262,6 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - state = module.params['state'] network_name = module.params['network_name'] cidr = module.params['cidr'] @@ -290,10 +279,9 @@ def main(): use_default_subnetpool = module.params['use_default_subnetpool'] project = module.params.pop('project') - if (use_default_subnetpool and - StrictVersion(shade.__version__) < StrictVersion('1.16.0')): - module.fail_json(msg="To utilize use_default_subnetpool, the installed" - " version of the shade library MUST be >=1.16.0") + min_version = None + if use_default_subnetpool: + min_version = '1.16.0' # Check for required parameters when state == 'present' if state == 'present': @@ -313,8 +301,8 @@ def main(): if no_gateway_ip and gateway_ip: module.fail_json(msg='no_gateway_ip is not allowed with gateway_ip') + shade, cloud = openstack_cloud_from_module(module, min_version=min_version) try: - cloud = shade.openstack_cloud(**module.params) if project is not None: proj = cloud.get_project(project) if proj is None: diff --git a/lib/ansible/modules/cloud/openstack/os_subnets_facts.py b/lib/ansible/modules/cloud/openstack/os_subnets_facts.py index 157530ab3d..8a6382f4d0 100644 --- a/lib/ansible/modules/cloud/openstack/os_subnets_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_subnets_facts.py @@ -44,7 +44,7 @@ EXAMPLES = ''' - name: Gather facts about previously created subnets os_subnets_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -56,7 +56,7 @@ EXAMPLES = ''' - name: Gather facts about a previously created subnet by name os_subnets_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -70,7 +70,7 @@ EXAMPLES = ''' # Note: name and filters parameters are not mutually exclusive os_subnets_facts: auth: - auth_url: https://your_api_url.com:9000/v2.0 + auth_url: https://identity.example.com username: user password: password project_name: someproject @@ -130,14 +130,8 @@ openstack_subnets: type: list of dicts ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -148,11 +142,8 @@ def main(): ) module = AnsibleModule(argument_spec) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) subnets = cloud.search_subnets(module.params['name'], module.params['filters']) module.exit_json(changed=False, ansible_facts=dict( diff --git a/lib/ansible/modules/cloud/openstack/os_user.py b/lib/ansible/modules/cloud/openstack/os_user.py index 91889eef15..eb07b2d3e4 100644 --- a/lib/ansible/modules/cloud/openstack/os_user.py +++ b/lib/ansible/modules/cloud/openstack/os_user.py @@ -139,14 +139,8 @@ user: ''' from distutils.version import StrictVersion -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _needs_update(params_dict, user): @@ -205,11 +199,8 @@ def main(): argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - name = module.params['name'] - password = module.params.pop('password') + password = module.params.get('password') email = module.params['email'] default_project = module.params['default_project'] domain = module.params['domain'] @@ -221,14 +212,13 @@ def main(): if description and StrictVersion(shade.__version__) < StrictVersion('1.13.0'): module.fail_json(msg="To utilize description, the installed version of the shade library MUST be >=1.13.0") + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) user = cloud.get_user(name) domain_id = None if domain: - opcloud = shade.operator_cloud(**module.params) - domain_id = _get_domain_id(opcloud, domain) + domain_id = _get_domain_id(cloud, domain) if state == 'present': if update_password in ('always', 'on_create'): diff --git a/lib/ansible/modules/cloud/openstack/os_user_facts.py b/lib/ansible/modules/cloud/openstack/os_user_facts.py index f6cb1b4102..4b96a3249c 100644 --- a/lib/ansible/modules/cloud/openstack/os_user_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_user_facts.py @@ -115,14 +115,8 @@ openstack_users: type: string ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def main(): @@ -135,16 +129,12 @@ def main(): module = AnsibleModule(argument_spec) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - + shade, opcloud = openstack_cloud_from_module(module) try: name = module.params['name'] domain = module.params['domain'] filters = module.params['filters'] - opcloud = shade.operator_cloud(**module.params) - if domain: try: # We assume admin is passing domain id diff --git a/lib/ansible/modules/cloud/openstack/os_user_group.py b/lib/ansible/modules/cloud/openstack/os_user_group.py index d5c6967e18..ab357fd484 100644 --- a/lib/ansible/modules/cloud/openstack/os_user_group.py +++ b/lib/ansible/modules/cloud/openstack/os_user_group.py @@ -51,14 +51,8 @@ EXAMPLES = ''' group: demo ''' -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, in_group): @@ -81,16 +75,12 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - user = module.params['user'] group = module.params['group'] state = module.params['state'] + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.operator_cloud(**module.params) - in_group = cloud.is_user_in_group(user, group) if module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_user_role.py b/lib/ansible/modules/cloud/openstack/os_user_role.py index 79c3cf8867..060d4aa806 100644 --- a/lib/ansible/modules/cloud/openstack/os_user_role.py +++ b/lib/ansible/modules/cloud/openstack/os_user_role.py @@ -86,16 +86,8 @@ RETURN = ''' # ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, assignment): @@ -137,20 +129,17 @@ def main(): supports_check_mode=True, **module_kwargs) + role = module.params.get('role') + user = module.params.get('user') + group = module.params.get('group') + project = module.params.get('project') + domain = module.params.get('domain') + state = module.params.get('state') + # role grant/revoke API introduced in 1.5.0 - if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.5.0')): - module.fail_json(msg='shade 1.5.0 or higher is required for this module') - - role = module.params.pop('role') - user = module.params.pop('user') - group = module.params.pop('group') - project = module.params.pop('project') - domain = module.params.pop('domain') - state = module.params.pop('state') - + shade, cloud = openstack_cloud_from_module( + module, min_version='1.5.0') try: - cloud = shade.operator_cloud(**module.params) - filters = {} r = cloud.get_role(role) diff --git a/lib/ansible/modules/cloud/openstack/os_volume.py b/lib/ansible/modules/cloud/openstack/os_volume.py index e9285e876e..a64cc48dc6 100644 --- a/lib/ansible/modules/cloud/openstack/os_volume.py +++ b/lib/ansible/modules/cloud/openstack/os_volume.py @@ -95,14 +95,9 @@ EXAMPLES = ''' ''' from distutils.version import StrictVersion -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _present_volume(module, cloud): @@ -137,7 +132,7 @@ def _present_volume(module, cloud): module.exit_json(changed=True, id=volume['id'], volume=volume) -def _absent_volume(module, cloud): +def _absent_volume(module, cloud, shade): changed = False if cloud.volume_exists(module.params['display_name']): try: @@ -169,9 +164,6 @@ def main(): ) module = AnsibleModule(argument_spec=argument_spec, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if (module.params['scheduler_hints'] and StrictVersion(shade.__version__) < StrictVersion('1.22')): module.fail_json(msg="To utilize scheduler_hints, the installed version of" @@ -182,12 +174,12 @@ def main(): if state == 'present' and not module.params['size']: module.fail_json(msg="Size is required when state is 'present'") + shade, cloud = openstack_cloud_from_module(module) try: - cloud = shade.openstack_cloud(**module.params) if state == 'present': _present_volume(module, cloud) if state == 'absent': - _absent_volume(module, cloud) + _absent_volume(module, cloud, shade) except shade.OpenStackCloudException as e: module.fail_json(msg=str(e)) diff --git a/lib/ansible/modules/cloud/openstack/os_zone.py b/lib/ansible/modules/cloud/openstack/os_zone.py index 688c6ee750..3aea08777e 100644 --- a/lib/ansible/modules/cloud/openstack/os_zone.py +++ b/lib/ansible/modules/cloud/openstack/os_zone.py @@ -126,16 +126,8 @@ zone: sample: [] ''' -from distutils.version import StrictVersion - -try: - import shade - HAS_SHADE = True -except ImportError: - HAS_SHADE = False - from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs, openstack_cloud_from_module def _system_state_change(state, email, description, ttl, masters, zone): @@ -171,17 +163,11 @@ def main(): supports_check_mode=True, **module_kwargs) - if not HAS_SHADE: - module.fail_json(msg='shade is required for this module') - if StrictVersion(shade.__version__) < StrictVersion('1.8.0'): - module.fail_json(msg="To utilize this module, the installed version of" - "the shade library MUST be >=1.8.0") - name = module.params.get('name') state = module.params.get('state') + shade, cloud = openstack_cloud_from_module(module, min_version='1.8.0') try: - cloud = shade.openstack_cloud(**module.params) zone = cloud.get_zone(name) if state == 'present': diff --git a/lib/ansible/utils/module_docs_fragments/openstack.py b/lib/ansible/utils/module_docs_fragments/openstack.py index ade8aa7135..51c9299a35 100644 --- a/lib/ansible/utils/module_docs_fragments/openstack.py +++ b/lib/ansible/utils/module_docs_fragments/openstack.py @@ -23,9 +23,13 @@ class ModuleDocFragment(object): options: cloud: description: - - Named cloud to operate against. Provides default values for I(auth) and - I(auth_type). This parameter is not needed if I(auth) is provided or if - OpenStack OS_* environment variables are present. + - Named cloud or cloud config to operate against. + If I(cloud) is a string, it references a named cloud config as defined + in an OpenStack clouds.yaml file. Provides default values for I(auth) + and I(auth_type). This parameter is not needed if I(auth) is provided + or if OpenStack OS_* environment variables are present. + If I(cloud) is a dict, it contains a complete cloud configuration like + would be in a section of clouds.yaml. required: false auth: description: @@ -87,18 +91,14 @@ options: - A path to a client key to use as part of the SSL transaction. required: false default: None - endpoint_type: + interface: description: - Endpoint URL type to fetch from the service catalog. choices: [public, internal, admin] required: false default: public - identity_api_version: - description: - - The identity API version - choices: [2.0, 3] - required: false - default: None + aliases: ['endpoint_type'] + version_added: "2.3" requirements: - python >= 2.7 - shade diff --git a/test/units/modules/cloud/openstack/test_os_server.py b/test/units/modules/cloud/openstack/test_os_server.py index 34f9cb16cf..ce836dd3bf 100644 --- a/test/units/modules/cloud/openstack/test_os_server.py +++ b/test/units/modules/cloud/openstack/test_os_server.py @@ -81,6 +81,9 @@ class FakeCloud (object): def get_network(self, name): return self._find(self.networks, name) + def get_openstack_vars(self, server): + return server + create_server = mock.MagicMock()