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 84c5eefd797..8d0cb291b44 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 9cfc6cba0cd..434a6561efa 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 81e8f28a505..f88759f084a 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 4eba8e75189..d01ce36e6eb 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 0465b286829..4f6b69f3ab0 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 a20e0659283..4e469b54946 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 faf090de3cd..5052abcddc9 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 46144cabe2a..6a55669f280 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 3488688b56d..689530c6fcc 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 348e76f452b..2137335d530 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 691243e55d3..38624e5df28 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 bc9eff7dfeb..b1aff29a52b 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 6b018cb42bd..172fef47675 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 42d94bb3103..e814eb011e1 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 532247b6428..b87a8b405f2 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 0af66ead09e..369971a99a0 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 2caee8254e7..20eff9ef637 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 9fb5a167dda..b63c1529550 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 46b2dfcf022..9795e38c230 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 6d2d5f6ebca..733c4f5e046 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 6b78ffa84c3..1cca6a9262d 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 54db16ddb75..38e867b965d 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 07f6074b36c..7da2e021ede 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 70b8dab26a4..26d8edf64f9 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 db3e3dba354..95ba9afe83e 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 5c38eb8fca3..f6c2f1f6a44 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 c319b12ddb9..c78e5409d50 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 7ec2c215c67..f88b7067f1a 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 760ea3133ef..fe5a6cb0d59 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 cfa17902ace..03d11e1bc47 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 e6c6fac1502..9ad9ff67f61 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 c4748beb794..e939433c321 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 de41d9015c9..378e659e8f5 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 34caa4ca3a7..64b5f5d103a 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 89a9e76707f..d6a29490ac5 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 710107410b4..532c26bf609 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 cfde6c0800d..f53d33fc5ad 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 2daf4d70858..296622d8e38 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 157530ab3d2..8a6382f4d0e 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 91889eef156..eb07b2d3e4c 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 f6cb1b41025..4b96a3249c6 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 d5c6967e18f..ab357fd4841 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 79c3cf8867d..060d4aa8064 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 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') + 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 + 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 e9285e876e6..a64cc48dc62 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 688c6ee7509..3aea08777ec 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 ade8aa7135b..51c9299a350 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 34f9cb16cf1..ce836dd3bf0 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()