diff --git a/lib/ansible/modules/cloud/openstack/_glance_image.py b/lib/ansible/modules/cloud/openstack/_glance_image.py deleted file mode 100644 index fe1d91ca235..00000000000 --- a/lib/ansible/modules/cloud/openstack/_glance_image.py +++ /dev/null @@ -1,283 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: glance_image -author: "Benno Joy (@bennojoy)" -version_added: "1.2" -deprecated: Deprecated in 1.10. Use M(os_image) instead. -short_description: Add/Delete images from glance -description: - - Add or Remove images from the glance repository. -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - name: - description: - - Name that has to be given to the image - required: true - default: None - disk_format: - description: - - The format of the disk that is getting uploaded - required: false - default: qcow2 - container_format: - description: - - The format of the container - required: false - default: bare - owner: - description: - - The owner of the image - required: false - default: None - min_disk: - description: - - The minimum disk space required to deploy this image - required: false - default: None - min_ram: - description: - - The minimum ram required to deploy this image - required: false - default: None - is_public: - description: - - Whether the image can be accessed publicly - required: false - default: 'yes' - copy_from: - description: - - A url from where the image can be downloaded, mutually exclusive with file parameter - required: false - default: None - timeout: - description: - - The time to wait for the image process to complete in seconds - required: false - default: 180 - file: - description: - - The path to the file which has to be uploaded, mutually exclusive with copy_from - required: false - default: None - endpoint_type: - description: - - The name of the glance service's endpoint URL type - choices: [publicURL, internalURL] - required: false - default: publicURL - version_added: "1.7" -requirements: - - "python >= 2.6" - - "python-glanceclient" - - "python-keystoneclient" - -''' - -EXAMPLES = ''' -- name: Upload an image from an HTTP URL - glance_image: - login_username: admin - login_password: passme - login_tenant_name: admin - name: cirros - container_format: bare - disk_format: qcow2 - state: present - copy_from: http://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img -''' - -import time -try: - import glanceclient - HAS_GLANCECLIENT = True -except ImportError: - HAS_GLANCECLIENT = False -try: - from keystoneclient.v2_0 import client as ksclient - HAS_KEYSTONECLIENT = True -except ImportError: - HAS_KEYSTONECLIENT= False - - -def _get_ksclient(module, kwargs): - try: - client = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg="Error authenticating to the keystone: %s " % e.message) - return client - - -def _get_endpoint(module, client, endpoint_type): - try: - endpoint = client.service_catalog.url_for(service_type='image', endpoint_type=endpoint_type) - except Exception as e: - module.fail_json(msg="Error getting endpoint for glance: %s" % e.message) - return endpoint - - -def _get_glance_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint =_get_endpoint(module, _ksclient, kwargs.get('endpoint_type')) - kwargs = { - 'token': token, - } - try: - client = glanceclient.Client('1', endpoint, **kwargs) - except Exception as e: - module.fail_json(msg="Error in connecting to glance: %s" % e.message) - return client - - -def _glance_image_present(module, params, client): - try: - for image in client.images.list(): - if image.name == params['name']: - return image.id - return None - except Exception as e: - module.fail_json(msg="Error in fetching image list: %s" % e.message) - - -def _glance_image_create(module, params, client): - kwargs = { - 'name': params.get('name'), - 'disk_format': params.get('disk_format'), - 'container_format': params.get('container_format'), - 'owner': params.get('owner'), - 'is_public': params.get('is_public'), - 'copy_from': params.get('copy_from'), - } - try: - timeout = float(params.get('timeout')) - expire = time.time() + timeout - image = client.images.create(**kwargs) - if not params['copy_from']: - image.update(data=open(params['file'], 'rb')) - while time.time() < expire: - image = client.images.get(image.id) - if image.status == 'active': - break - time.sleep(5) - except Exception as e: - module.fail_json(msg="Error in creating image: %s" % e.message) - if image.status == 'active': - module.exit_json(changed=True, result=image.status, id=image.id) - else: - module.fail_json(msg=" The module timed out, please check manually " + image.status) - - -def _glance_delete_image(module, params, client): - try: - for image in client.images.list(): - if image.name == params['name']: - client.images.delete(image) - except Exception as e: - module.fail_json(msg="Error in deleting image: %s" % e.message) - module.exit_json(changed=True, result="Deleted") - - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - disk_format = dict(default='qcow2', choices=['aki', 'vhd', 'vmdk', 'raw', 'qcow2', 'vdi', 'iso']), - container_format = dict(default='bare', choices=['aki', 'ari', 'bare', 'ovf']), - owner = dict(default=None), - min_disk = dict(default=None), - min_ram = dict(default=None), - is_public = dict(default=True), - copy_from = dict(default= None), - timeout = dict(default=180), - file = dict(default=None), - endpoint_type = dict(default='publicURL', choices=['publicURL', 'internalURL']), - state = dict(default='present', choices=['absent', 'present']) - )) - module = AnsibleModule( - argument_spec=argument_spec, - mutually_exclusive = [['file','copy_from']], - ) - - if not HAS_GLANCECLIENT: - module.fail_json(msg='python-glanceclient is required for this module') - if not HAS_KEYSTONECLIENT: - module.fail_json(msg='python-keystoneclient is required for this module') - - if module.params['state'] == 'present': - if not module.params['file'] and not module.params['copy_from']: - module.fail_json(msg="Either file or copy_from variable should be set to create the image") - client = _get_glance_client(module, module.params) - id = _glance_image_present(module, module.params, client) - if not id: - _glance_image_create(module, module.params, client) - module.exit_json(changed=False, id=id, result="success") - - if module.params['state'] == 'absent': - client = _get_glance_client(module, module.params) - id = _glance_image_present(module, module.params, client) - if not id: - module.exit_json(changed=False, result="Success") - else: - _glance_delete_image(module, module.params, client) - -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/cloud/openstack/_keystone_user.py b/lib/ansible/modules/cloud/openstack/_keystone_user.py deleted file mode 100644 index 8602137c3cf..00000000000 --- a/lib/ansible/modules/cloud/openstack/_keystone_user.py +++ /dev/null @@ -1,445 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . - -# Based on Jimmy Tang's implementation - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: keystone_user -version_added: "1.2" -deprecated: Deprecated in 2.0. Use M(os_user) instead. -short_description: Manage OpenStack Identity (keystone) users, tenants and roles -description: - - Manage users,tenants, roles from OpenStack. -options: - login_user: - description: - - login username to authenticate to keystone - required: false - default: admin - login_password: - description: - - Password of login user - required: false - default: 'yes' - login_tenant_name: - description: - - The tenant login_user belongs to - required: false - default: None - version_added: "1.3" - token: - description: - - The token to be uses in case the password is not specified - required: false - default: None - endpoint: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - user: - description: - - The name of the user that has to added/removed from OpenStack - required: false - default: None - password: - description: - - The password to be assigned to the user - required: false - default: None - tenant: - description: - - The tenant name that has be added/removed - required: false - default: None - tenant_description: - description: - - A description for the tenant - required: false - default: None - email: - description: - - An email address for the user - required: false - default: None - role: - description: - - The name of the role to be assigned or created - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present -requirements: - - "python >= 2.6" - - python-keystoneclient -author: "Ansible Core Team (deprecated)" -''' - -EXAMPLES = ''' -- name: Create a tenant - keystone_user: - tenant: demo - tenant_description: "Default Tenant" - -- name: Create a user - keystone_user: - user: john - tenant: demo - password: secrete - -- name: Apply the admin role to the john user in the demo tenant - keystone_user: - role: admin - user: john - tenant: demo -''' - -try: - from keystoneclient.v2_0 import client -except ImportError: - keystoneclient_found = False -else: - keystoneclient_found = True - - -def authenticate(endpoint, token, login_user, login_password, login_tenant_name): - """Return a keystone client object""" - - if token: - return client.Client(endpoint=endpoint, token=token) - else: - return client.Client(auth_url=endpoint, username=login_user, - password=login_password, tenant_name=login_tenant_name) - - -def tenant_exists(keystone, tenant): - """ Return True if tenant already exists""" - return tenant in [x.name for x in keystone.tenants.list()] - - -def user_exists(keystone, user): - """" Return True if user already exists""" - return user in [x.name for x in keystone.users.list()] - - -def get_tenant(keystone, name): - """ Retrieve a tenant by name""" - tenants = [x for x in keystone.tenants.list() if x.name == name] - count = len(tenants) - if count == 0: - raise KeyError("No keystone tenants with name %s" % name) - elif count > 1: - raise ValueError("%d tenants with name %s" % (count, name)) - else: - return tenants[0] - - -def get_user(keystone, name): - """ Retrieve a user by name""" - users = [x for x in keystone.users.list() if x.name == name] - count = len(users) - if count == 0: - raise KeyError("No keystone users with name %s" % name) - elif count > 1: - raise ValueError("%d users with name %s" % (count, name)) - else: - return users[0] - - -def get_role(keystone, name): - """ Retrieve a role by name""" - roles = [x for x in keystone.roles.list() if x.name == name] - count = len(roles) - if count == 0: - raise KeyError("No keystone roles with name %s" % name) - elif count > 1: - raise ValueError("%d roles with name %s" % (count, name)) - else: - return roles[0] - - -def get_tenant_id(keystone, name): - return get_tenant(keystone, name).id - - -def get_user_id(keystone, name): - return get_user(keystone, name).id - - -def ensure_tenant_exists(keystone, tenant_name, tenant_description, - check_mode): - """ Ensure that a tenant exists. - - Return (True, id) if a new tenant was created, (False, None) if it - already existed. - """ - - # Check if tenant already exists - try: - tenant = get_tenant(keystone, tenant_name) - except KeyError: - # Tenant doesn't exist yet - pass - else: - if tenant.description == tenant_description: - return (False, tenant.id) - else: - # We need to update the tenant description - if check_mode: - return (True, tenant.id) - else: - tenant.update(description=tenant_description) - return (True, tenant.id) - - # We now know we will have to create a new tenant - if check_mode: - return (True, None) - - ks_tenant = keystone.tenants.create(tenant_name=tenant_name, - description=tenant_description, - enabled=True) - return (True, ks_tenant.id) - - -def ensure_tenant_absent(keystone, tenant, check_mode): - """ Ensure that a tenant does not exist - - Return True if the tenant was removed, False if it didn't exist - in the first place - """ - if not tenant_exists(keystone, tenant): - return False - - # We now know we will have to delete the tenant - if check_mode: - return True - - -def ensure_user_exists(keystone, user_name, password, email, tenant_name, - check_mode): - """ Check if user exists - - Return (True, id) if a new user was created, (False, id) user already - exists - """ - - # Check if tenant already exists - try: - user = get_user(keystone, user_name) - except KeyError: - # Tenant doesn't exist yet - pass - else: - # User does exist, we're done - return (False, user.id) - - # We now know we will have to create a new user - if check_mode: - return (True, None) - - tenant = get_tenant(keystone, tenant_name) - - user = keystone.users.create(name=user_name, password=password, - email=email, tenant_id=tenant.id) - return (True, user.id) - -def ensure_role_exists(keystone, role_name): - # Get the role if it exists - try: - role = get_role(keystone, role_name) - # Role does exist, we're done - return (False, role.id) - except KeyError: - # Role doesn't exist yet - pass - - role = keystone.roles.create(role_name) - return (True, role.id) - -def ensure_user_role_exists(keystone, user_name, tenant_name, role_name, - check_mode): - """ Check if role exists - - Return (True, id) if a new role was created or if the role was newly - assigned to the user for the tenant. (False, id) if the role already - exists and was already assigned to the user for the tenant. - - """ - # Check if the user has the role in the tenant - user = get_user(keystone, user_name) - tenant = get_tenant(keystone, tenant_name) - roles = [x for x in keystone.roles.roles_for_user(user, tenant) - if x.name == role_name] - count = len(roles) - - if count == 1: - # If the role is in there, we are done - role = roles[0] - return (False, role.id) - elif count > 1: - # Too many roles with the same name, throw an error - raise ValueError("%d roles with name %s" % (count, role_name)) - - # At this point, we know we will need to make changes - if check_mode: - return (True, None) - - # Get the role if it exists - try: - role = get_role(keystone, role_name) - except KeyError: - # Role doesn't exist yet - role = keystone.roles.create(role_name) - - # Associate the role with the user in the admin - keystone.roles.add_user_role(user, role, tenant) - return (True, role.id) - - -def ensure_user_absent(keystone, user, check_mode): - raise NotImplementedError("Not yet implemented") - - -def ensure_user_role_absent(keystone, uesr, tenant, role, check_mode): - raise NotImplementedError("Not yet implemented") - -def ensure_role_absent(keystone, role_name): - raise NotImplementedError("Not yet implemented") - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - tenant_description=dict(required=False), - email=dict(required=False), - user=dict(required=False), - tenant=dict(required=False), - password=dict(required=False), - role=dict(required=False), - state=dict(default='present', choices=['present', 'absent']), - endpoint=dict(required=False, - default="http://127.0.0.1:35357/v2.0"), - token=dict(required=False), - login_user=dict(required=False), - login_password=dict(required=False, no_log=True), - login_tenant_name=dict(required=False) - )) - # keystone operations themselves take an endpoint, not a keystone auth_url - del(argument_spec['auth_url']) - module = AnsibleModule( - argument_spec=argument_spec, - supports_check_mode=True, - mutually_exclusive=[['token', 'login_user'], - ['token', 'login_password'], - ['token', 'login_tenant_name']] - ) - - if not keystoneclient_found: - module.fail_json(msg="the python-keystoneclient module is required") - - user = module.params['user'] - password = module.params['password'] - tenant = module.params['tenant'] - tenant_description = module.params['tenant_description'] - email = module.params['email'] - role = module.params['role'] - state = module.params['state'] - endpoint = module.params['endpoint'] - token = module.params['token'] - login_user = module.params['login_user'] - login_password = module.params['login_password'] - login_tenant_name = module.params['login_tenant_name'] - - keystone = authenticate(endpoint, token, login_user, login_password, login_tenant_name) - - check_mode = module.check_mode - - try: - d = dispatch(keystone, user, password, tenant, tenant_description, - email, role, state, endpoint, token, login_user, - login_password, check_mode) - except Exception as e: - if check_mode: - # If we have a failure in check mode - module.exit_json(changed=True, - msg="exception: %s" % e) - else: - module.fail_json(msg="exception: %s" % e) - else: - module.exit_json(**d) - - -def dispatch(keystone, user=None, password=None, tenant=None, - tenant_description=None, email=None, role=None, - state="present", endpoint=None, token=None, login_user=None, - login_password=None, check_mode=False): - """ Dispatch to the appropriate method. - - Returns a dict that will be passed to exit_json - - tenant user role state - ------ ---- ---- -------- - X present ensure_tenant_exists - X absent ensure_tenant_absent - X X present ensure_user_exists - X X absent ensure_user_absent - X X X present ensure_user_role_exists - X X X absent ensure_user_role_absent - X present ensure_role_exists - X absent ensure_role_absent - """ - changed = False - id = None - if not tenant and not user and role and state == "present": - changed, id = ensure_role_exists(keystone, role) - elif not tenant and not user and role and state == "absent": - changed = ensure_role_absent(keystone, role) - elif tenant and not user and not role and state == "present": - changed, id = ensure_tenant_exists(keystone, tenant, - tenant_description, check_mode) - elif tenant and not user and not role and state == "absent": - changed = ensure_tenant_absent(keystone, tenant, check_mode) - elif tenant and user and not role and state == "present": - changed, id = ensure_user_exists(keystone, user, password, - email, tenant, check_mode) - elif tenant and user and not role and state == "absent": - changed = ensure_user_absent(keystone, user, check_mode) - elif tenant and user and role and state == "present": - changed, id = ensure_user_role_exists(keystone, user, tenant, role, - check_mode) - elif tenant and user and role and state == "absent": - changed = ensure_user_role_absent(keystone, user, tenant, role, check_mode) - else: - # Should never reach here - raise ValueError("Code should never reach here") - - return dict(changed=changed, id=id) - -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/cloud/openstack/_nova_compute.py b/lib/ansible/modules/cloud/openstack/_nova_compute.py deleted file mode 100644 index fedca58ca52..00000000000 --- a/lib/ansible/modules/cloud/openstack/_nova_compute.py +++ /dev/null @@ -1,606 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# (c) 2013, John Dewey -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: nova_compute -version_added: "1.2" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_server) instead. -short_description: Create/Delete VMs from OpenStack -description: - - Create or Remove virtual machines from Openstack. -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - name: - description: - - Name that has to be given to the instance - required: true - default: None - image_id: - description: - - The id of the base image to boot. Mutually exclusive with image_name - required: true - default: None - image_name: - description: - - The name of the base image to boot. Mutually exclusive with image_id - required: true - default: None - version_added: "1.8" - image_exclude: - description: - - Text to use to filter image names, for the case, such as HP, where there are multiple image names matching the common identifying - portions. image_exclude is a negative match filter - it is text that may not exist in the image name. Defaults to "(deprecated)" - version_added: "1.8" - flavor_id: - description: - - The id of the flavor in which the new VM has to be created. Mutually exclusive with flavor_ram - required: false - default: 1 - flavor_ram: - description: - - The minimum amount of ram in MB that the flavor in which the new VM has to be created must have. Mutually exclusive with flavor_id - required: false - default: 1 - version_added: "1.8" - flavor_include: - description: - - Text to use to filter flavor names, for the case, such as Rackspace, where there are multiple flavors that have the same ram count. - flavor_include is a positive match filter - it must exist in the flavor name. - version_added: "1.8" - key_name: - description: - - The key pair name to be used when creating a VM - required: false - default: None - security_groups: - description: - - The name of the security group to which the VM should be added - required: false - default: None - nics: - description: - - A list of network id's to which the VM's interface should be attached - required: false - default: None - auto_floating_ip: - description: - - Should a floating ip be auto created and assigned - required: false - default: 'no' - version_added: "1.8" - floating_ips: - description: - - list of valid floating IPs that pre-exist to assign to this node - required: false - default: None - version_added: "1.8" - floating_ip_pools: - description: - - list of floating IP pools from which to choose a floating IP - required: false - default: None - version_added: "1.8" - availability_zone: - description: - - Name of the availability zone - required: false - default: None - version_added: "1.8" - meta: - description: - - A list of key value pairs that should be provided as a metadata to the new VM - required: false - default: None - wait: - description: - - If the module should wait for the VM to be created. - required: false - default: 'yes' - wait_for: - description: - - The amount of time the module should wait for the VM to get into active state - required: false - default: 180 - config_drive: - description: - - Whether to boot the server with config drive enabled - required: false - default: 'no' - version_added: "1.8" - user_data: - description: - - Opaque blob of data which is made available to the instance - required: false - default: None - version_added: "1.6" - scheduler_hints: - description: - - Arbitrary key/value pairs to the scheduler for custom use - required: false - default: None - version_added: "1.9" -requirements: - - "python >= 2.6" - - "python-novaclient" -''' - -EXAMPLES = ''' -# Creates a new VM and attaches to a network and passes metadata to the instance -- nova_compute: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - name: vm1 - image_id: 4f905f38-e52a-43d2-b6ec-754a13ffb529 - key_name: ansible_key - wait_for: 200 - flavor_id: 4 - nics: - - net-id: 34605f38-e52a-25d2-b6ec-754a13ffb723 - meta: - hostname: test1 - group: uge_master - -# Creates a new VM in HP Cloud AE1 region availability zone az2 and automatically assigns a floating IP -- name: launch a nova instance - hosts: localhost - tasks: - - name: launch an instance - nova_compute: - state: present - login_username: username - login_password: Equality7-2521 - login_tenant_name: username-project1 - name: vm1 - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ - region_name: region-b.geo-1 - availability_zone: az2 - image_id: 9302692b-b787-4b52-a3a6-daebb79cb498 - key_name: test - wait_for: 200 - flavor_id: 101 - security_groups: default - auto_floating_ip: yes - -# Creates a new VM in HP Cloud AE1 region availability zone az2 and assigns a pre-known floating IP -- name: launch a nova instance - hosts: localhost - tasks: - - name: launch an instance - nova_compute: - state: present - login_username: username - login_password: Equality7-2521 - login_tenant_name: username-project1 - name: vm1 - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ - region_name: region-b.geo-1 - availability_zone: az2 - image_id: 9302692b-b787-4b52-a3a6-daebb79cb498 - key_name: test - wait_for: 200 - flavor_id: 101 - floating_ips: - - 12.34.56.79 - -# Creates a new VM with 4G of RAM on Ubuntu Trusty, ignoring deprecated images -- name: launch a nova instance - hosts: localhost - tasks: - - name: launch an instance - nova_compute: - name: vm1 - state: present - login_username: username - login_password: Equality7-2521 - login_tenant_name: username-project1 - auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/ - region_name: region-b.geo-1 - image_name: Ubuntu Server 14.04 - image_exclude: deprecated - flavor_ram: 4096 - -# Creates a new VM with 4G of RAM on Ubuntu Trusty on a Rackspace Performance node in DFW -- name: launch a nova instance - hosts: localhost - tasks: - - name: launch an instance - nova_compute: - name: vm1 - state: present - login_username: username - login_password: Equality7-2521 - login_tenant_name: username-project1 - auth_url: https://identity.api.rackspacecloud.com/v2.0/ - region_name: DFW - image_name: Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM) - flavor_ram: 4096 - flavor_include: Performance -''' - -import operator -import os -import time - -try: - from novaclient.v1_1 import client as nova_client - from novaclient.v1_1 import floating_ips - from novaclient import exceptions - from novaclient import utils - HAS_NOVACLIENT = True -except ImportError: - HAS_NOVACLIENT = False - - -def _delete_server(module, nova): - name = None - server_list = None - try: - server_list = nova.servers.list(True, {'name': module.params['name']}) - if server_list: - server = [x for x in server_list if x.name == module.params['name']] - nova.servers.delete(server.pop()) - except Exception as e: - module.fail_json( msg = "Error in deleting vm: %s" % e.message) - if module.params['wait'] == 'no': - module.exit_json(changed = True, result = "deleted") - expire = time.time() + int(module.params['wait_for']) - while time.time() < expire: - name = nova.servers.list(True, {'name': module.params['name']}) - if not name: - module.exit_json(changed = True, result = "deleted") - time.sleep(5) - module.fail_json(msg = "Timed out waiting for server to get deleted, please check manually") - - -def _add_floating_ip_from_pool(module, nova, server): - - # instantiate FloatingIPManager object - floating_ip_obj = floating_ips.FloatingIPManager(nova) - - # empty dict and list - usable_floating_ips = {} - pools = [] - - # user specified - pools = module.params['floating_ip_pools'] - - # get the list of all floating IPs. Mileage may - # vary according to Nova Compute configuration - # per cloud provider - all_floating_ips = floating_ip_obj.list() - - # iterate through all pools of IP address. Empty - # string means all and is the default value - for pool in pools: - # temporary list per pool - pool_ips = [] - # loop through all floating IPs - for f_ip in all_floating_ips: - # if not reserved and the correct pool, add - if f_ip.fixed_ip is None and (f_ip.pool == pool): - pool_ips.append(f_ip.ip) - # only need one - break - - # if the list is empty, add for this pool - if not pool_ips: - try: - new_ip = nova.floating_ips.create(pool) - except Exception as e: - module.fail_json(msg = "Unable to create floating ip: %s" % (e.message)) - pool_ips.append(new_ip.ip) - # Add to the main list - usable_floating_ips[pool] = pool_ips - - # finally, add ip(s) to instance for each pool - for pool in usable_floating_ips: - for ip in usable_floating_ips[pool]: - try: - server.add_floating_ip(ip) - # We only need to assign one ip - but there is an inherent - # race condition and some other cloud operation may have - # stolen an available floating ip - break - except Exception as e: - module.fail_json(msg = "Error attaching IP %s to instance %s: %s " % (ip, server.id, e.message)) - - -def _add_floating_ip_list(module, server, ips): - # add ip(s) to instance - for ip in ips: - try: - server.add_floating_ip(ip) - except Exception as e: - module.fail_json(msg = "Error attaching IP %s to instance %s: %s " % (ip, server.id, e.message)) - - -def _add_auto_floating_ip(module, nova, server): - - try: - new_ip = nova.floating_ips.create() - except Exception as e: - module.fail_json(msg = "Unable to create floating ip: %s" % (e)) - - try: - server.add_floating_ip(new_ip) - except Exception as e: - # Clean up - we auto-created this ip, and it's not attached - # to the server, so the cloud will not know what to do with it - server.floating_ips.delete(new_ip) - module.fail_json(msg = "Error attaching IP %s to instance %s: %s " % (ip, server.id, e.message)) - - -def _add_floating_ip(module, nova, server): - - if module.params['floating_ip_pools']: - _add_floating_ip_from_pool(module, nova, server) - elif module.params['floating_ips']: - _add_floating_ip_list(module, server, module.params['floating_ips']) - elif module.params['auto_floating_ip']: - _add_auto_floating_ip(module, nova, server) - else: - return server - - # this may look redundant, but if there is now a - # floating IP, then it needs to be obtained from - # a recent server object if the above code path exec'd - try: - server = nova.servers.get(server.id) - except Exception as e: - module.fail_json(msg = "Error in getting info from instance: %s " % e.message) - return server - - -def _get_image_id(module, nova): - if module.params['image_name']: - for image in nova.images.list(): - if (module.params['image_name'] in image.name and ( - not module.params['image_exclude'] - or module.params['image_exclude'] not in image.name)): - return image.id - module.fail_json(msg = "Error finding image id from name(%s)" % module.params['image_name']) - return module.params['image_id'] - - -def _get_flavor_id(module, nova): - if module.params['flavor_ram']: - for flavor in sorted(nova.flavors.list(), key=operator.attrgetter('ram')): - if (flavor.ram >= module.params['flavor_ram'] and - (not module.params['flavor_include'] or module.params['flavor_include'] in flavor.name)): - return flavor.id - module.fail_json(msg = "Error finding flavor with %sMB of RAM" % module.params['flavor_ram']) - return module.params['flavor_id'] - - -def _create_server(module, nova): - image_id = _get_image_id(module, nova) - flavor_id = _get_flavor_id(module, nova) - bootargs = [module.params['name'], image_id, flavor_id] - bootkwargs = { - 'nics' : module.params['nics'], - 'meta' : module.params['meta'], - 'security_groups': module.params['security_groups'].split(','), - #userdata is unhyphenated in novaclient, but hyphenated here for consistency with the ec2 module: - 'userdata': module.params['user_data'], - 'config_drive': module.params['config_drive'], - } - - for optional_param in ('region_name', 'key_name', 'availability_zone', 'scheduler_hints'): - if module.params[optional_param]: - bootkwargs[optional_param] = module.params[optional_param] - try: - server = nova.servers.create(*bootargs, **bootkwargs) - server = nova.servers.get(server.id) - except Exception as e: - module.fail_json( msg = "Error in creating instance: %s " % e.message) - if module.params['wait'] == 'yes': - expire = time.time() + int(module.params['wait_for']) - while time.time() < expire: - try: - server = nova.servers.get(server.id) - except Exception as e: - module.fail_json( msg = "Error in getting info from instance: %s" % e.message) - if server.status == 'ACTIVE': - server = _add_floating_ip(module, nova, server) - - private = openstack_find_nova_addresses(getattr(server, 'addresses'), 'fixed', 'private') - public = openstack_find_nova_addresses(getattr(server, 'addresses'), 'floating', 'public') - - # now exit with info - module.exit_json(changed=True, id=server.id, private_ip=''.join(private), public_ip=''.join(public), status=server.status, info=server._info) - - if server.status == 'ERROR': - module.fail_json(msg = "Error in creating the server, please check logs") - time.sleep(2) - - module.fail_json(msg = "Timeout waiting for the server to come up.. Please check manually") - if server.status == 'ERROR': - module.fail_json(msg = "Error in creating the server.. Please check manually") - private = openstack_find_nova_addresses(getattr(server, 'addresses'), 'fixed', 'private') - public = openstack_find_nova_addresses(getattr(server, 'addresses'), 'floating', 'public') - - module.exit_json(changed = True, id = info['id'], private_ip=''.join(private), public_ip=''.join(public), status = server.status, info = server._info) - - -def _delete_floating_ip_list(module, nova, server, extra_ips): - for ip in extra_ips: - nova.servers.remove_floating_ip(server=server.id, address=ip) - - -def _check_floating_ips(module, nova, server): - changed = False - if module.params['floating_ip_pools'] or module.params['floating_ips'] or module.params['auto_floating_ip']: - ips = openstack_find_nova_addresses(server.addresses, 'floating') - if not ips: - # If we're configured to have a floating but we don't have one, - # let's add one - server = _add_floating_ip(module, nova, server) - changed = True - elif module.params['floating_ips']: - # we were configured to have specific ips, let's make sure we have - # those - missing_ips = [] - for ip in module.params['floating_ips']: - if ip not in ips: - missing_ips.append(ip) - if missing_ips: - server = _add_floating_ip_list(module, server, missing_ips) - changed = True - extra_ips = [] - for ip in ips: - if ip not in module.params['floating_ips']: - extra_ips.append(ip) - if extra_ips: - _delete_floating_ip_list(module, server, extra_ips) - changed = True - return (changed, server) - - -def _get_server_state(module, nova): - server = None - try: - servers = nova.servers.list(True, {'name': module.params['name']}) - if servers: - # the {'name': module.params['name']} will also return servers - # with names that partially match the server name, so we have to - # strictly filter here - servers = [x for x in servers if x.name == module.params['name']] - if servers: - server = servers[0] - except Exception as e: - module.fail_json(msg = "Error in getting the server list: %s" % e.message) - if server and module.params['state'] == 'present': - if server.status != 'ACTIVE': - module.fail_json( msg="The VM is available but not Active. state:" + server.status) - (ip_changed, server) = _check_floating_ips(module, nova, server) - private = openstack_find_nova_addresses(getattr(server, 'addresses'), 'fixed', 'private') - public = openstack_find_nova_addresses(getattr(server, 'addresses'), 'floating', 'public') - module.exit_json(changed = ip_changed, id = server.id, public_ip = public, private_ip = private, info = server._info) - if server and module.params['state'] == 'absent': - return True - if module.params['state'] == 'absent': - module.exit_json(changed = False, result = "not present") - return True - - - -def main(): - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - image_id = dict(default=None), - image_name = dict(default=None), - image_exclude = dict(default='(deprecated)'), - flavor_id = dict(default=1), - flavor_ram = dict(default=None, type='int'), - flavor_include = dict(default=None), - key_name = dict(default=None), - security_groups = dict(default='default'), - nics = dict(default=None, type='list'), - meta = dict(default=None, type='dict'), - wait = dict(default='yes', choices=['yes', 'no']), - wait_for = dict(default=180), - state = dict(default='present', choices=['absent', 'present']), - user_data = dict(default=None), - config_drive = dict(default=False, type='bool'), - auto_floating_ip = dict(default=False, type='bool'), - floating_ips = dict(default=None, type='list'), - floating_ip_pools = dict(default=None, type='list'), - scheduler_hints = dict(default=None, type='dict'), - )) - module = AnsibleModule( - argument_spec=argument_spec, - mutually_exclusive=[ - ['auto_floating_ip','floating_ips'], - ['auto_floating_ip','floating_ip_pools'], - ['floating_ips','floating_ip_pools'], - ['image_id','image_name'], - ['flavor_id','flavor_ram'], - ], - ) - - if not HAS_NOVACLIENT: - module.fail_json(msg='python-novaclient is required for this module') - - nova = nova_client.Client(module.params['login_username'], - module.params['login_password'], - module.params['login_tenant_name'], - module.params['auth_url'], - region_name=module.params['region_name'], - service_type='compute') - try: - nova.authenticate() - except exceptions.Unauthorized as e: - module.fail_json(msg = "Invalid OpenStack Nova credentials.: %s" % e.message) - except exceptions.AuthorizationFailure as e: - module.fail_json(msg = "Unable to authorize user: %s" % e.message) - - if module.params['state'] == 'present': - if not module.params['image_id'] and not module.params['image_name']: - module.fail_json( msg = "Parameter 'image_id' or `image_name` is required if state == 'present'") - else: - _get_server_state(module, nova) - _create_server(module, nova) - if module.params['state'] == 'absent': - _get_server_state(module, nova) - _delete_server(module, nova) - -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() diff --git a/lib/ansible/modules/cloud/openstack/_nova_keypair.py b/lib/ansible/modules/cloud/openstack/_nova_keypair.py deleted file mode 100644 index 274e34bccca..00000000000 --- a/lib/ansible/modules/cloud/openstack/_nova_keypair.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# (c) 2013, John Dewey -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: nova_keypair -version_added: "1.2" -author: - - "Benno Joy (@bennojoy)" - - "Michael DeHaan" -deprecated: Deprecated in 2.0. Use M(os_keypair) instead. -short_description: Add/Delete key pair from nova -description: - - Add or Remove key pair from nova . -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - name: - description: - - Name that has to be given to the key pair - required: true - default: None - public_key: - description: - - The public key that would be uploaded to nova and injected to vm's upon creation - required: false - default: None - -requirements: - - "python >= 2.6" - - "python-novaclient" -''' -EXAMPLES = ''' -- name: Create a key pair with the running users public key - nova_keypair: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - name: ansible_key - public_key: "{{ lookup('file','~/.ssh/id_rsa.pub') }}" - -- name: Create a new key pair and the private key returned after the run. - nova_keypair: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - name: ansible_key -''' - -import time -try: - from novaclient.v1_1 import client as nova_client - from novaclient import exceptions as exc - HAS_NOVACLIENT = True -except ImportError: - HAS_NOVACLIENT = False - - -def main(): - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - public_key = dict(default=None), - state = dict(default='present', choices=['absent', 'present']) - )) - module = AnsibleModule(argument_spec=argument_spec) - if not HAS_NOVACLIENT: - module.fail_json(msg='python-novaclient is required for this module to work') - - nova = nova_client.Client(module.params['login_username'], - module.params['login_password'], - module.params['login_tenant_name'], - module.params['auth_url'], - region_name=module.params['region_name'], - service_type='compute') - try: - nova.authenticate() - except exc.Unauthorized as e: - module.fail_json(msg = "Invalid OpenStack Nova credentials.: %s" % e.message) - except exc.AuthorizationFailure as e: - module.fail_json(msg = "Unable to authorize user: %s" % e.message) - - if module.params['state'] == 'present': - for key in nova.keypairs.list(): - if key.name == module.params['name']: - if module.params['public_key'] and (module.params['public_key'] != key.public_key ): - module.fail_json(msg = "name {} present but key hash not the same as offered. Delete key first.".format(key['name'])) - else: - module.exit_json(changed = False, result = "Key present") - try: - key = nova.keypairs.create(module.params['name'], module.params['public_key']) - except Exception as e: - module.exit_json(msg = "Error in creating the keypair: %s" % e.message) - if not module.params['public_key']: - module.exit_json(changed = True, key = key.private_key) - module.exit_json(changed = True, key = None) - if module.params['state'] == 'absent': - for key in nova.keypairs.list(): - if key.name == module.params['name']: - try: - nova.keypairs.delete(module.params['name']) - except Exception as e: - module.fail_json(msg = "The keypair deletion has failed: %s" % e.message) - module.exit_json( changed = True, result = "deleted") - module.exit_json(changed = False, result = "not present") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_floating_ip.py b/lib/ansible/modules/cloud/openstack/_quantum_floating_ip.py deleted file mode 100644 index 9777a830631..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_floating_ip.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_floating_ip -version_added: "1.2" -author: - - "Benno Joy (@bennojoy)" - - "Brad P. Crochet (@bcrochet)" -deprecated: Deprecated in 2.0. Use M(os_floating_ip) instead. -short_description: Add/Remove floating IP from an instance -description: - - Add or Remove a floating IP to an instance -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - network_name: - description: - - Name of the network from which IP has to be assigned to VM. Please make sure the network is an external network - required: true - default: None - instance_name: - description: - - The name of the instance to which the IP address should be assigned - required: true - default: None - internal_network_name: - description: - - The name of the network of the port to associate with the floating ip. Necessary when VM multiple networks. - required: false - default: None - version_added: "1.5" -requirements: - - "python >= 2.6" - - "python-novaclient" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: Assign a floating ip to the instance from an external network - quantum_floating_ip: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - network_name: external_network - instance_name: vm1 - internal_network_name: internal_network -''' - -import time - -try: - from novaclient.v1_1 import client as nova_client - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url'), - region_name=kwargs.get('region_name')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) - return neutron - -def _get_server_state(module, nova): - server_info = None - server = None - try: - for server in nova.servers.list(): - if server: - info = server._info - if info['name'] == module.params['instance_name']: - if info['status'] != 'ACTIVE' and module.params['state'] == 'present': - module.fail_json( msg="The VM is available but not Active. state:" + info['status']) - server_info = info - break - except Exception as e: - module.fail_json(msg = "Error in getting the server list: %s" % e.message) - return server_info, server - -def _get_port_info(neutron, module, instance_id, internal_network_name=None): - subnet_id = None - if internal_network_name: - kwargs = {'name': internal_network_name} - networks = neutron.list_networks(**kwargs) - network_id = networks['networks'][0]['id'] - kwargs = { - 'network_id': network_id, - 'ip_version': 4 - } - subnets = neutron.list_subnets(**kwargs) - subnet_id = subnets['subnets'][0]['id'] - kwargs = { - 'device_id': instance_id, - } - try: - ports = neutron.list_ports(**kwargs) - except Exception as e: - module.fail_json( msg = "Error in listing ports: %s" % e.message) - if subnet_id: - port = next(port for port in ports['ports'] if port['fixed_ips'][0]['subnet_id'] == subnet_id) - port_id = port['id'] - fixed_ip_address = port['fixed_ips'][0]['ip_address'] - else: - port_id = ports['ports'][0]['id'] - fixed_ip_address = ports['ports'][0]['fixed_ips'][0]['ip_address'] - if not ports['ports']: - return None, None - return fixed_ip_address, port_id - -def _get_floating_ip(module, neutron, fixed_ip_address, network_name): - kwargs = { - 'fixed_ip_address': fixed_ip_address - } - try: - ips = neutron.list_floatingips(**kwargs) - except Exception as e: - module.fail_json(msg = "error in fetching the floatingips's %s" % e.message) - if not ips['floatingips']: - return None, None - for address in ips['floatingips']: - if _check_ips_network(neutron, address['floating_network_id'], network_name): - return address['id'], address['floating_ip_address'] - return None, None - -def _check_ips_network(neutron, net_id, network_name): - if neutron.show_network(net_id)['network']['name'] == network_name: - return True - else: - return False - -def _create_floating_ip(neutron, module, port_id, net_id, fixed_ip): - kwargs = { - 'port_id': port_id, - 'floating_network_id': net_id, - 'fixed_ip_address': fixed_ip - } - try: - result = neutron.create_floatingip({'floatingip': kwargs}) - except Exception as e: - module.fail_json(msg="There was an error in updating the floating ip address: %s" % e.message) - module.exit_json(changed=True, result=result, public_ip=result['floatingip']['floating_ip_address']) - -def _get_net_id(neutron, module): - kwargs = { - 'name': module.params['network_name'], - } - try: - networks = neutron.list_networks(**kwargs) - except Exception as e: - module.fail_json(msg="Error in listing neutron networks: %s" % e.message) - if not networks['networks']: - return None - return networks['networks'][0]['id'] - -def _update_floating_ip(neutron, module, port_id, floating_ip_id): - kwargs = { - 'port_id': port_id - } - try: - result = neutron.update_floatingip(floating_ip_id, {'floatingip': kwargs}) - except Exception as e: - module.fail_json(msg="There was an error in updating the floating ip address: %s" % e.message) - module.exit_json(changed=True, result=result) - - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - network_name = dict(required=True), - instance_name = dict(required=True), - state = dict(default='present', choices=['absent', 'present']), - internal_network_name = dict(default=None), - )) - module = AnsibleModule(argument_spec=argument_spec) - - if not HAVE_DEPS: - module.fail_json(msg='python-novaclient, python-keystoneclient, and either python-neutronclient or python-quantumclient are required') - - try: - nova = nova_client.Client(module.params['login_username'], module.params['login_password'], - module.params['login_tenant_name'], module.params['auth_url'], region_name=module.params['region_name'], service_type='compute') - neutron = _get_neutron_client(module, module.params) - except Exception as e: - module.fail_json(msg="Error in authenticating to nova: %s" % e.message) - - server_info, server_obj = _get_server_state(module, nova) - if not server_info: - module.fail_json(msg="The instance name provided cannot be found") - - fixed_ip, port_id = _get_port_info(neutron, module, server_info['id'], module.params['internal_network_name']) - if not port_id: - module.fail_json(msg="Cannot find a port for this instance, maybe fixed ip is not assigned") - - floating_id, floating_ip = _get_floating_ip(module, neutron, fixed_ip, module.params['network_name']) - - if module.params['state'] == 'present': - if floating_ip: - module.exit_json(changed = False, public_ip=floating_ip) - net_id = _get_net_id(neutron, module) - if not net_id: - module.fail_json(msg = "cannot find the network specified, please check") - _create_floating_ip(neutron, module, port_id, net_id, fixed_ip) - - if module.params['state'] == 'absent': - if floating_ip: - _update_floating_ip(neutron, module, None, floating_id) - module.exit_json(changed=False) - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_floating_ip_associate.py b/lib/ansible/modules/cloud/openstack/_quantum_floating_ip_associate.py deleted file mode 100644 index d5b5792a236..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_floating_ip_associate.py +++ /dev/null @@ -1,235 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_floating_ip_associate -version_added: "1.2" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_floating_ip) instead. -short_description: Associate or disassociate a particular floating IP with an instance -description: - - Associates or disassociates a specific floating IP with a particular instance -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - the tenant name of the login user - required: true - default: true - auth_url: - description: - - the keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - name of the region - required: false - default: None - state: - description: - - indicates the desired state of the resource - choices: ['present', 'absent'] - default: present - instance_name: - description: - - name of the instance to which the public IP should be assigned - required: true - default: None - ip_address: - description: - - floating ip that should be assigned to the instance - required: true - default: None -requirements: - - "python >= 2.6" - - "python-novaclient" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: Associate a specific floating IP with an Instance - quantum_floating_ip_associate: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - ip_address: 1.1.1.1 - instance_name: vm1 -''' - -import time -try: - from novaclient.v1_1 import client as nova_client - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) - return neutron - -def _get_server_state(module, nova): - server_info = None - server = None - try: - for server in nova.servers.list(): - if server: - info = server._info - if info['name'] == module.params['instance_name']: - if info['status'] != 'ACTIVE' and module.params['state'] == 'present': - module.fail_json(msg="The VM is available but not Active. state:" + info['status']) - server_info = info - break - except Exception as e: - module.fail_json(msg = "Error in getting the server list: %s" % e.message) - return server_info, server - -def _get_port_id(neutron, module, instance_id): - kwargs = dict(device_id = instance_id) - try: - ports = neutron.list_ports(**kwargs) - except Exception as e: - module.fail_json( msg = "Error in listing ports: %s" % e.message) - if not ports['ports']: - return None - return ports['ports'][0]['id'] - -def _get_floating_ip_id(module, neutron): - kwargs = { - 'floating_ip_address': module.params['ip_address'] - } - try: - ips = neutron.list_floatingips(**kwargs) - except Exception as e: - module.fail_json(msg = "error in fetching the floatingips's %s" % e.message) - if not ips['floatingips']: - module.fail_json(msg = "Could find the ip specified in parameter, Please check") - ip = ips['floatingips'][0]['id'] - if not ips['floatingips'][0]['port_id']: - state = "detached" - else: - state = "attached" - return state, ip - -def _update_floating_ip(neutron, module, port_id, floating_ip_id): - kwargs = { - 'port_id': port_id - } - try: - result = neutron.update_floatingip(floating_ip_id, {'floatingip': kwargs}) - except Exception as e: - module.fail_json(msg = "There was an error in updating the floating ip address: %s" % e.message) - module.exit_json(changed = True, result = result, public_ip=module.params['ip_address']) - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - ip_address = dict(required=True), - instance_name = dict(required=True), - state = dict(default='present', choices=['absent', 'present']) - )) - module = AnsibleModule(argument_spec=argument_spec) - - if not HAVE_DEPS: - module.fail_json(msg='python-novaclient, python-keystoneclient, and either python-neutronclient or python-quantumclient are required') - - try: - nova = nova_client.Client(module.params['login_username'], module.params['login_password'], - module.params['login_tenant_name'], module.params['auth_url'], service_type='compute') - except Exception as e: - module.fail_json( msg = " Error in authenticating to nova: %s" % e.message) - neutron = _get_neutron_client(module, module.params) - state, floating_ip_id = _get_floating_ip_id(module, neutron) - if module.params['state'] == 'present': - if state == 'attached': - module.exit_json(changed = False, result = 'attached', public_ip=module.params['ip_address']) - server_info, server_obj = _get_server_state(module, nova) - if not server_info: - module.fail_json(msg = " The instance name provided cannot be found") - port_id = _get_port_id(neutron, module, server_info['id']) - if not port_id: - module.fail_json(msg = "Cannot find a port for this instance, maybe fixed ip is not assigned") - _update_floating_ip(neutron, module, port_id, floating_ip_id) - - if module.params['state'] == 'absent': - if state == 'detached': - module.exit_json(changed = False, result = 'detached') - if state == 'attached': - _update_floating_ip(neutron, module, None, floating_ip_id) - module.exit_json(changed = True, result = "detached") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_network.py b/lib/ansible/modules/cloud/openstack/_quantum_network.py deleted file mode 100644 index 89c090ece23..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_network.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_network -version_added: "1.4" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_network) instead. -short_description: Creates/Removes networks from OpenStack -description: - - Add or Remove network from OpenStack. -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - tenant_name: - description: - - The name of the tenant for whom the network is created - required: false - default: None - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - name: - description: - - Name to be assigned to the network - required: true - default: None - provider_network_type: - description: - - The type of the network to be created, gre, vlan, local. Available types depend on the plugin. The Quantum service decides if not specified. - required: false - default: None - provider_physical_network: - description: - - The physical network which would realize the virtual network for flat and vlan networks. - required: false - default: None - provider_segmentation_id: - description: - - The id that has to be assigned to the network, in case of vlan networks that would be vlan id and for gre the tunnel id - required: false - default: None - router_external: - description: - - If 'yes', specifies that the virtual network is a external network (public). - required: false - default: false - shared: - description: - - Whether this network is shared or not - required: false - default: false - admin_state_up: - description: - - Whether the state should be marked as up or down - required: false - default: true -requirements: - - "python >= 2.6" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" - -''' - -EXAMPLES = ''' -- name: Create a GRE backed Quantum network with tunnel id 1 for tenant1 - quantum_network: - name: t1network - tenant_name: tenant1 - state: present - provider_network_type: gre - provider_segmentation_id: 1 - login_username: admin - login_password: admin - login_tenant_name: admin - -- name: Create an external network - quantum_network: - name: external_network - state: present - provider_network_type: local - router_external: yes - login_username: admin - login_password: admin - login_tenant_name: admin -''' - -try: - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - -_os_keystone = None -_os_tenant_id = None - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s" %e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s " %e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = " Error in connecting to neutron: %s " %e.message) - return neutron - -def _set_tenant_id(module): - global _os_tenant_id - if not module.params['tenant_name']: - _os_tenant_id = _os_keystone.tenant_id - else: - tenant_name = module.params['tenant_name'] - - for tenant in _os_keystone.tenants.list(): - if tenant.name == tenant_name: - _os_tenant_id = tenant.id - break - if not _os_tenant_id: - module.fail_json(msg = "The tenant id cannot be found, please check the parameters") - -def _get_net_id(neutron, module): - kwargs = { - 'tenant_id': _os_tenant_id, - 'name': module.params['name'], - } - try: - networks = neutron.list_networks(**kwargs) - except Exception as e: - module.fail_json(msg = "Error in listing neutron networks: %s" % e.message) - if not networks['networks']: - return None - return networks['networks'][0]['id'] - -def _create_network(module, neutron): - - neutron.format = 'json' - - network = { - 'name': module.params.get('name'), - 'tenant_id': _os_tenant_id, - 'provider:network_type': module.params.get('provider_network_type'), - 'provider:physical_network': module.params.get('provider_physical_network'), - 'provider:segmentation_id': module.params.get('provider_segmentation_id'), - 'router:external': module.params.get('router_external'), - 'shared': module.params.get('shared'), - 'admin_state_up': module.params.get('admin_state_up'), - } - - if module.params['provider_network_type'] == 'local': - network.pop('provider:physical_network', None) - network.pop('provider:segmentation_id', None) - - if module.params['provider_network_type'] == 'flat': - network.pop('provider:segmentation_id', None) - - if module.params['provider_network_type'] == 'gre': - network.pop('provider:physical_network', None) - - if module.params['provider_network_type'] is None: - network.pop('provider:network_type', None) - network.pop('provider:physical_network', None) - network.pop('provider:segmentation_id', None) - - try: - net = neutron.create_network({'network':network}) - except Exception as e: - module.fail_json(msg = "Error in creating network: %s" % e.message) - return net['network']['id'] - -def _delete_network(module, net_id, neutron): - - try: - id = neutron.delete_network(net_id) - except Exception as e: - module.fail_json(msg = "Error in deleting the network: %s" % e.message) - return True - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - tenant_name = dict(default=None), - provider_network_type = dict(default=None, choices=['local', 'vlan', 'flat', 'gre']), - provider_physical_network = dict(default=None), - provider_segmentation_id = dict(default=None), - router_external = dict(default=False, type='bool'), - shared = dict(default=False, type='bool'), - admin_state_up = dict(default=True, type='bool'), - state = dict(default='present', choices=['absent', 'present']) - )) - module = AnsibleModule(argument_spec=argument_spec) - - if not HAVE_DEPS: - module.fail_json(msg='python-keystoneclient and either python-neutronclient or python-quantumclient are required') - - if module.params['provider_network_type'] in ['vlan' , 'flat']: - if not module.params['provider_physical_network']: - module.fail_json(msg = " for vlan and flat networks, variable provider_physical_network should be set.") - - if module.params['provider_network_type'] in ['vlan', 'gre']: - if not module.params['provider_segmentation_id']: - module.fail_json(msg = " for vlan & gre networks, variable provider_segmentation_id should be set.") - - neutron = _get_neutron_client(module, module.params) - - _set_tenant_id(module) - - if module.params['state'] == 'present': - network_id = _get_net_id(neutron, module) - if not network_id: - network_id = _create_network(module, neutron) - module.exit_json(changed = True, result = "Created", id = network_id) - else: - module.exit_json(changed = False, result = "Success", id = network_id) - - if module.params['state'] == 'absent': - network_id = _get_net_id(neutron, module) - if not network_id: - module.exit_json(changed = False, result = "Success") - else: - _delete_network(module, network_id, neutron) - module.exit_json(changed = True, result = "Deleted") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_router.py b/lib/ansible/modules/cloud/openstack/_quantum_router.py deleted file mode 100644 index 12466e859e9..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_router.py +++ /dev/null @@ -1,225 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_router -version_added: "1.2" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_router) instead. -short_description: Create or Remove router from openstack -description: - - Create or Delete routers from OpenStack -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone url for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - name: - description: - - Name to be give to the router - required: true - default: None - tenant_name: - description: - - Name of the tenant for which the router has to be created, if none router would be created for the login tenant. - required: false - default: None - admin_state_up: - description: - - desired admin state of the created router . - required: false - default: true -requirements: - - "python >= 2.6" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: Create a router for tenant admin - quantum_router: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - name: router1 -''' - -try: - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - -_os_keystone = None -_os_tenant_id = None - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) - return neutron - -def _set_tenant_id(module): - global _os_tenant_id - if not module.params['tenant_name']: - _os_tenant_id = _os_keystone.tenant_id - else: - tenant_name = module.params['tenant_name'] - - for tenant in _os_keystone.tenants.list(): - if tenant.name == tenant_name: - _os_tenant_id = tenant.id - break - if not _os_tenant_id: - module.fail_json(msg = "The tenant id cannot be found, please check the parameters") - -def _get_router_id(module, neutron): - kwargs = { - 'name': module.params['name'], - 'tenant_id': _os_tenant_id, - } - try: - routers = neutron.list_routers(**kwargs) - except Exception as e: - module.fail_json(msg = "Error in getting the router list: %s " % e.message) - if not routers['routers']: - return None - return routers['routers'][0]['id'] - -def _create_router(module, neutron): - router = { - 'name': module.params['name'], - 'tenant_id': _os_tenant_id, - 'admin_state_up': module.params['admin_state_up'], - } - try: - new_router = neutron.create_router(dict(router=router)) - except Exception as e: - module.fail_json( msg = "Error in creating router: %s" % e.message) - return new_router['router']['id'] - -def _delete_router(module, neutron, router_id): - try: - neutron.delete_router(router_id) - except: - module.fail_json(msg="Error in deleting the router") - return True - -def main(): - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - tenant_name = dict(default=None), - state = dict(default='present', choices=['absent', 'present']), - admin_state_up = dict(type='bool', default=True), - )) - module = AnsibleModule(argument_spec=argument_spec) - if not HAVE_DEPS: - module.fail_json(msg='python-keystoneclient and either python-neutronclient or python-quantumclient are required') - - neutron = _get_neutron_client(module, module.params) - _set_tenant_id(module) - - if module.params['state'] == 'present': - router_id = _get_router_id(module, neutron) - if not router_id: - router_id = _create_router(module, neutron) - module.exit_json(changed=True, result="Created", id=router_id) - else: - module.exit_json(changed=False, result="success" , id=router_id) - - else: - router_id = _get_router_id(module, neutron) - if not router_id: - module.exit_json(changed=False, result="success") - else: - _delete_router(module, neutron, router_id) - module.exit_json(changed=True, result="deleted") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_router_gateway.py b/lib/ansible/modules/cloud/openstack/_quantum_router_gateway.py deleted file mode 100644 index c5ee608ff77..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_router_gateway.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_router_gateway -version_added: "1.2" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_router) instead. -short_description: set/unset a gateway interface for the router with the specified external network -description: - - Creates/Removes a gateway interface from the router, used to associate a external network with a router to route external traffic. -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone URL for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - router_name: - description: - - Name of the router to which the gateway should be attached. - required: true - default: None - network_name: - description: - - Name of the external network which should be attached to the router. - required: true - default: None -requirements: - - "python >= 2.6" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: Attach an external network with a router to allow flow of external traffic - quantum_router_gateway: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - router_name: external_router - network_name: external_network -''' - -try: - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - -_os_keystone = None - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) - return neutron - -def _get_router_id(module, neutron): - kwargs = { - 'name': module.params['router_name'], - } - try: - routers = neutron.list_routers(**kwargs) - except Exception as e: - module.fail_json(msg = "Error in getting the router list: %s " % e.message) - if not routers['routers']: - return None - return routers['routers'][0]['id'] - -def _get_net_id(neutron, module): - kwargs = { - 'name': module.params['network_name'], - 'router:external': True - } - try: - networks = neutron.list_networks(**kwargs) - except Exception as e: - module.fail_json(msg="Error in listing neutron networks: %s" % e.message) - if not networks['networks']: - return None - return networks['networks'][0]['id'] - -def _get_port_id(neutron, module, router_id, network_id): - kwargs = { - 'device_id': router_id, - 'network_id': network_id, - } - try: - ports = neutron.list_ports(**kwargs) - except Exception as e: - module.fail_json( msg = "Error in listing ports: %s" % e.message) - if not ports['ports']: - return None - return ports['ports'][0]['id'] - -def _add_gateway_router(neutron, module, router_id, network_id): - kwargs = { - 'network_id': network_id - } - try: - neutron.add_gateway_router(router_id, kwargs) - except Exception as e: - module.fail_json(msg = "Error in adding gateway to router: %s" % e.message) - return True - -def _remove_gateway_router(neutron, module, router_id): - try: - neutron.remove_gateway_router(router_id) - except Exception as e: - module.fail_json(msg = "Error in removing gateway to router: %s" % e.message) - return True - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - router_name = dict(required=True), - network_name = dict(required=True), - state = dict(default='present', choices=['absent', 'present']), - )) - module = AnsibleModule(argument_spec=argument_spec) - if not HAVE_DEPS: - module.fail_json(msg='python-keystoneclient and either python-neutronclient or python-quantumclient are required') - - neutron = _get_neutron_client(module, module.params) - router_id = _get_router_id(module, neutron) - - if not router_id: - module.fail_json(msg="failed to get the router id, please check the router name") - - network_id = _get_net_id(neutron, module) - if not network_id: - module.fail_json(msg="failed to get the network id, please check the network name and make sure it is external") - - if module.params['state'] == 'present': - port_id = _get_port_id(neutron, module, router_id, network_id) - if not port_id: - _add_gateway_router(neutron, module, router_id, network_id) - module.exit_json(changed=True, result="created") - module.exit_json(changed=False, result="success") - - if module.params['state'] == 'absent': - port_id = _get_port_id(neutron, module, router_id, network_id) - if not port_id: - module.exit_json(changed=False, result="Success") - _remove_gateway_router(neutron, module, router_id) - module.exit_json(changed=True, result="Deleted") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_router_interface.py b/lib/ansible/modules/cloud/openstack/_quantum_router_interface.py deleted file mode 100644 index b742f27d70b..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_router_interface.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_router_interface -version_added: "1.2" -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_router) instead. -short_description: Attach/Detach a subnet's interface to a router -description: - - Attach/Detach a subnet interface to a router, to provide a gateway for the subnet. -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: 'yes' - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: 'yes' - auth_url: - description: - - The keystone URL for authentication - required: false - default: 'http://127.0.0.1:35357/v2.0/' - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - router_name: - description: - - Name of the router to which the subnet's interface should be attached. - required: true - default: None - subnet_name: - description: - - Name of the subnet to whose interface should be attached to the router. - required: true - default: None - tenant_name: - description: - - Name of the tenant whose subnet has to be attached. - required: false - default: None -requirements: - - "python >= 2.6" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: "Attach tenant1's subnet to the external router" - quantum_router_interface: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - tenant_name: tenant1 - router_name: external_route - subnet_name: t1subnet -''' - -try: - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - -_os_keystone = None -_os_tenant_id = None - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s " % e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = "Error in connecting to neutron: %s " % e.message) - return neutron - -def _set_tenant_id(module): - global _os_tenant_id - if not module.params['tenant_name']: - _os_tenant_id = _os_keystone.tenant_id - else: - tenant_name = module.params['tenant_name'] - - for tenant in _os_keystone.tenants.list(): - if tenant.name == tenant_name: - _os_tenant_id = tenant.id - break - if not _os_tenant_id: - module.fail_json(msg = "The tenant id cannot be found, please check the parameters") - -def _get_router_id(module, neutron): - kwargs = { - 'name': module.params['router_name'], - } - try: - routers = neutron.list_routers(**kwargs) - except Exception as e: - module.fail_json(msg = "Error in getting the router list: %s " % e.message) - if not routers['routers']: - return None - return routers['routers'][0]['id'] - - -def _get_subnet_id(module, neutron): - subnet_id = None - kwargs = { - 'tenant_id': _os_tenant_id, - 'name': module.params['subnet_name'], - } - try: - subnets = neutron.list_subnets(**kwargs) - except Exception as e: - module.fail_json( msg = " Error in getting the subnet list:%s " % e.message) - if not subnets['subnets']: - return None - return subnets['subnets'][0]['id'] - -def _get_port_id(neutron, module, router_id, subnet_id): - kwargs = { - 'tenant_id': _os_tenant_id, - 'device_id': router_id, - } - try: - ports = neutron.list_ports(**kwargs) - except Exception as e: - module.fail_json( msg = "Error in listing ports: %s" % e.message) - if not ports['ports']: - return None - for port in ports['ports']: - for subnet in port['fixed_ips']: - if subnet['subnet_id'] == subnet_id: - return port['id'] - return None - -def _add_interface_router(neutron, module, router_id, subnet_id): - kwargs = { - 'subnet_id': subnet_id - } - try: - neutron.add_interface_router(router_id, kwargs) - except Exception as e: - module.fail_json(msg = "Error in adding interface to router: %s" % e.message) - return True - -def _remove_interface_router(neutron, module, router_id, subnet_id): - kwargs = { - 'subnet_id': subnet_id - } - try: - neutron.remove_interface_router(router_id, kwargs) - except Exception as e: - module.fail_json(msg="Error in removing interface from router: %s" % e.message) - return True - -def main(): - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - router_name = dict(required=True), - subnet_name = dict(required=True), - tenant_name = dict(default=None), - state = dict(default='present', choices=['absent', 'present']), - )) - module = AnsibleModule(argument_spec=argument_spec) - if not HAVE_DEPS: - module.fail_json(msg='python-keystoneclient and either python-neutronclient or python-quantumclient are required') - - neutron = _get_neutron_client(module, module.params) - _set_tenant_id(module) - - router_id = _get_router_id(module, neutron) - if not router_id: - module.fail_json(msg="failed to get the router id, please check the router name") - - subnet_id = _get_subnet_id(module, neutron) - if not subnet_id: - module.fail_json(msg="failed to get the subnet id, please check the subnet name") - - if module.params['state'] == 'present': - port_id = _get_port_id(neutron, module, router_id, subnet_id) - if not port_id: - _add_interface_router(neutron, module, router_id, subnet_id) - module.exit_json(changed=True, result="created", id=port_id) - module.exit_json(changed=False, result="success", id=port_id) - - if module.params['state'] == 'absent': - port_id = _get_port_id(neutron, module, router_id, subnet_id) - if not port_id: - module.exit_json(changed = False, result = "Success") - _remove_interface_router(neutron, module, router_id, subnet_id) - module.exit_json(changed=True, result="Deleted") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() - diff --git a/lib/ansible/modules/cloud/openstack/_quantum_subnet.py b/lib/ansible/modules/cloud/openstack/_quantum_subnet.py deleted file mode 100644 index 22dcc39ff7e..00000000000 --- a/lib/ansible/modules/cloud/openstack/_quantum_subnet.py +++ /dev/null @@ -1,313 +0,0 @@ -#!/usr/bin/python -#coding: utf-8 -*- - -# (c) 2013, Benno Joy -# -# This module is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this software. If not, see . - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['deprecated'], - 'supported_by': 'community'} - - -DOCUMENTATION = ''' ---- -module: quantum_subnet -author: "Benno Joy (@bennojoy)" -deprecated: Deprecated in 2.0. Use M(os_subnet) instead. -version_added: "1.2" -short_description: Add/remove subnet from a network -description: - - Add/remove subnet from a network -options: - login_username: - description: - - login username to authenticate to keystone - required: true - default: admin - login_password: - description: - - Password of login user - required: true - default: True - login_tenant_name: - description: - - The tenant name of the login user - required: true - default: True - auth_url: - description: - - The keystone URL for authentication - required: false - default: http://127.0.0.1:35357/v2.0/ - region_name: - description: - - Name of the region - required: false - default: None - state: - description: - - Indicate desired state of the resource - choices: ['present', 'absent'] - default: present - network_name: - description: - - Name of the network to which the subnet should be attached - required: true - default: None - name: - description: - - The name of the subnet that should be created - required: true - default: None - cidr: - description: - - The CIDR representation of the subnet that should be assigned to the subnet - required: true - default: None - tenant_name: - description: - - The name of the tenant for whom the subnet should be created - required: false - default: None - ip_version: - description: - - The IP version of the subnet 4 or 6 - required: false - default: 4 - enable_dhcp: - description: - - Whether DHCP should be enabled for this subnet. - required: false - default: true - gateway_ip: - description: - - The ip that would be assigned to the gateway for this subnet - required: false - default: None - dns_nameservers: - description: - - DNS nameservers for this subnet, comma-separated - required: false - default: None - version_added: "1.4" - allocation_pool_start: - description: - - From the subnet pool the starting address from which the IP should be allocated - required: false - default: None - allocation_pool_end: - description: - - From the subnet pool the last IP that should be assigned to the virtual machines - required: false - default: None -requirements: - - "python >= 2.6" - - "python-neutronclient or python-quantumclient" - - "python-keystoneclient" -''' - -EXAMPLES = ''' -- name: Create a subnet for a tenant with the specified subnet - quantum_subnet: - state: present - login_username: admin - login_password: admin - login_tenant_name: admin - tenant_name: tenant1 - network_name: network1 - name: net1subnet - cidr: 192.168.0.0/24 -''' - -try: - try: - from neutronclient.neutron import client - except ImportError: - from quantumclient.quantum import client - from keystoneclient.v2_0 import client as ksclient - HAVE_DEPS = True -except ImportError: - HAVE_DEPS = False - -_os_keystone = None -_os_tenant_id = None -_os_network_id = None - - -def _get_ksclient(module, kwargs): - try: - kclient = ksclient.Client(username=kwargs.get('login_username'), - password=kwargs.get('login_password'), - tenant_name=kwargs.get('login_tenant_name'), - auth_url=kwargs.get('auth_url')) - except Exception as e: - module.fail_json(msg = "Error authenticating to the keystone: %s" %e.message) - global _os_keystone - _os_keystone = kclient - return kclient - - -def _get_endpoint(module, ksclient): - try: - endpoint = ksclient.service_catalog.url_for(service_type='network', endpoint_type='publicURL') - except Exception as e: - module.fail_json(msg = "Error getting network endpoint: %s" % e.message) - return endpoint - -def _get_neutron_client(module, kwargs): - _ksclient = _get_ksclient(module, kwargs) - token = _ksclient.auth_token - endpoint = _get_endpoint(module, _ksclient) - kwargs = { - 'token': token, - 'endpoint_url': endpoint - } - try: - neutron = client.Client('2.0', **kwargs) - except Exception as e: - module.fail_json(msg = " Error in connecting to neutron: %s" % e.message) - return neutron - -def _set_tenant_id(module): - global _os_tenant_id - if not module.params['tenant_name']: - _os_tenant_id = _os_keystone.tenant_id - else: - tenant_name = module.params['tenant_name'] - - for tenant in _os_keystone.tenants.list(): - if tenant.name == tenant_name: - _os_tenant_id = tenant.id - break - if not _os_tenant_id: - module.fail_json(msg = "The tenant id cannot be found, please check the parameters") - -def _get_net_id(neutron, module): - kwargs = { - 'tenant_id': _os_tenant_id, - 'name': module.params['network_name'], - } - try: - networks = neutron.list_networks(**kwargs) - except Exception as e: - module.fail_json(msg="Error in listing neutron networks: %s" % e.message) - if not networks['networks']: - return None - return networks['networks'][0]['id'] - - -def _get_subnet_id(module, neutron): - global _os_network_id - subnet_id = None - _os_network_id = _get_net_id(neutron, module) - if not _os_network_id: - module.fail_json(msg = "network id of network not found.") - else: - kwargs = { - 'tenant_id': _os_tenant_id, - 'name': module.params['name'], - } - try: - subnets = neutron.list_subnets(**kwargs) - except Exception as e: - module.fail_json( msg = " Error in getting the subnet list:%s " % e.message) - if not subnets['subnets']: - return None - return subnets['subnets'][0]['id'] - -def _create_subnet(module, neutron): - neutron.format = 'json' - subnet = { - 'name': module.params['name'], - 'ip_version': module.params['ip_version'], - 'enable_dhcp': module.params['enable_dhcp'], - 'tenant_id': _os_tenant_id, - 'gateway_ip': module.params['gateway_ip'], - 'dns_nameservers': module.params['dns_nameservers'], - 'network_id': _os_network_id, - 'cidr': module.params['cidr'], - } - if module.params['allocation_pool_start'] and module.params['allocation_pool_end']: - allocation_pools = [ - { - 'start' : module.params['allocation_pool_start'], - 'end' : module.params['allocation_pool_end'] - } - ] - subnet.update({'allocation_pools': allocation_pools}) - if not module.params['gateway_ip']: - subnet.pop('gateway_ip') - if module.params['dns_nameservers']: - subnet['dns_nameservers'] = module.params['dns_nameservers'].split(',') - else: - subnet.pop('dns_nameservers') - try: - new_subnet = neutron.create_subnet(dict(subnet=subnet)) - except Exception as e: - module.fail_json(msg = "Failure in creating subnet: %s" % e.message) - return new_subnet['subnet']['id'] - - -def _delete_subnet(module, neutron, subnet_id): - try: - neutron.delete_subnet(subnet_id) - except Exception as e: - module.fail_json( msg = "Error in deleting subnet: %s" % e.message) - return True - - -def main(): - - argument_spec = openstack_argument_spec() - argument_spec.update(dict( - name = dict(required=True), - network_name = dict(required=True), - cidr = dict(required=True), - tenant_name = dict(default=None), - state = dict(default='present', choices=['absent', 'present']), - ip_version = dict(default='4', choices=['4', '6']), - enable_dhcp = dict(default='true', type='bool'), - gateway_ip = dict(default=None), - dns_nameservers = dict(default=None), - allocation_pool_start = dict(default=None), - allocation_pool_end = dict(default=None), - )) - module = AnsibleModule(argument_spec=argument_spec) - if not HAVE_DEPS: - module.fail_json(msg='python-keystoneclient and either python-neutronclient or python-quantumclient are required') - - neutron = _get_neutron_client(module, module.params) - _set_tenant_id(module) - if module.params['state'] == 'present': - subnet_id = _get_subnet_id(module, neutron) - if not subnet_id: - subnet_id = _create_subnet(module, neutron) - module.exit_json(changed = True, result = "Created" , id = subnet_id) - else: - module.exit_json(changed = False, result = "success" , id = subnet_id) - else: - subnet_id = _get_subnet_id(module, neutron) - if not subnet_id: - module.exit_json(changed = False, result = "success") - else: - _delete_subnet(module, neutron, subnet_id) - module.exit_json(changed = True, result = "deleted") - -# this is magic, see lib/ansible/module.params['common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * -if __name__ == '__main__': - main() -