summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/cloud/cloudstack
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ansible/modules/cloud/cloudstack')
-rw-r--r--lib/ansible/modules/cloud/cloudstack/_cs_instance_facts.py374
-rw-r--r--lib/ansible/modules/cloud/cloudstack/_cs_zone_facts.py200
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_account.py462
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_affinitygroup.py234
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_cluster.py392
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_configuration.py276
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_disk_offering.py380
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_domain.py250
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_facts.py236
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_firewall.py448
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_host.py626
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_image_store.py251
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instance.py1114
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instance_info.py378
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instance_nic.py289
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instance_nic_secondaryip.py272
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instance_password_reset.py157
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_instancegroup.py186
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_ip_address.py286
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_iso.py453
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule.py379
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule_member.py349
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_network.py644
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_network_acl.py201
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_network_acl_rule.py461
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_network_offering.py425
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_physical_network.py482
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_pod.py296
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_portforward.py398
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_project.py279
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_region.py192
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_resourcelimit.py207
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_role.py211
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_role_permission.py351
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_router.py377
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_securitygroup.py199
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_securitygroup_rule.py388
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_service_offering.py583
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_snapshot_policy.py361
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_sshkeypair.py266
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_staticnat.py256
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_storage_pool.py509
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_template.py745
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_traffic_type.py326
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_user.py445
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vlan_ip_range.py387
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vmsnapshot.py284
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_volume.py576
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vpc.py398
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vpc_offering.py322
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vpn_connection.py354
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vpn_customer_gateway.py347
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_vpn_gateway.py209
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_zone.py384
-rw-r--r--lib/ansible/modules/cloud/cloudstack/cs_zone_info.py212
55 files changed, 0 insertions, 20067 deletions
diff --git a/lib/ansible/modules/cloud/cloudstack/_cs_instance_facts.py b/lib/ansible/modules/cloud/cloudstack/_cs_instance_facts.py
deleted file mode 100644
index 6f9567448a..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/_cs_instance_facts.py
+++ /dev/null
@@ -1,374 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance_facts
-short_description: Gathering facts from the API of instances from Apache CloudStack based clouds.
-description:
- - Gathering facts from the API of an instance.
-deprecated:
- removed_in: "2.13"
- why: Transformed into an info module.
- alternative: Use M(cs_instance_info) instead.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name or display name of the instance.
- type: str
- required: true
- domain:
- description:
- - Domain the instance is related to.
- type: str
- account:
- description:
- - Account the instance is related to.
- type: str
- project:
- description:
- - Project the instance is related to.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: gather instance facts
- cs_instance_facts:
- name: web-vm-1
- delegate_to: localhost
- register: vm
-
-- debug:
- var: cloudstack_instance
-
-- debug:
- var: vm
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the instance.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the instance.
- returned: success
- type: str
- sample: web-01
-display_name:
- description: Display name of the instance.
- returned: success
- type: str
- sample: web-01
-group:
- description: Group name of the instance is related.
- returned: success
- type: str
- sample: web
-created:
- description: Date of the instance was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-password_enabled:
- description: True if password setting is enabled.
- returned: success
- type: bool
- sample: true
-password:
- description: The password of the instance if exists.
- returned: success
- type: str
- sample: Ge2oe7Do
-ssh_key:
- description: Name of SSH key deployed to instance.
- returned: success
- type: str
- sample: key@work
-domain:
- description: Domain the instance is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the instance is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the instance is related to.
- returned: success
- type: str
- sample: Production
-default_ip:
- description: Default IP address of the instance.
- returned: success
- type: str
- sample: 10.23.37.42
-public_ip:
- description: Public IP address with instance via static NAT rule.
- returned: success
- type: str
- sample: 1.2.3.4
-iso:
- description: Name of ISO the instance was deployed with.
- returned: success
- type: str
- sample: Debian-8-64bit
-template:
- description: Name of template the instance was deployed with.
- returned: success
- type: str
- sample: Debian-8-64bit
-service_offering:
- description: Name of the service offering the instance has.
- returned: success
- type: str
- sample: 2cpu_2gb
-zone:
- description: Name of zone the instance is in.
- returned: success
- type: str
- sample: ch-gva-2
-state:
- description: State of the instance.
- returned: success
- type: str
- sample: Running
-security_groups:
- description: Security groups the instance is in.
- returned: success
- type: list
- sample: '[ "default" ]'
-affinity_groups:
- description: Affinity groups the instance is in.
- returned: success
- type: list
- sample: '[ "webservers" ]'
-tags:
- description: List of resource tags associated with the instance.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-hypervisor:
- description: Hypervisor related to this instance.
- returned: success
- type: str
- sample: KVM
-host:
- description: Host the instance is running on.
- returned: success and instance is running
- type: str
- sample: host01.example.com
- version_added: '2.6'
-instance_name:
- description: Internal name of the instance (ROOT admin only).
- returned: success
- type: str
- sample: i-44-3992-VM
-volumes:
- description: List of dictionaries of the volumes attached to the instance.
- returned: success
- type: list
- sample: '[ { name: "ROOT-1369", type: "ROOT", size: 10737418240 }, { name: "data01, type: "DATADISK", size: 10737418240 } ]'
-nic:
- description: List of dictionaries of the instance nics.
- returned: success
- type: complex
- version_added: '2.8'
- contains:
- broadcasturi:
- description: The broadcast uri of the nic.
- returned: success
- type: str
- sample: vlan://2250
- gateway:
- description: The gateway of the nic.
- returned: success
- type: str
- sample: 10.1.2.1
- id:
- description: The ID of the nic.
- returned: success
- type: str
- sample: 5dc74fa3-2ec3-48a0-9e0d-6f43365336a9
- ipaddress:
- description: The ip address of the nic.
- returned: success
- type: str
- sample: 10.1.2.3
- isdefault:
- description: True if nic is default, false otherwise.
- returned: success
- type: bool
- sample: true
- isolationuri:
- description: The isolation uri of the nic.
- returned: success
- type: str
- sample: vlan://2250
- macaddress:
- description: The mac address of the nic.
- returned: success
- type: str
- sample: 06:a2:03:00:08:12
- netmask:
- description: The netmask of the nic.
- returned: success
- type: str
- sample: 255.255.255.0
- networkid:
- description: The ID of the corresponding network.
- returned: success
- type: str
- sample: 432ce27b-c2bb-4e12-a88c-a919cd3a3017
- networkname:
- description: The name of the corresponding network.
- returned: success
- type: str
- sample: network1
- traffictype:
- description: The traffic type of the nic.
- returned: success
- type: str
- sample: Guest
- type:
- description: The type of the network.
- returned: success
- type: str
- sample: Shared
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec
-
-
-class AnsibleCloudStackInstanceFacts(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstanceFacts, self).__init__(module)
- self.instance = None
- self.returns = {
- 'group': 'group',
- 'hypervisor': 'hypervisor',
- 'instancename': 'instance_name',
- 'publicip': 'public_ip',
- 'passwordenabled': 'password_enabled',
- 'password': 'password',
- 'serviceofferingname': 'service_offering',
- 'isoname': 'iso',
- 'templatename': 'template',
- 'keypair': 'ssh_key',
- 'hostname': 'host',
- }
- self.facts = {
- 'cloudstack_instance': None,
- }
-
- def get_instance(self):
- instance = self.instance
- if not instance:
- instance_name = self.module.params.get('name')
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'fetch_list': True,
- }
- # Do not pass zoneid, as the instance name must be unique across zones.
- instances = self.query_api('listVirtualMachines', **args)
- if instances:
- for v in instances:
- if instance_name.lower() in [v['name'].lower(), v['displayname'].lower(), v['id']]:
- self.instance = v
- break
- return self.instance
-
- def get_volumes(self, instance):
- volume_details = []
- if instance:
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'virtualmachineid': instance['id'],
- 'fetch_list': True,
- }
-
- volumes = self.query_api('listVolumes', **args)
- if volumes:
- for vol in volumes:
- volume_details.append({'size': vol['size'], 'type': vol['type'], 'name': vol['name']})
- return volume_details
-
- def run(self):
- instance = self.get_instance()
- if not instance:
- self.module.fail_json(msg="Instance not found: %s" % self.module.params.get('name'))
- return instance
-
- def get_result(self, instance):
- super(AnsibleCloudStackInstanceFacts, self).get_result(instance)
- if instance:
- if 'securitygroup' in instance:
- security_groups = []
- for securitygroup in instance['securitygroup']:
- security_groups.append(securitygroup['name'])
- self.result['security_groups'] = security_groups
- if 'affinitygroup' in instance:
- affinity_groups = []
- for affinitygroup in instance['affinitygroup']:
- affinity_groups.append(affinitygroup['name'])
- self.result['affinity_groups'] = affinity_groups
- if 'nic' in instance:
- for nic in instance['nic']:
- if nic['isdefault'] and 'ipaddress' in nic:
- self.result['default_ip'] = nic['ipaddress']
- self.result['nic'] = instance['nic']
- volumes = self.get_volumes(instance)
- if volumes:
- self.result['volumes'] = volumes
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- domain=dict(),
- account=dict(),
- project=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
- acs_instance_facts = AnsibleCloudStackInstanceFacts(module=module)
- cs_instance_facts = acs_instance_facts.get_result_and_facts(
- facts_name='cloudstack_instance',
- resource=acs_instance_facts.run()
- )
- module.exit_json(**cs_instance_facts)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/_cs_zone_facts.py b/lib/ansible/modules/cloud/cloudstack/_cs_zone_facts.py
deleted file mode 100644
index 91abf23fbe..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/_cs_zone_facts.py
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['deprecated'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_zone_facts
-short_description: Gathering facts of zones from Apache CloudStack based clouds.
-description:
- - Gathering facts from the API of a zone.
- - Sets Ansible facts accessible by the key C(cloudstack_zone) and since version 2.6 also returns results.
-deprecated:
- removed_in: "2.13"
- why: Transformed into an info module.
- alternative: Use M(cs_zone_info) instead.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- zone:
- description:
- - Name of the zone.
- type: str
- required: true
- aliases: [ name ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Gather facts from a zone
- cs_zone_facts:
- name: ch-gva-1
- register: zone
- delegate_to: localhost
-
-- name: Show the returned results of the registered variable
- debug:
- var: zone
-
-- name: Show the facts by the ansible_facts key cloudstack_zone
- debug:
- var: cloudstack_zone
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the zone.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the zone.
- returned: success
- type: str
- sample: zone01
-dns1:
- description: First DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
-dns2:
- description: Second DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
-internal_dns1:
- description: First internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
-internal_dns2:
- description: Second internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
-dns1_ipv6:
- description: First IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8888"
-dns2_ipv6:
- description: Second IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8844"
-allocation_state:
- description: State of the zone.
- returned: success
- type: str
- sample: Enabled
-domain:
- description: Domain the zone is related to.
- returned: success
- type: str
- sample: ROOT
-network_domain:
- description: Network domain for the zone.
- returned: success
- type: str
- sample: example.com
-network_type:
- description: Network type for the zone.
- returned: success
- type: str
- sample: basic
-local_storage_enabled:
- description: Local storage offering enabled.
- returned: success
- type: bool
- sample: false
-securitygroups_enabled:
- description: Security groups support is enabled.
- returned: success
- type: bool
- sample: false
-guest_cidr_address:
- description: Guest CIDR address for the zone
- returned: success
- type: str
- sample: 10.1.1.0/24
-dhcp_provider:
- description: DHCP provider for the zone
- returned: success
- type: str
- sample: VirtualRouter
-zone_token:
- description: Zone token
- returned: success
- type: str
- sample: ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7
-tags:
- description: List of resource tags associated with the zone.
- returned: success
- type: dict
- sample: [ { "key": "foo", "value": "bar" } ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
-)
-
-
-class AnsibleCloudStackZoneFacts(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackZoneFacts, self).__init__(module)
- self.returns = {
- 'dns1': 'dns1',
- 'dns2': 'dns2',
- 'internaldns1': 'internal_dns1',
- 'internaldns2': 'internal_dns2',
- 'ipv6dns1': 'dns1_ipv6',
- 'ipv6dns2': 'dns2_ipv6',
- 'domain': 'network_domain',
- 'networktype': 'network_type',
- 'securitygroupsenabled': 'securitygroups_enabled',
- 'localstorageenabled': 'local_storage_enabled',
- 'guestcidraddress': 'guest_cidr_address',
- 'dhcpprovider': 'dhcp_provider',
- 'allocationstate': 'allocation_state',
- 'zonetoken': 'zone_token',
- }
-
- def get_zone(self):
- return super(AnsibleCloudStackZoneFacts, self).get_zone()
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- zone=dict(required=True, aliases=['name']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- acs_zone_facts = AnsibleCloudStackZoneFacts(module=module)
- result = acs_zone_facts.get_result_and_facts(
- facts_name='cloudstack_zone',
- resource=acs_zone_facts.get_zone()
- )
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_account.py b/lib/ansible/modules/cloud/cloudstack/cs_account.py
deleted file mode 100644
index 3f3c50b805..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_account.py
+++ /dev/null
@@ -1,462 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_account
-short_description: Manages accounts on Apache CloudStack based clouds.
-description:
- - Create, disable, lock, enable and remove accounts.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of account.
- type: str
- required: true
- username:
- description:
- - Username of the user to be created if account did not exist.
- - Required on I(state=present).
- type: str
- password:
- description:
- - Password of the user to be created if account did not exist.
- - Required on I(state=present) if I(ldap_domain) is not set.
- type: str
- first_name:
- description:
- - First name of the user to be created if account did not exist.
- - Required on I(state=present) if I(ldap_domain) is not set.
- type: str
- last_name:
- description:
- - Last name of the user to be created if account did not exist.
- - Required on I(state=present) if I(ldap_domain) is not set.
- type: str
- email:
- description:
- - Email of the user to be created if account did not exist.
- - Required on I(state=present) if I(ldap_domain) is not set.
- type: str
- timezone:
- description:
- - Timezone of the user to be created if account did not exist.
- type: str
- network_domain:
- description:
- - Network domain of the account.
- type: str
- account_type:
- description:
- - Type of the account.
- type: str
- choices: [ user, root_admin, domain_admin ]
- default: user
- domain:
- description:
- - Domain the account is related to.
- type: str
- default: ROOT
- role:
- description:
- - Creates the account under the specified role name or id.
- type: str
- version_added: '2.8'
- ldap_domain:
- description:
- - Name of the LDAP group or OU to bind.
- - If set, account will be linked to LDAP.
- type: str
- version_added: '2.8'
- ldap_type:
- description:
- - Type of the ldap name. GROUP or OU, defaults to GROUP.
- type: str
- choices: [ GROUP, OU ]
- default: GROUP
- version_added: '2.8'
- state:
- description:
- - State of the account.
- - C(unlocked) is an alias for C(enabled).
- type: str
- choices: [ present, absent, enabled, disabled, locked, unlocked ]
- default: present
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create an account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- username: customer_xy
- password: S3Cur3
- last_name: Doe
- first_name: John
- email: john.doe@example.com
- domain: CUSTOMERS
- role: Domain Admin
- delegate_to: localhost
-
-- name: Lock an existing account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- domain: CUSTOMERS
- state: locked
- delegate_to: localhost
-
-- name: Disable an existing account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- domain: CUSTOMERS
- state: disabled
- delegate_to: localhost
-
-- name: Enable an existing account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- domain: CUSTOMERS
- state: enabled
- delegate_to: localhost
-
-- name: Remove an account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- domain: CUSTOMERS
- state: absent
- delegate_to: localhost
-
-- name: Create a single user LDAP account in domain 'CUSTOMERS'
- cs_account:
- name: customer_xy
- username: customer_xy
- domain: CUSTOMERS
- ldap_domain: cn=customer_xy,cn=team_xy,ou=People,dc=domain,dc=local
- delegate_to: localhost
-
-- name: Create a LDAP account in domain 'CUSTOMERS' and bind it to a LDAP group
- cs_account:
- name: team_xy
- username: customer_xy
- domain: CUSTOMERS
- ldap_domain: cn=team_xy,ou=People,dc=domain,dc=local
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the account.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-name:
- description: Name of the account.
- returned: success
- type: str
- sample: linus@example.com
-account_type:
- description: Type of the account.
- returned: success
- type: str
- sample: user
-state:
- description: State of the account.
- returned: success
- type: str
- sample: enabled
-network_domain:
- description: Network domain of the account.
- returned: success
- type: str
- sample: example.local
-domain:
- description: Domain the account is related.
- returned: success
- type: str
- sample: ROOT
-role:
- description: The role name of the account
- returned: success
- type: str
- sample: Domain Admin
-'''
-
-# import cloudstack common
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackAccount(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackAccount, self).__init__(module)
- self.returns = {
- 'networkdomain': 'network_domain',
- 'rolename': 'role',
- }
- self.account = None
- self.account_types = {
- 'user': 0,
- 'root_admin': 1,
- 'domain_admin': 2,
- }
-
- def get_role_id(self):
- role_param = self.module.params.get('role')
- role_id = None
-
- if role_param:
- role_list = self.query_api('listRoles')
- for role in role_list['role']:
- if role_param in [role['name'], role['id']]:
- role_id = role['id']
-
- if not role_id:
- self.module.fail_json(msg="Role not found: %s" % role_param)
-
- return role_id
-
- def get_account_type(self):
- account_type = self.module.params.get('account_type')
- return self.account_types[account_type]
-
- def get_account(self):
- if not self.account:
- args = {
- 'listall': True,
- 'domainid': self.get_domain(key='id'),
- 'fetch_list': True,
- }
- accounts = self.query_api('listAccounts', **args)
- if accounts:
- account_name = self.module.params.get('name')
- for a in accounts:
- if account_name == a['name']:
- self.account = a
- break
-
- return self.account
-
- def enable_account(self):
- account = self.get_account()
- if not account:
- account = self.present_account()
-
- if account['state'].lower() != 'enabled':
- self.result['changed'] = True
- args = {
- 'id': account['id'],
- 'account': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id')
- }
- if not self.module.check_mode:
- res = self.query_api('enableAccount', **args)
- account = res['account']
- return account
-
- def lock_account(self):
- return self.lock_or_disable_account(lock=True)
-
- def disable_account(self):
- return self.lock_or_disable_account()
-
- def lock_or_disable_account(self, lock=False):
- account = self.get_account()
- if not account:
- account = self.present_account()
-
- # we need to enable the account to lock it.
- if lock and account['state'].lower() == 'disabled':
- account = self.enable_account()
-
- if (lock and account['state'].lower() != 'locked' or
- not lock and account['state'].lower() != 'disabled'):
- self.result['changed'] = True
- args = {
- 'id': account['id'],
- 'account': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- 'lock': lock,
- }
- if not self.module.check_mode:
- account = self.query_api('disableAccount', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- account = self.poll_job(account, 'account')
- return account
-
- def present_account(self):
- account = self.get_account()
-
- if not account:
- self.result['changed'] = True
-
- if self.module.params.get('ldap_domain'):
- required_params = [
- 'domain',
- 'username',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- account = self.create_ldap_account(account)
-
- else:
- required_params = [
- 'email',
- 'username',
- 'password',
- 'first_name',
- 'last_name',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- account = self.create_account(account)
-
- return account
-
- def create_ldap_account(self, account):
- args = {
- 'account': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- 'accounttype': self.get_account_type(),
- 'networkdomain': self.module.params.get('network_domain'),
- 'username': self.module.params.get('username'),
- 'timezone': self.module.params.get('timezone'),
- 'roleid': self.get_role_id()
- }
- if not self.module.check_mode:
- res = self.query_api('ldapCreateAccount', **args)
- account = res['account']
-
- args = {
- 'account': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- 'accounttype': self.get_account_type(),
- 'ldapdomain': self.module.params.get('ldap_domain'),
- 'type': self.module.params.get('ldap_type')
- }
-
- self.query_api('linkAccountToLdap', **args)
-
- return account
-
- def create_account(self, account):
- args = {
- 'account': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- 'accounttype': self.get_account_type(),
- 'networkdomain': self.module.params.get('network_domain'),
- 'username': self.module.params.get('username'),
- 'password': self.module.params.get('password'),
- 'firstname': self.module.params.get('first_name'),
- 'lastname': self.module.params.get('last_name'),
- 'email': self.module.params.get('email'),
- 'timezone': self.module.params.get('timezone'),
- 'roleid': self.get_role_id()
- }
- if not self.module.check_mode:
- res = self.query_api('createAccount', **args)
- account = res['account']
-
- return account
-
- def absent_account(self):
- account = self.get_account()
- if account:
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('deleteAccount', id=account['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'account')
- return account
-
- def get_result(self, account):
- super(AnsibleCloudStackAccount, self).get_result(account)
- if account:
- if 'accounttype' in account:
- for key, value in self.account_types.items():
- if value == account['accounttype']:
- self.result['account_type'] = key
- break
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent', 'enabled', 'disabled', 'locked', 'unlocked'], default='present'),
- account_type=dict(choices=['user', 'root_admin', 'domain_admin'], default='user'),
- network_domain=dict(),
- domain=dict(default='ROOT'),
- email=dict(),
- first_name=dict(),
- last_name=dict(),
- username=dict(),
- password=dict(no_log=True),
- timezone=dict(),
- role=dict(),
- ldap_domain=dict(),
- ldap_type=dict(choices=['GROUP', 'OU'], default='GROUP'),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_acc = AnsibleCloudStackAccount(module)
-
- state = module.params.get('state')
-
- if state in ['absent']:
- account = acs_acc.absent_account()
-
- elif state in ['enabled', 'unlocked']:
- account = acs_acc.enable_account()
-
- elif state in ['disabled']:
- account = acs_acc.disable_account()
-
- elif state in ['locked']:
- account = acs_acc.lock_account()
-
- else:
- account = acs_acc.present_account()
-
- result = acs_acc.get_result(account)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_affinitygroup.py b/lib/ansible/modules/cloud/cloudstack/cs_affinitygroup.py
deleted file mode 100644
index 3e57d1e208..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_affinitygroup.py
+++ /dev/null
@@ -1,234 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_affinitygroup
-short_description: Manages affinity groups on Apache CloudStack based clouds.
-description:
- - Create and remove affinity groups.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the affinity group.
- type: str
- required: true
- affinity_type:
- description:
- - Type of the affinity group. If not specified, first found affinity type is used.
- type: str
- description:
- description:
- - Description of the affinity group.
- type: str
- state:
- description:
- - State of the affinity group.
- type: str
- choices: [ present, absent ]
- default: present
- domain:
- description:
- - Domain the affinity group is related to.
- type: str
- account:
- description:
- - Account the affinity group is related to.
- type: str
- project:
- description:
- - Name of the project the affinity group is related to.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a affinity group
- cs_affinitygroup:
- name: haproxy
- affinity_type: host anti-affinity
- delegate_to: localhost
-
-- name: Remove a affinity group
- cs_affinitygroup:
- name: haproxy
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the affinity group.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-name:
- description: Name of affinity group.
- returned: success
- type: str
- sample: app
-description:
- description: Description of affinity group.
- returned: success
- type: str
- sample: application affinity group
-affinity_type:
- description: Type of affinity group.
- returned: success
- type: str
- sample: host anti-affinity
-project:
- description: Name of project the affinity group is related to.
- returned: success
- type: str
- sample: Production
-domain:
- description: Domain the affinity group is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the affinity group is related to.
- returned: success
- type: str
- sample: example account
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackAffinityGroup(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackAffinityGroup, self).__init__(module)
- self.returns = {
- 'type': 'affinity_type',
- }
- self.affinity_group = None
-
- def get_affinity_group(self):
- if not self.affinity_group:
-
- args = {
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'name': self.module.params.get('name'),
- }
- affinity_groups = self.query_api('listAffinityGroups', **args)
- if affinity_groups:
- self.affinity_group = affinity_groups['affinitygroup'][0]
- return self.affinity_group
-
- def get_affinity_type(self):
- affinity_type = self.module.params.get('affinity_type')
-
- affinity_types = self.query_api('listAffinityGroupTypes', )
- if affinity_types:
- if not affinity_type:
- return affinity_types['affinityGroupType'][0]['type']
-
- for a in affinity_types['affinityGroupType']:
- if a['type'] == affinity_type:
- return a['type']
- self.module.fail_json(msg="affinity group type not found: %s" % affinity_type)
-
- def create_affinity_group(self):
- affinity_group = self.get_affinity_group()
- if not affinity_group:
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'type': self.get_affinity_type(),
- 'description': self.module.params.get('description'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- }
- if not self.module.check_mode:
- res = self.query_api('createAffinityGroup', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- affinity_group = self.poll_job(res, 'affinitygroup')
- return affinity_group
-
- def remove_affinity_group(self):
- affinity_group = self.get_affinity_group()
- if affinity_group:
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- }
- if not self.module.check_mode:
- res = self.query_api('deleteAffinityGroup', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- self.poll_job(res, 'affinitygroup')
- return affinity_group
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- affinity_type=dict(),
- description=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_ag = AnsibleCloudStackAffinityGroup(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- affinity_group = acs_ag.remove_affinity_group()
- else:
- affinity_group = acs_ag.create_affinity_group()
-
- result = acs_ag.get_result(affinity_group)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_cluster.py b/lib/ansible/modules/cloud/cloudstack/cs_cluster.py
deleted file mode 100644
index e1ee3b1c55..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_cluster.py
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_cluster
-short_description: Manages host clusters on Apache CloudStack based clouds.
-description:
- - Create, update and remove clusters.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - name of the cluster.
- type: str
- required: true
- zone:
- description:
- - Name of the zone in which the cluster belongs to.
- - If not set, default zone is used.
- type: str
- pod:
- description:
- - Name of the pod in which the cluster belongs to.
- type: str
- cluster_type:
- description:
- - Type of the cluster.
- - Required if I(state=present)
- type: str
- choices: [ CloudManaged, ExternalManaged ]
- hypervisor:
- description:
- - Name the hypervisor to be used.
- - Required if I(state=present).
- - Possible values are C(KVM), C(VMware), C(BareMetal), C(XenServer), C(LXC), C(HyperV), C(UCS), C(OVM), C(Simulator).
- type: str
- url:
- description:
- - URL for the cluster
- type: str
- username:
- description:
- - Username for the cluster.
- type: str
- password:
- description:
- - Password for the cluster.
- type: str
- guest_vswitch_name:
- description:
- - Name of virtual switch used for guest traffic in the cluster.
- - This would override zone wide traffic label setting.
- type: str
- guest_vswitch_type:
- description:
- - Type of virtual switch used for guest traffic in the cluster.
- - Allowed values are, vmwaresvs (for VMware standard vSwitch) and vmwaredvs (for VMware distributed vSwitch)
- type: str
- choices: [ vmwaresvs, vmwaredvs ]
- public_vswitch_name:
- description:
- - Name of virtual switch used for public traffic in the cluster.
- - This would override zone wide traffic label setting.
- type: str
- public_vswitch_type:
- description:
- - Type of virtual switch used for public traffic in the cluster.
- - Allowed values are, vmwaresvs (for VMware standard vSwitch) and vmwaredvs (for VMware distributed vSwitch)
- type: str
- choices: [ vmwaresvs, vmwaredvs ]
- vms_ip_address:
- description:
- - IP address of the VSM associated with this cluster.
- type: str
- vms_username:
- description:
- - Username for the VSM associated with this cluster.
- type: str
- vms_password:
- description:
- - Password for the VSM associated with this cluster.
- type: str
- ovm3_cluster:
- description:
- - Ovm3 native OCFS2 clustering enabled for cluster.
- type: str
- ovm3_pool:
- description:
- - Ovm3 native pooling enabled for cluster.
- type: str
- ovm3_vip:
- description:
- - Ovm3 vip to use for pool (and cluster).
- type: str
- state:
- description:
- - State of the cluster.
- type: str
- choices: [ present, absent, disabled, enabled ]
- default: present
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a cluster is present
- cs_cluster:
- name: kvm-cluster-01
- zone: ch-zrh-ix-01
- hypervisor: KVM
- cluster_type: CloudManaged
- delegate_to: localhost
-
-- name: Ensure a cluster is disabled
- cs_cluster:
- name: kvm-cluster-01
- zone: ch-zrh-ix-01
- state: disabled
- delegate_to: localhost
-
-- name: Ensure a cluster is enabled
- cs_cluster:
- name: kvm-cluster-01
- zone: ch-zrh-ix-01
- state: enabled
- delegate_to: localhost
-
-- name: Ensure a cluster is absent
- cs_cluster:
- name: kvm-cluster-01
- zone: ch-zrh-ix-01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the cluster.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the cluster.
- returned: success
- type: str
- sample: cluster01
-allocation_state:
- description: State of the cluster.
- returned: success
- type: str
- sample: Enabled
-cluster_type:
- description: Type of the cluster.
- returned: success
- type: str
- sample: ExternalManaged
-cpu_overcommit_ratio:
- description: The CPU overcommit ratio of the cluster.
- returned: success
- type: str
- sample: 1.0
-memory_overcommit_ratio:
- description: The memory overcommit ratio of the cluster.
- returned: success
- type: str
- sample: 1.0
-managed_state:
- description: Whether this cluster is managed by CloudStack.
- returned: success
- type: str
- sample: Managed
-ovm3_vip:
- description: Ovm3 VIP to use for pooling and/or clustering
- returned: success
- type: str
- sample: 10.10.10.101
-hypervisor:
- description: Hypervisor of the cluster
- returned: success
- type: str
- sample: VMware
-zone:
- description: Name of zone the cluster is in.
- returned: success
- type: str
- sample: ch-gva-2
-pod:
- description: Name of pod the cluster is in.
- returned: success
- type: str
- sample: pod01
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackCluster(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackCluster, self).__init__(module)
- self.returns = {
- 'allocationstate': 'allocation_state',
- 'hypervisortype': 'hypervisor',
- 'clustertype': 'cluster_type',
- 'podname': 'pod',
- 'managedstate': 'managed_state',
- 'memoryovercommitratio': 'memory_overcommit_ratio',
- 'cpuovercommitratio': 'cpu_overcommit_ratio',
- 'ovm3vip': 'ovm3_vip',
- }
- self.cluster = None
-
- def _get_common_cluster_args(self):
- args = {
- 'clustername': self.module.params.get('name'),
- 'hypervisor': self.module.params.get('hypervisor'),
- 'clustertype': self.module.params.get('cluster_type'),
- }
- state = self.module.params.get('state')
- if state in ['enabled', 'disabled']:
- args['allocationstate'] = state.capitalize()
- return args
-
- def get_pod(self, key=None):
- args = {
- 'name': self.module.params.get('pod'),
- 'zoneid': self.get_zone(key='id'),
- }
- pods = self.query_api('listPods', **args)
- if pods:
- return self._get_by_key(key, pods['pod'][0])
- self.module.fail_json(msg="Pod %s not found in zone %s" % (self.module.params.get('pod'), self.get_zone(key='name')))
-
- def get_cluster(self):
- if not self.cluster:
- args = {}
-
- uuid = self.module.params.get('id')
- if uuid:
- args['id'] = uuid
- clusters = self.query_api('listClusters', **args)
- if clusters:
- self.cluster = clusters['cluster'][0]
- return self.cluster
-
- args['name'] = self.module.params.get('name')
- clusters = self.query_api('listClusters', **args)
- if clusters:
- self.cluster = clusters['cluster'][0]
- # fix different return from API then request argument given
- self.cluster['hypervisor'] = self.cluster['hypervisortype']
- self.cluster['clustername'] = self.cluster['name']
- return self.cluster
-
- def present_cluster(self):
- cluster = self.get_cluster()
- if cluster:
- cluster = self._update_cluster()
- else:
- cluster = self._create_cluster()
- return cluster
-
- def _create_cluster(self):
- required_params = [
- 'cluster_type',
- 'hypervisor',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- args = self._get_common_cluster_args()
- args['zoneid'] = self.get_zone(key='id')
- args['podid'] = self.get_pod(key='id')
- args['url'] = self.module.params.get('url')
- args['username'] = self.module.params.get('username')
- args['password'] = self.module.params.get('password')
- args['guestvswitchname'] = self.module.params.get('guest_vswitch_name')
- args['guestvswitchtype'] = self.module.params.get('guest_vswitch_type')
- args['publicvswitchtype'] = self.module.params.get('public_vswitch_name')
- args['publicvswitchtype'] = self.module.params.get('public_vswitch_type')
- args['vsmipaddress'] = self.module.params.get('vms_ip_address')
- args['vsmusername'] = self.module.params.get('vms_username')
- args['vmspassword'] = self.module.params.get('vms_password')
- args['ovm3cluster'] = self.module.params.get('ovm3_cluster')
- args['ovm3pool'] = self.module.params.get('ovm3_pool')
- args['ovm3vip'] = self.module.params.get('ovm3_vip')
-
- self.result['changed'] = True
-
- cluster = None
- if not self.module.check_mode:
- res = self.query_api('addCluster', **args)
-
- # API returns a list as result CLOUDSTACK-9205
- if isinstance(res['cluster'], list):
- cluster = res['cluster'][0]
- else:
- cluster = res['cluster']
- return cluster
-
- def _update_cluster(self):
- cluster = self.get_cluster()
-
- args = self._get_common_cluster_args()
- args['id'] = cluster['id']
-
- if self.has_changed(args, cluster):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateCluster', **args)
- cluster = res['cluster']
-
- return cluster
-
- def absent_cluster(self):
- cluster = self.get_cluster()
- if cluster:
- self.result['changed'] = True
-
- args = {
- 'id': cluster['id'],
- }
-
- if not self.module.check_mode:
- self.query_api('deleteCluster', **args)
-
- return cluster
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- zone=dict(),
- pod=dict(),
- cluster_type=dict(choices=['CloudManaged', 'ExternalManaged']),
- hypervisor=dict(),
- state=dict(choices=['present', 'enabled', 'disabled', 'absent'], default='present'),
- url=dict(),
- username=dict(),
- password=dict(no_log=True),
- guest_vswitch_name=dict(),
- guest_vswitch_type=dict(choices=['vmwaresvs', 'vmwaredvs']),
- public_vswitch_name=dict(),
- public_vswitch_type=dict(choices=['vmwaresvs', 'vmwaredvs']),
- vms_ip_address=dict(),
- vms_username=dict(),
- vms_password=dict(no_log=True),
- ovm3_cluster=dict(),
- ovm3_pool=dict(),
- ovm3_vip=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_cluster = AnsibleCloudStackCluster(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- cluster = acs_cluster.absent_cluster()
- else:
- cluster = acs_cluster.present_cluster()
-
- result = acs_cluster.get_result(cluster)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_configuration.py b/lib/ansible/modules/cloud/cloudstack/cs_configuration.py
deleted file mode 100644
index 79e01990f1..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_configuration.py
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_configuration
-short_description: Manages configuration on Apache CloudStack based clouds.
-description:
- - Manages global, zone, account, storage and cluster configurations.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the configuration.
- type: str
- required: true
- value:
- description:
- - Value of the configuration.
- type: str
- required: true
- account:
- description:
- - Ensure the value for corresponding account.
- type: str
- domain:
- description:
- - Domain the account is related to.
- - Only considered if I(account) is used.
- type: str
- default: ROOT
- zone:
- description:
- - Ensure the value for corresponding zone.
- type: str
- storage:
- description:
- - Ensure the value for corresponding storage pool.
- type: str
- cluster:
- description:
- - Ensure the value for corresponding cluster.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure global configuration
- cs_configuration:
- name: router.reboot.when.outofband.migrated
- value: false
- delegate_to: localhost
-
-- name: Ensure zone configuration
- cs_configuration:
- name: router.reboot.when.outofband.migrated
- zone: ch-gva-01
- value: true
- delegate_to: localhost
-
-- name: Ensure storage configuration
- cs_configuration:
- name: storage.overprovisioning.factor
- storage: storage01
- value: 2.0
- delegate_to: localhost
-
-- name: Ensure account configuration
- cs_configuration:
- name: allow.public.user.templates
- value: false
- account: acme inc
- domain: customers
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-category:
- description: Category of the configuration.
- returned: success
- type: str
- sample: Advanced
-scope:
- description: Scope (zone/cluster/storagepool/account) of the parameter that needs to be updated.
- returned: success
- type: str
- sample: storagepool
-description:
- description: Description of the configuration.
- returned: success
- type: str
- sample: Setup the host to do multipath
-name:
- description: Name of the configuration.
- returned: success
- type: str
- sample: zone.vlan.capacity.notificationthreshold
-value:
- description: Value of the configuration.
- returned: success
- type: str
- sample: "0.75"
-account:
- description: Account of the configuration.
- returned: success
- type: str
- sample: admin
-Domain:
- description: Domain of account of the configuration.
- returned: success
- type: str
- sample: ROOT
-zone:
- description: Zone of the configuration.
- returned: success
- type: str
- sample: ch-gva-01
-cluster:
- description: Cluster of the configuration.
- returned: success
- type: str
- sample: cluster01
-storage:
- description: Storage of the configuration.
- returned: success
- type: str
- sample: storage01
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackConfiguration(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackConfiguration, self).__init__(module)
- self.returns = {
- 'category': 'category',
- 'scope': 'scope',
- 'value': 'value',
- }
- self.storage = None
- self.account = None
- self.cluster = None
-
- def _get_common_configuration_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'accountid': self.get_account(key='id'),
- 'storageid': self.get_storage(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'clusterid': self.get_cluster(key='id'),
- }
- return args
-
- def get_zone(self, key=None):
- # make sure we do net use the default zone
- zone = self.module.params.get('zone')
- if zone:
- return super(AnsibleCloudStackConfiguration, self).get_zone(key=key)
-
- def get_cluster(self, key=None):
- if not self.cluster:
- cluster_name = self.module.params.get('cluster')
- if not cluster_name:
- return None
- args = {
- 'name': cluster_name,
- }
- clusters = self.query_api('listClusters', **args)
- if clusters:
- self.cluster = clusters['cluster'][0]
- self.result['cluster'] = self.cluster['name']
- else:
- self.module.fail_json(msg="Cluster %s not found." % cluster_name)
- return self._get_by_key(key=key, my_dict=self.cluster)
-
- def get_storage(self, key=None):
- if not self.storage:
- storage_pool_name = self.module.params.get('storage')
- if not storage_pool_name:
- return None
- args = {
- 'name': storage_pool_name,
- }
- storage_pools = self.query_api('listStoragePools', **args)
- if storage_pools:
- self.storage = storage_pools['storagepool'][0]
- self.result['storage'] = self.storage['name']
- else:
- self.module.fail_json(msg="Storage pool %s not found." % storage_pool_name)
- return self._get_by_key(key=key, my_dict=self.storage)
-
- def get_configuration(self):
- configuration = None
- args = self._get_common_configuration_args()
- args['fetch_list'] = True
- configurations = self.query_api('listConfigurations', **args)
- if not configurations:
- self.module.fail_json(msg="Configuration %s not found." % args['name'])
- for config in configurations:
- if args['name'] == config['name']:
- configuration = config
- return configuration
-
- def get_value(self):
- value = str(self.module.params.get('value'))
- if value in ('True', 'False'):
- value = value.lower()
- return value
-
- def present_configuration(self):
- configuration = self.get_configuration()
- args = self._get_common_configuration_args()
- args['value'] = self.get_value()
- if self.has_changed(args, configuration, ['value']):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateConfiguration', **args)
- configuration = res['configuration']
- return configuration
-
- def get_result(self, configuration):
- self.result = super(AnsibleCloudStackConfiguration, self).get_result(configuration)
- if self.account:
- self.result['account'] = self.account['name']
- self.result['domain'] = self.domain['path']
- elif self.zone:
- self.result['zone'] = self.zone['name']
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- value=dict(type='str', required=True),
- zone=dict(),
- storage=dict(),
- cluster=dict(),
- account=dict(),
- domain=dict(default='ROOT')
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_configuration = AnsibleCloudStackConfiguration(module)
- configuration = acs_configuration.present_configuration()
- result = acs_configuration.get_result(configuration)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_disk_offering.py b/lib/ansible/modules/cloud/cloudstack/cs_disk_offering.py
deleted file mode 100644
index da4bd1f6b5..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_disk_offering.py
+++ /dev/null
@@ -1,380 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2018, David Passante <@dpassante>
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_disk_offering
-description:
- - Create and delete disk offerings for guest VMs.
- - Update display_text or display_offering of existing disk offering.
-short_description: Manages disk offerings on Apache CloudStack based clouds.
-version_added: '2.7'
-author:
- - David Passante (@dpassante)
- - René Moser (@resmo)
-options:
- disk_size:
- description:
- - Size of the disk offering in GB (1GB = 1,073,741,824 bytes).
- type: int
- bytes_read_rate:
- description:
- - Bytes read rate of the disk offering.
- type: int
- bytes_write_rate:
- description:
- - Bytes write rate of the disk offering.
- type: int
- display_text:
- description:
- - Display text of the disk offering.
- - If not set, C(name) will be used as C(display_text) while creating.
- type: str
- domain:
- description:
- - Domain the disk offering is related to.
- - Public for all domains and subdomains if not set.
- type: str
- hypervisor_snapshot_reserve:
- description:
- - Hypervisor snapshot reserve space as a percent of a volume.
- - Only for managed storage using Xen or VMware.
- type: int
- customized:
- description:
- - Whether disk offering iops is custom or not.
- type: bool
- default: no
- iops_read_rate:
- description:
- - IO requests read rate of the disk offering.
- type: int
- iops_write_rate:
- description:
- - IO requests write rate of the disk offering.
- type: int
- iops_max:
- description:
- - Max. iops of the disk offering.
- type: int
- iops_min:
- description:
- - Min. iops of the disk offering.
- type: int
- name:
- description:
- - Name of the disk offering.
- type: str
- required: true
- provisioning_type:
- description:
- - Provisioning type used to create volumes.
- type: str
- choices: [ thin, sparse, fat ]
- state:
- description:
- - State of the disk offering.
- type: str
- choices: [ present, absent ]
- default: present
- storage_type:
- description:
- - The storage type of the disk offering.
- type: str
- choices: [ local, shared ]
- storage_tags:
- description:
- - The storage tags for this disk offering.
- type: list
- aliases: [ storage_tag ]
- display_offering:
- description:
- - An optional field, whether to display the offering to the end user or not.
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a disk offering with local storage
- cs_disk_offering:
- name: small
- display_text: Small 10GB
- disk_size: 10
- storage_type: local
- delegate_to: localhost
-
-- name: Create or update a disk offering with shared storage
- cs_disk_offering:
- name: small
- display_text: Small 10GB
- disk_size: 10
- storage_type: shared
- storage_tags: SAN01
- delegate_to: localhost
-
-- name: Remove a disk offering
- cs_disk_offering:
- name: small
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the disk offering
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-disk_size:
- description: Size of the disk offering in GB
- returned: success
- type: int
- sample: 10
-iops_max:
- description: Max iops of the disk offering
- returned: success
- type: int
- sample: 1000
-iops_min:
- description: Min iops of the disk offering
- returned: success
- type: int
- sample: 500
-bytes_read_rate:
- description: Bytes read rate of the disk offering
- returned: success
- type: int
- sample: 1000
-bytes_write_rate:
- description: Bytes write rate of the disk offering
- returned: success
- type: int
- sample: 1000
-iops_read_rate:
- description: IO requests per second read rate of the disk offering
- returned: success
- type: int
- sample: 1000
-iops_write_rate:
- description: IO requests per second write rate of the disk offering
- returned: success
- type: int
- sample: 1000
-created:
- description: Date the offering was created
- returned: success
- type: str
- sample: 2017-11-19T10:48:59+0000
-display_text:
- description: Display text of the offering
- returned: success
- type: str
- sample: Small 10GB
-domain:
- description: Domain the offering is into
- returned: success
- type: str
- sample: ROOT
-storage_tags:
- description: List of storage tags
- returned: success
- type: list
- sample: [ 'eco' ]
-customized:
- description: Whether the offering uses custom IOPS or not
- returned: success
- type: bool
- sample: false
-name:
- description: Name of the system offering
- returned: success
- type: str
- sample: Micro
-provisioning_type:
- description: Provisioning type used to create volumes
- returned: success
- type: str
- sample: thin
-storage_type:
- description: Storage type used to create volumes
- returned: success
- type: str
- sample: shared
-display_offering:
- description: Whether to display the offering to the end user or not.
- returned: success
- type: bool
- sample: false
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackDiskOffering(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackDiskOffering, self).__init__(module)
- self.returns = {
- 'disksize': 'disk_size',
- 'diskBytesReadRate': 'bytes_read_rate',
- 'diskBytesWriteRate': 'bytes_write_rate',
- 'diskIopsReadRate': 'iops_read_rate',
- 'diskIopsWriteRate': 'iops_write_rate',
- 'maxiops': 'iops_max',
- 'miniops': 'iops_min',
- 'hypervisorsnapshotreserve': 'hypervisor_snapshot_reserve',
- 'customized': 'customized',
- 'provisioningtype': 'provisioning_type',
- 'storagetype': 'storage_type',
- 'tags': 'storage_tags',
- 'displayoffering': 'display_offering',
- }
-
- self.disk_offering = None
-
- def get_disk_offering(self):
- args = {
- 'name': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- }
- disk_offerings = self.query_api('listDiskOfferings', **args)
- if disk_offerings:
- for disk_offer in disk_offerings['diskoffering']:
- if args['name'] == disk_offer['name']:
- self.disk_offering = disk_offer
-
- return self.disk_offering
-
- def present_disk_offering(self):
- disk_offering = self.get_disk_offering()
- if not disk_offering:
- disk_offering = self._create_offering(disk_offering)
- else:
- disk_offering = self._update_offering(disk_offering)
-
- return disk_offering
-
- def absent_disk_offering(self):
- disk_offering = self.get_disk_offering()
- if disk_offering:
- self.result['changed'] = True
- if not self.module.check_mode:
- args = {
- 'id': disk_offering['id'],
- }
- self.query_api('deleteDiskOffering', **args)
- return disk_offering
-
- def _create_offering(self, disk_offering):
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'disksize': self.module.params.get('disk_size'),
- 'bytesreadrate': self.module.params.get('bytes_read_rate'),
- 'byteswriterate': self.module.params.get('bytes_write_rate'),
- 'customized': self.module.params.get('customized'),
- 'domainid': self.get_domain(key='id'),
- 'hypervisorsnapshotreserve': self.module.params.get('hypervisor_snapshot_reserve'),
- 'iopsreadrate': self.module.params.get('iops_read_rate'),
- 'iopswriterate': self.module.params.get('iops_write_rate'),
- 'maxiops': self.module.params.get('iops_max'),
- 'miniops': self.module.params.get('iops_min'),
- 'provisioningtype': self.module.params.get('provisioning_type'),
- 'diskofferingdetails': self.module.params.get('disk_offering_details'),
- 'storagetype': self.module.params.get('storage_type'),
- 'tags': self.module.params.get('storage_tags'),
- 'displayoffering': self.module.params.get('display_offering'),
- }
- if not self.module.check_mode:
- res = self.query_api('createDiskOffering', **args)
- disk_offering = res['diskoffering']
- return disk_offering
-
- def _update_offering(self, disk_offering):
- args = {
- 'id': disk_offering['id'],
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'displayoffering': self.module.params.get('display_offering'),
- }
- if self.has_changed(args, disk_offering):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateDiskOffering', **args)
- disk_offering = res['diskoffering']
- return disk_offering
-
- def get_result(self, disk_offering):
- super(AnsibleCloudStackDiskOffering, self).get_result(disk_offering)
- if disk_offering:
- # Prevent confusion, the api returns a tags key for storage tags.
- if 'tags' in disk_offering:
- self.result['storage_tags'] = disk_offering['tags'].split(',') or [disk_offering['tags']]
- if 'tags' in self.result:
- del self.result['tags']
-
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- domain=dict(),
- disk_size=dict(type='int'),
- display_offering=dict(type='bool'),
- hypervisor_snapshot_reserve=dict(type='int'),
- bytes_read_rate=dict(type='int'),
- bytes_write_rate=dict(type='int'),
- customized=dict(type='bool'),
- iops_read_rate=dict(type='int'),
- iops_write_rate=dict(type='int'),
- iops_max=dict(type='int'),
- iops_min=dict(type='int'),
- provisioning_type=dict(choices=['thin', 'sparse', 'fat']),
- storage_type=dict(choices=['local', 'shared']),
- storage_tags=dict(type='list', aliases=['storage_tag']),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_do = AnsibleCloudStackDiskOffering(module)
-
- state = module.params.get('state')
- if state == "absent":
- disk_offering = acs_do.absent_disk_offering()
- else:
- disk_offering = acs_do.present_disk_offering()
-
- result = acs_do.get_result(disk_offering)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_domain.py b/lib/ansible/modules/cloud/cloudstack/cs_domain.py
deleted file mode 100644
index 125fb5ee81..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_domain.py
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_domain
-short_description: Manages domains on Apache CloudStack based clouds.
-description:
- - Create, update and remove domains.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- path:
- description:
- - Path of the domain.
- - Prefix C(ROOT/) or C(/ROOT/) in path is optional.
- type: str
- required: true
- network_domain:
- description:
- - Network domain for networks in the domain.
- type: str
- clean_up:
- description:
- - Clean up all domain resources like child domains and accounts.
- - Considered on I(state=absent).
- type: bool
- default: no
- state:
- description:
- - State of the domain.
- type: str
- choices: [ present, absent ]
- default: present
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a domain
- cs_domain:
- path: ROOT/customers
- network_domain: customers.example.com
- delegate_to: localhost
-
-- name: Create another subdomain
- cs_domain:
- path: ROOT/customers/xy
- network_domain: xy.customers.example.com
- delegate_to: localhost
-
-- name: Remove a domain
- cs_domain:
- path: ROOT/customers/xy
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the domain.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-name:
- description: Name of the domain.
- returned: success
- type: str
- sample: customers
-path:
- description: Domain path.
- returned: success
- type: str
- sample: /ROOT/customers
-parent_domain:
- description: Parent domain of the domain.
- returned: success
- type: str
- sample: ROOT
-network_domain:
- description: Network domain of the domain.
- returned: success
- type: str
- sample: example.local
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackDomain(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackDomain, self).__init__(module)
- self.returns = {
- 'path': 'path',
- 'networkdomain': 'network_domain',
- 'parentdomainname': 'parent_domain',
- }
- self.domain = None
-
- def _get_domain_internal(self, path=None):
- if not path:
- path = self.module.params.get('path')
-
- if path.endswith('/'):
- self.module.fail_json(msg="Path '%s' must not end with /" % path)
-
- path = path.lower()
-
- if path.startswith('/') and not path.startswith('/root/'):
- path = "root" + path
- elif not path.startswith('root/'):
- path = "root/" + path
-
- args = {
- 'listall': True,
- 'fetch_list': True,
- }
-
- domains = self.query_api('listDomains', **args)
- if domains:
- for d in domains:
- if path == d['path'].lower():
- return d
- return None
-
- def get_name(self):
- # last part of the path is the name
- name = self.module.params.get('path').split('/')[-1:]
- return name
-
- def get_domain(self, key=None):
- if not self.domain:
- self.domain = self._get_domain_internal()
- return self._get_by_key(key, self.domain)
-
- def get_parent_domain(self, key=None):
- path = self.module.params.get('path')
- # cut off last /*
- path = '/'.join(path.split('/')[:-1])
- if not path:
- return None
- parent_domain = self._get_domain_internal(path=path)
- if not parent_domain:
- self.module.fail_json(msg="Parent domain path %s does not exist" % path)
- return self._get_by_key(key, parent_domain)
-
- def present_domain(self):
- domain = self.get_domain()
- if not domain:
- domain = self.create_domain(domain)
- else:
- domain = self.update_domain(domain)
- return domain
-
- def create_domain(self, domain):
- self.result['changed'] = True
-
- args = {
- 'name': self.get_name(),
- 'parentdomainid': self.get_parent_domain(key='id'),
- 'networkdomain': self.module.params.get('network_domain')
- }
- if not self.module.check_mode:
- res = self.query_api('createDomain', **args)
- domain = res['domain']
- return domain
-
- def update_domain(self, domain):
- args = {
- 'id': domain['id'],
- 'networkdomain': self.module.params.get('network_domain')
- }
- if self.has_changed(args, domain):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateDomain', **args)
- domain = res['domain']
- return domain
-
- def absent_domain(self):
- domain = self.get_domain()
- if domain:
- self.result['changed'] = True
-
- if not self.module.check_mode:
- args = {
- 'id': domain['id'],
- 'cleanup': self.module.params.get('clean_up')
- }
- res = self.query_api('deleteDomain', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- res = self.poll_job(res, 'domain')
- return domain
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- path=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- network_domain=dict(),
- clean_up=dict(type='bool', default=False),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_dom = AnsibleCloudStackDomain(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- domain = acs_dom.absent_domain()
- else:
- domain = acs_dom.present_domain()
-
- result = acs_dom.get_result(domain)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_facts.py b/lib/ansible/modules/cloud/cloudstack/cs_facts.py
deleted file mode 100644
index 12d4397d3e..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_facts.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_facts
-short_description: Gather facts on instances of Apache CloudStack based clouds.
-description:
- - This module fetches data from the metadata API in CloudStack. The module must be called from within the instance itself.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- filter:
- description:
- - Filter for a specific fact.
- type: str
- choices:
- - cloudstack_service_offering
- - cloudstack_availability_zone
- - cloudstack_public_hostname
- - cloudstack_public_ipv4
- - cloudstack_local_hostname
- - cloudstack_local_ipv4
- - cloudstack_instance_id
- - cloudstack_user_data
- meta_data_host:
- description:
- - Host or IP of the meta data API service.
- - If not set, determination by parsing the dhcp lease file.
- type: str
- version_added: '2.4'
-requirements: [ yaml ]
-'''
-
-EXAMPLES = '''
-# Gather all facts on instances
-- name: Gather cloudstack facts
- cs_facts:
-
-# Gather specific fact on instances
-- name: Gather cloudstack facts
- cs_facts: filter=cloudstack_instance_id
-
-# Gather specific fact on instances with a given meta_data_host
-- name: Gather cloudstack facts
- cs_facts:
- filter: cloudstack_instance_id
- meta_data_host: 169.254.169.254
-'''
-
-RETURN = '''
----
-cloudstack_availability_zone:
- description: zone the instance is deployed in.
- returned: success
- type: str
- sample: ch-gva-2
-cloudstack_instance_id:
- description: UUID of the instance.
- returned: success
- type: str
- sample: ab4e80b0-3e7e-4936-bdc5-e334ba5b0139
-cloudstack_local_hostname:
- description: local hostname of the instance.
- returned: success
- type: str
- sample: VM-ab4e80b0-3e7e-4936-bdc5-e334ba5b0139
-cloudstack_local_ipv4:
- description: local IPv4 of the instance.
- returned: success
- type: str
- sample: 185.19.28.35
-cloudstack_public_hostname:
- description: public IPv4 of the router. Same as I(cloudstack_public_ipv4).
- returned: success
- type: str
- sample: VM-ab4e80b0-3e7e-4936-bdc5-e334ba5b0139
-cloudstack_public_ipv4:
- description: public IPv4 of the router.
- returned: success
- type: str
- sample: 185.19.28.35
-cloudstack_service_offering:
- description: service offering of the instance.
- returned: success
- type: str
- sample: Micro 512mb 1cpu
-cloudstack_user_data:
- description: data of the instance provided by users.
- returned: success
- type: dict
- sample: { "bla": "foo" }
-'''
-
-import os
-import traceback
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-from ansible.module_utils.urls import fetch_url
-from ansible.module_utils.facts import ansible_collector, default_collectors
-
-YAML_IMP_ERR = None
-try:
- import yaml
- HAS_LIB_YAML = True
-except ImportError:
- YAML_IMP_ERR = traceback.format_exc()
- HAS_LIB_YAML = False
-
-CS_METADATA_BASE_URL = "http://%s/latest/meta-data"
-CS_USERDATA_BASE_URL = "http://%s/latest/user-data"
-
-
-class CloudStackFacts(object):
-
- def __init__(self):
- collector = ansible_collector.get_ansible_collector(all_collector_classes=default_collectors.collectors,
- filter_spec='default_ipv4',
- gather_subset=['!all', 'network'],
- gather_timeout=10)
- self.facts = collector.collect(module)
-
- self.api_ip = None
- self.fact_paths = {
- 'cloudstack_service_offering': 'service-offering',
- 'cloudstack_availability_zone': 'availability-zone',
- 'cloudstack_public_hostname': 'public-hostname',
- 'cloudstack_public_ipv4': 'public-ipv4',
- 'cloudstack_local_hostname': 'local-hostname',
- 'cloudstack_local_ipv4': 'local-ipv4',
- 'cloudstack_instance_id': 'instance-id'
- }
-
- def run(self):
- result = {}
- filter = module.params.get('filter')
- if not filter:
- for key, path in self.fact_paths.items():
- result[key] = self._fetch(CS_METADATA_BASE_URL + "/" + path)
- result['cloudstack_user_data'] = self._get_user_data_json()
- else:
- if filter == 'cloudstack_user_data':
- result['cloudstack_user_data'] = self._get_user_data_json()
- elif filter in self.fact_paths:
- result[filter] = self._fetch(CS_METADATA_BASE_URL + "/" + self.fact_paths[filter])
- return result
-
- def _get_user_data_json(self):
- try:
- # this data come form users, we try what we can to parse it...
- return yaml.safe_load(self._fetch(CS_USERDATA_BASE_URL))
- except Exception:
- return None
-
- def _fetch(self, path):
- api_ip = self._get_api_ip()
- if not api_ip:
- return None
- api_url = path % api_ip
- (response, info) = fetch_url(module, api_url, force=True)
- if response:
- data = response.read()
- else:
- data = None
- return data
-
- def _get_dhcp_lease_file(self):
- """Return the path of the lease file."""
- default_iface = self.facts['default_ipv4']['interface']
- dhcp_lease_file_locations = [
- '/var/lib/dhcp/dhclient.%s.leases' % default_iface, # debian / ubuntu
- '/var/lib/dhclient/dhclient-%s.leases' % default_iface, # centos 6
- '/var/lib/dhclient/dhclient--%s.lease' % default_iface, # centos 7
- '/var/db/dhclient.leases.%s' % default_iface, # openbsd
- ]
- for file_path in dhcp_lease_file_locations:
- if os.path.exists(file_path):
- return file_path
- module.fail_json(msg="Could not find dhclient leases file.")
-
- def _get_api_ip(self):
- """Return the IP of the DHCP server."""
- if module.params.get('meta_data_host'):
- return module.params.get('meta_data_host')
- elif not self.api_ip:
- dhcp_lease_file = self._get_dhcp_lease_file()
- for line in open(dhcp_lease_file):
- if 'dhcp-server-identifier' in line:
- # get IP of string "option dhcp-server-identifier 185.19.28.176;"
- line = line.translate(None, ';')
- self.api_ip = line.split()[2]
- break
- if not self.api_ip:
- module.fail_json(msg="No dhcp-server-identifier found in leases file.")
- return self.api_ip
-
-
-def main():
- global module
- module = AnsibleModule(
- argument_spec=dict(
- filter=dict(default=None, choices=[
- 'cloudstack_service_offering',
- 'cloudstack_availability_zone',
- 'cloudstack_public_hostname',
- 'cloudstack_public_ipv4',
- 'cloudstack_local_hostname',
- 'cloudstack_local_ipv4',
- 'cloudstack_instance_id',
- 'cloudstack_user_data',
- ]),
- meta_data_host=dict(),
- ),
- supports_check_mode=True
- )
-
- if not HAS_LIB_YAML:
- module.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR)
-
- cs_facts = CloudStackFacts().run()
- cs_facts_result = dict(changed=False, ansible_facts=cs_facts)
- module.exit_json(**cs_facts_result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_firewall.py b/lib/ansible/modules/cloud/cloudstack/cs_firewall.py
deleted file mode 100644
index 08a26b8e4d..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_firewall.py
+++ /dev/null
@@ -1,448 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright: (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_firewall
-short_description: Manages firewall rules on Apache CloudStack based clouds.
-description:
- - Creates and removes firewall rules.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- ip_address:
- description:
- - Public IP address the ingress rule is assigned to.
- - Required if I(type=ingress).
- type: str
- network:
- description:
- - Network the egress rule is related to.
- - Required if I(type=egress).
- type: str
- state:
- description:
- - State of the firewall rule.
- type: str
- default: present
- choices: [ present, absent ]
- type:
- description:
- - Type of the firewall rule.
- type: str
- default: ingress
- choices: [ ingress, egress ]
- protocol:
- description:
- - Protocol of the firewall rule.
- - C(all) is only available if I(type=egress).
- type: str
- default: tcp
- choices: [ tcp, udp, icmp, all ]
- cidrs:
- description:
- - List of CIDRs (full notation) to be used for firewall rule.
- - Since version 2.5, it is a list of CIDR.
- type: list
- default: 0.0.0.0/0
- aliases: [ cidr ]
- start_port:
- description:
- - Start port for this rule.
- - Considered if I(protocol=tcp) or I(protocol=udp).
- type: int
- aliases: [ port ]
- end_port:
- description:
- - End port for this rule. Considered if I(protocol=tcp) or I(protocol=udp).
- - If not specified, equal I(start_port).
- type: int
- icmp_type:
- description:
- - Type of the icmp message being sent.
- - Considered if I(protocol=icmp).
- type: int
- icmp_code:
- description:
- - Error code for this icmp message.
- - Considered if I(protocol=icmp).
- type: int
- domain:
- description:
- - Domain the firewall rule is related to.
- type: str
- account:
- description:
- - Account the firewall rule is related to.
- type: str
- project:
- description:
- - Name of the project the firewall rule is related to.
- type: str
- zone:
- description:
- - Name of the zone in which the virtual machine is in.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set an empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Allow inbound port 80/tcp from 1.2.3.4 to 4.3.2.1
- cs_firewall:
- ip_address: 4.3.2.1
- port: 80
- cidr: 1.2.3.4/32
- delegate_to: localhost
-
-- name: Allow inbound tcp/udp port 53 to 4.3.2.1
- cs_firewall:
- ip_address: 4.3.2.1
- port: 53
- protocol: '{{ item }}'
- with_items:
- - tcp
- - udp
- delegate_to: localhost
-
-- name: Ensure firewall rule is removed
- cs_firewall:
- ip_address: 4.3.2.1
- start_port: 8000
- end_port: 8888
- cidr: 17.0.0.0/8
- state: absent
- delegate_to: localhost
-
-- name: Allow all outbound traffic
- cs_firewall:
- network: my_network
- type: egress
- protocol: all
- delegate_to: localhost
-
-- name: Allow only HTTP outbound traffic for an IP
- cs_firewall:
- network: my_network
- type: egress
- port: 80
- cidr: 10.101.1.20
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the rule.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-ip_address:
- description: IP address of the rule if C(type=ingress)
- returned: success
- type: str
- sample: 10.100.212.10
-type:
- description: Type of the rule.
- returned: success
- type: str
- sample: ingress
-cidr:
- description: CIDR string of the rule.
- returned: success
- type: str
- sample: 0.0.0.0/0
-cidrs:
- description: CIDR list of the rule.
- returned: success
- type: list
- sample: [ '0.0.0.0/0' ]
- version_added: '2.5'
-protocol:
- description: Protocol of the rule.
- returned: success
- type: str
- sample: tcp
-start_port:
- description: Start port of the rule.
- returned: success
- type: int
- sample: 80
-end_port:
- description: End port of the rule.
- returned: success
- type: int
- sample: 80
-icmp_code:
- description: ICMP code of the rule.
- returned: success
- type: int
- sample: 1
-icmp_type:
- description: ICMP type of the rule.
- returned: success
- type: int
- sample: 1
-network:
- description: Name of the network if C(type=egress)
- returned: success
- type: str
- sample: my_network
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackFirewall(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackFirewall, self).__init__(module)
- self.returns = {
- 'cidrlist': 'cidr',
- 'startport': 'start_port',
- 'endport': 'end_port',
- 'protocol': 'protocol',
- 'ipaddress': 'ip_address',
- 'icmpcode': 'icmp_code',
- 'icmptype': 'icmp_type',
- }
- self.firewall_rule = None
- self.network = None
-
- def get_firewall_rule(self):
- if not self.firewall_rule:
- cidrs = self.module.params.get('cidrs')
- protocol = self.module.params.get('protocol')
- start_port = self.module.params.get('start_port')
- end_port = self.get_or_fallback('end_port', 'start_port')
- icmp_code = self.module.params.get('icmp_code')
- icmp_type = self.module.params.get('icmp_type')
- fw_type = self.module.params.get('type')
-
- if protocol in ['tcp', 'udp'] and not (start_port and end_port):
- self.module.fail_json(msg="missing required argument for protocol '%s': start_port or end_port" % protocol)
-
- if protocol == 'icmp' and not icmp_type:
- self.module.fail_json(msg="missing required argument for protocol 'icmp': icmp_type")
-
- if protocol == 'all' and fw_type != 'egress':
- self.module.fail_json(msg="protocol 'all' could only be used for type 'egress'")
-
- args = {
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id'),
- 'projectid': self.get_project('id'),
- 'fetch_list': True,
- }
- if fw_type == 'egress':
- args['networkid'] = self.get_network(key='id')
- if not args['networkid']:
- self.module.fail_json(msg="missing required argument for type egress: network")
-
- # CloudStack 4.11 use the network cidr for 0.0.0.0/0 in egress
- # That is why we need to replace it.
- network_cidr = self.get_network(key='cidr')
- egress_cidrs = [network_cidr if cidr == '0.0.0.0/0' else cidr for cidr in cidrs]
-
- firewall_rules = self.query_api('listEgressFirewallRules', **args)
- else:
- args['ipaddressid'] = self.get_ip_address('id')
- if not args['ipaddressid']:
- self.module.fail_json(msg="missing required argument for type ingress: ip_address")
- egress_cidrs = None
-
- firewall_rules = self.query_api('listFirewallRules', **args)
-
- if firewall_rules:
- for rule in firewall_rules:
- type_match = self._type_cidrs_match(rule, cidrs, egress_cidrs)
-
- protocol_match = (
- self._tcp_udp_match(rule, protocol, start_port, end_port) or
- self._icmp_match(rule, protocol, icmp_code, icmp_type) or
- self._egress_all_match(rule, protocol, fw_type)
- )
-
- if type_match and protocol_match:
- self.firewall_rule = rule
- break
- return self.firewall_rule
-
- def _tcp_udp_match(self, rule, protocol, start_port, end_port):
- return (
- protocol in ['tcp', 'udp'] and
- protocol == rule['protocol'] and
- start_port == int(rule['startport']) and
- end_port == int(rule['endport'])
- )
-
- def _egress_all_match(self, rule, protocol, fw_type):
- return (
- protocol in ['all'] and
- protocol == rule['protocol'] and
- fw_type == 'egress'
- )
-
- def _icmp_match(self, rule, protocol, icmp_code, icmp_type):
- return (
- protocol == 'icmp' and
- protocol == rule['protocol'] and
- icmp_code == rule['icmpcode'] and
- icmp_type == rule['icmptype']
- )
-
- def _type_cidrs_match(self, rule, cidrs, egress_cidrs):
- if egress_cidrs is not None:
- return ",".join(egress_cidrs) == rule['cidrlist'] or ",".join(cidrs) == rule['cidrlist']
- else:
- return ",".join(cidrs) == rule['cidrlist']
-
- def create_firewall_rule(self):
- firewall_rule = self.get_firewall_rule()
- if not firewall_rule:
- self.result['changed'] = True
-
- args = {
- 'cidrlist': self.module.params.get('cidrs'),
- 'protocol': self.module.params.get('protocol'),
- 'startport': self.module.params.get('start_port'),
- 'endport': self.get_or_fallback('end_port', 'start_port'),
- 'icmptype': self.module.params.get('icmp_type'),
- 'icmpcode': self.module.params.get('icmp_code')
- }
-
- fw_type = self.module.params.get('type')
- if not self.module.check_mode:
- if fw_type == 'egress':
- args['networkid'] = self.get_network(key='id')
- res = self.query_api('createEgressFirewallRule', **args)
- else:
- args['ipaddressid'] = self.get_ip_address('id')
- res = self.query_api('createFirewallRule', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- firewall_rule = self.poll_job(res, 'firewallrule')
-
- if firewall_rule:
- firewall_rule = self.ensure_tags(resource=firewall_rule, resource_type='Firewallrule')
- self.firewall_rule = firewall_rule
-
- return firewall_rule
-
- def remove_firewall_rule(self):
- firewall_rule = self.get_firewall_rule()
- if firewall_rule:
- self.result['changed'] = True
-
- args = {
- 'id': firewall_rule['id']
- }
-
- fw_type = self.module.params.get('type')
- if not self.module.check_mode:
- if fw_type == 'egress':
- res = self.query_api('deleteEgressFirewallRule', **args)
- else:
- res = self.query_api('deleteFirewallRule', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'firewallrule')
- return firewall_rule
-
- def get_result(self, firewall_rule):
- super(AnsibleCloudStackFirewall, self).get_result(firewall_rule)
- if firewall_rule:
- self.result['type'] = self.module.params.get('type')
- if self.result['type'] == 'egress':
- self.result['network'] = self.get_network(key='displaytext')
- if 'cidrlist' in firewall_rule:
- self.result['cidrs'] = firewall_rule['cidrlist'].split(',') or [firewall_rule['cidrlist']]
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- ip_address=dict(),
- network=dict(),
- cidrs=dict(type='list', default='0.0.0.0/0', aliases=['cidr']),
- protocol=dict(choices=['tcp', 'udp', 'icmp', 'all'], default='tcp'),
- type=dict(choices=['ingress', 'egress'], default='ingress'),
- icmp_type=dict(type='int'),
- icmp_code=dict(type='int'),
- start_port=dict(type='int', aliases=['port']),
- end_port=dict(type='int'),
- state=dict(choices=['present', 'absent'], default='present'),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag'], default=None),
- ))
-
- required_together = cs_required_together()
- required_together.extend([
- ['icmp_type', 'icmp_code'],
- ])
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=required_together,
- required_one_of=(
- ['ip_address', 'network'],
- ),
- mutually_exclusive=(
- ['icmp_type', 'start_port'],
- ['icmp_type', 'end_port'],
- ['ip_address', 'network'],
- ),
- supports_check_mode=True
- )
-
- acs_fw = AnsibleCloudStackFirewall(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- fw_rule = acs_fw.remove_firewall_rule()
- else:
- fw_rule = acs_fw.create_firewall_rule()
-
- result = acs_fw.get_result(fw_rule)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_host.py b/lib/ansible/modules/cloud/cloudstack/cs_host.py
deleted file mode 100644
index ca0b07d392..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_host.py
+++ /dev/null
@@ -1,626 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_host
-short_description: Manages hosts on Apache CloudStack based clouds.
-description:
- - Create, update and remove hosts.
-version_added: '2.3'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the host.
- type: str
- required: true
- aliases: [ ip_address ]
- url:
- description:
- - Url of the host used to create a host.
- - If not provided, C(http://) and param I(name) is used as url.
- - Only considered if I(state=present) and host does not yet exist.
- type: str
- username:
- description:
- - Username for the host.
- - Required if I(state=present) and host does not yet exist.
- type: str
- password:
- description:
- - Password for the host.
- - Required if I(state=present) and host does not yet exist.
- type: str
- pod:
- description:
- - Name of the pod.
- - Required if I(state=present) and host does not yet exist.
- type: str
- cluster:
- description:
- - Name of the cluster.
- type: str
- hypervisor:
- description:
- - Name of the cluster.
- - Required if I(state=present) and host does not yet exist.
- - Possible values are C(KVM), C(VMware), C(BareMetal), C(XenServer), C(LXC), C(HyperV), C(UCS), C(OVM), C(Simulator).
- type: str
- allocation_state:
- description:
- - Allocation state of the host.
- type: str
- choices: [ enabled, disabled, maintenance ]
- host_tags:
- description:
- - Tags of the host.
- type: list
- aliases: [ host_tag ]
- state:
- description:
- - State of the host.
- type: str
- default: present
- choices: [ present, absent ]
- zone:
- description:
- - Name of the zone in which the host should be deployed.
- - If not set, default zone is used.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a host is present but disabled
- cs_host:
- name: pod01.zone01.example.com
- cluster: vcenter.example.com/zone01/cluster01
- pod: pod01
- zone: zone01
- hypervisor: VMware
- allocation_state: disabled
- host_tags:
- - perf
- - gpu
- delegate_to: localhost
-
-- name: Ensure an existing host is disabled
- cs_host:
- name: pod01.zone01.example.com
- zone: zone01
- allocation_state: disabled
- delegate_to: localhost
-
-- name: Ensure an existing host is enabled
- cs_host:
- name: pod01.zone01.example.com
- zone: zone01
- allocation_state: enabled
- delegate_to: localhost
-
-- name: Ensure a host is absent
- cs_host:
- name: pod01.zone01.example.com
- zone: zone01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-capabilities:
- description: Capabilities of the host.
- returned: success
- type: str
- sample: hvm
-cluster:
- description: Cluster of the host.
- returned: success
- type: str
- sample: vcenter.example.com/zone/cluster01
-cluster_type:
- description: Type of the cluster of the host.
- returned: success
- type: str
- sample: ExternalManaged
-cpu_allocated:
- description: Amount in percent of the host's CPU currently allocated.
- returned: success
- type: str
- sample: 166.25%
-cpu_number:
- description: Number of CPUs of the host.
- returned: success
- type: str
- sample: 24
-cpu_sockets:
- description: Number of CPU sockets of the host.
- returned: success
- type: int
- sample: 2
-cpu_speed:
- description: CPU speed in Mhz
- returned: success
- type: int
- sample: 1999
-cpu_used:
- description: Amount of the host's CPU currently used.
- returned: success
- type: str
- sample: 33.6%
-cpu_with_overprovisioning:
- description: Amount of the host's CPU after applying the cpu.overprovisioning.factor.
- returned: success
- type: str
- sample: 959520.0
-created:
- description: Date when the host was created.
- returned: success
- type: str
- sample: 2015-05-03T15:05:51+0200
-disconnected:
- description: Date when the host was disconnected.
- returned: success
- type: str
- sample: 2015-05-03T15:05:51+0200
-disk_size_allocated:
- description: Host's currently allocated disk size.
- returned: success
- type: int
- sample: 2593
-disk_size_total:
- description: Total disk size of the host
- returned: success
- type: int
- sample: 259300
-events:
- description: Events available for the host
- returned: success
- type: str
- sample: "Ping; HostDown; AgentConnected; AgentDisconnected; PingTimeout; ShutdownRequested; Remove; StartAgentRebalance; ManagementServerDown"
-ha_host:
- description: Whether the host is a HA host.
- returned: success
- type: bool
- sample: false
-has_enough_capacity:
- description: Whether the host has enough CPU and RAM capacity to migrate a VM to it.
- returned: success
- type: bool
- sample: true
-host_tags:
- description: Comma-separated list of tags for the host.
- returned: success
- type: str
- sample: "perf"
-hypervisor:
- description: Host's hypervisor.
- returned: success
- type: str
- sample: VMware
-hypervisor_version:
- description: Hypervisor version.
- returned: success
- type: str
- sample: 5.1
-ip_address:
- description: IP address of the host
- returned: success
- type: str
- sample: 10.10.10.1
-is_local_storage_active:
- description: Whether the local storage is available or not.
- returned: success
- type: bool
- sample: false
-last_pinged:
- description: Date and time the host was last pinged.
- returned: success
- type: str
- sample: "1970-01-17T17:27:32+0100"
-management_server_id:
- description: Management server ID of the host.
- returned: success
- type: int
- sample: 345050593418
-memory_allocated:
- description: Amount of the host's memory currently allocated.
- returned: success
- type: int
- sample: 69793218560
-memory_total:
- description: Total of memory of the host.
- returned: success
- type: int
- sample: 206085263360
-memory_used:
- description: Amount of the host's memory currently used.
- returned: success
- type: int
- sample: 65504776192
-name:
- description: Name of the host.
- returned: success
- type: str
- sample: esx32.example.com
-network_kbs_read:
- description: Incoming network traffic on the host.
- returned: success
- type: int
- sample: 0
-network_kbs_write:
- description: Outgoing network traffic on the host.
- returned: success
- type: int
- sample: 0
-os_category:
- description: OS category name of the host.
- returned: success
- type: str
- sample: ...
-out_of_band_management:
- description: Host out-of-band management information.
- returned: success
- type: str
- sample: ...
-pod:
- description: Pod name of the host.
- returned: success
- type: str
- sample: Pod01
-removed:
- description: Date and time the host was removed.
- returned: success
- type: str
- sample: "1970-01-17T17:27:32+0100"
-resource_state:
- description: Resource state of the host.
- returned: success
- type: str
- sample: Enabled
-allocation_state::
- description: Allocation state of the host.
- returned: success
- type: str
- sample: enabled
-state:
- description: State of the host.
- returned: success
- type: str
- sample: Up
-suitable_for_migration:
- description: Whether this host is suitable (has enough capacity and satisfies all conditions like hosttags, max guests VM limit, etc) to migrate a VM
- to it or not.
- returned: success
- type: str
- sample: true
-host_type:
- description: Type of the host.
- returned: success
- type: str
- sample: Routing
-host_version:
- description: Version of the host.
- returned: success
- type: str
- sample: 4.5.2
-gpu_group:
- description: GPU cards present in the host.
- returned: success
- type: list
- sample: []
-zone:
- description: Zone of the host.
- returned: success
- type: str
- sample: zone01
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-import time
-
-
-class AnsibleCloudStackHost(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackHost, self).__init__(module)
- self.returns = {
- 'averageload': 'average_load',
- 'capabilities': 'capabilities',
- 'clustername': 'cluster',
- 'clustertype': 'cluster_type',
- 'cpuallocated': 'cpu_allocated',
- 'cpunumber': 'cpu_number',
- 'cpusockets': 'cpu_sockets',
- 'cpuspeed': 'cpu_speed',
- 'cpuused': 'cpu_used',
- 'cpuwithoverprovisioning': 'cpu_with_overprovisioning',
- 'disconnected': 'disconnected',
- 'details': 'details',
- 'disksizeallocated': 'disk_size_allocated',
- 'disksizetotal': 'disk_size_total',
- 'events': 'events',
- 'hahost': 'ha_host',
- 'hasenoughcapacity': 'has_enough_capacity',
- 'hypervisor': 'hypervisor',
- 'hypervisorversion': 'hypervisor_version',
- 'ipaddress': 'ip_address',
- 'islocalstorageactive': 'is_local_storage_active',
- 'lastpinged': 'last_pinged',
- 'managementserverid': 'management_server_id',
- 'memoryallocated': 'memory_allocated',
- 'memorytotal': 'memory_total',
- 'memoryused': 'memory_used',
- 'networkkbsread': 'network_kbs_read',
- 'networkkbswrite': 'network_kbs_write',
- 'oscategoryname': 'os_category',
- 'outofbandmanagement': 'out_of_band_management',
- 'podname': 'pod',
- 'removed': 'removed',
- 'resourcestate': 'resource_state',
- 'suitableformigration': 'suitable_for_migration',
- 'type': 'host_type',
- 'version': 'host_version',
- 'gpugroup': 'gpu_group',
- }
- # States only usable by the updateHost API
- self.allocation_states_for_update = {
- 'enabled': 'Enable',
- 'disabled': 'Disable',
- }
- self.host = None
-
- def get_pod(self, key=None):
- pod_name = self.module.params.get('pod')
- if not pod_name:
- return None
- args = {
- 'name': pod_name,
- 'zoneid': self.get_zone(key='id'),
- }
- pods = self.query_api('listPods', **args)
- if pods:
- return self._get_by_key(key, pods['pod'][0])
- self.module.fail_json(msg="Pod %s not found" % pod_name)
-
- def get_cluster(self, key=None):
- cluster_name = self.module.params.get('cluster')
- if not cluster_name:
- return None
- args = {
- 'name': cluster_name,
- 'zoneid': self.get_zone(key='id'),
- }
- clusters = self.query_api('listClusters', **args)
- if clusters:
- return self._get_by_key(key, clusters['cluster'][0])
- self.module.fail_json(msg="Cluster %s not found" % cluster_name)
-
- def get_host_tags(self):
- host_tags = self.module.params.get('host_tags')
- if host_tags is None:
- return None
- return ','.join(host_tags)
-
- def get_host(self, refresh=False):
- if self.host is not None and not refresh:
- return self.host
-
- name = self.module.params.get('name')
- args = {
- 'zoneid': self.get_zone(key='id'),
- 'fetch_list': True,
- }
- res = self.query_api('listHosts', **args)
- if res:
- for h in res:
- if name in [h['ipaddress'], h['name']]:
- self.host = h
- return self.host
-
- def _handle_allocation_state(self, host):
- allocation_state = self.module.params.get('allocation_state')
- if not allocation_state:
- return host
-
- host = self._set_host_allocation_state(host)
-
- # In case host in maintenance and target is maintenance
- if host['allocationstate'].lower() == allocation_state and allocation_state == 'maintenance':
- return host
-
- # Cancel maintenance if target state is enabled/disabled
- elif allocation_state in list(self.allocation_states_for_update.keys()):
- host = self.disable_maintenance(host)
- host = self._update_host(host, self.allocation_states_for_update[allocation_state])
-
- # Only an enabled host can put in maintenance
- elif allocation_state == 'maintenance':
- host = self._update_host(host, 'Enable')
- host = self.enable_maintenance(host)
-
- return host
-
- def _set_host_allocation_state(self, host):
- if host is None:
- host['allocationstate'] = 'Enable'
-
- # Set host allocationstate to be disabled/enabled
- elif host['resourcestate'].lower() in list(self.allocation_states_for_update.keys()):
- host['allocationstate'] = self.allocation_states_for_update[host['resourcestate'].lower()]
-
- else:
- host['allocationstate'] = host['resourcestate']
-
- return host
-
- def present_host(self):
- host = self.get_host()
-
- if not host:
- host = self._create_host(host)
- else:
- host = self._update_host(host)
-
- if host:
- host = self._handle_allocation_state(host)
-
- return host
-
- def _get_url(self):
- url = self.module.params.get('url')
- if url:
- return url
- else:
- return "http://%s" % self.module.params.get('name')
-
- def _create_host(self, host):
- required_params = [
- 'password',
- 'username',
- 'hypervisor',
- 'pod',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
- self.result['changed'] = True
- args = {
- 'hypervisor': self.module.params.get('hypervisor'),
- 'url': self._get_url(),
- 'username': self.module.params.get('username'),
- 'password': self.module.params.get('password'),
- 'podid': self.get_pod(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'clusterid': self.get_cluster(key='id'),
- 'hosttags': self.get_host_tags(),
- }
- if not self.module.check_mode:
- host = self.query_api('addHost', **args)
- host = host['host'][0]
- return host
-
- def _update_host(self, host, allocation_state=None):
- args = {
- 'id': host['id'],
- 'hosttags': self.get_host_tags(),
- 'allocationstate': allocation_state,
- }
-
- if allocation_state is not None:
- host = self._set_host_allocation_state(host)
-
- if self.has_changed(args, host):
- self.result['changed'] = True
- if not self.module.check_mode:
- host = self.query_api('updateHost', **args)
- host = host['host']
-
- return host
-
- def absent_host(self):
- host = self.get_host()
- if host:
- self.result['changed'] = True
- args = {
- 'id': host['id'],
- }
- if not self.module.check_mode:
- res = self.enable_maintenance(host)
- if res:
- res = self.query_api('deleteHost', **args)
- return host
-
- def enable_maintenance(self, host):
- if host['resourcestate'] not in ['PrepareForMaintenance', 'Maintenance']:
- self.result['changed'] = True
- args = {
- 'id': host['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('prepareHostForMaintenance', **args)
- self.poll_job(res, 'host')
- host = self._poll_for_maintenance()
- return host
-
- def disable_maintenance(self, host):
- if host['resourcestate'] in ['PrepareForMaintenance', 'Maintenance']:
- self.result['changed'] = True
- args = {
- 'id': host['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('cancelHostMaintenance', **args)
- host = self.poll_job(res, 'host')
- return host
-
- def _poll_for_maintenance(self):
- for i in range(0, 300):
- time.sleep(2)
- host = self.get_host(refresh=True)
- if not host:
- return None
- elif host['resourcestate'] != 'PrepareForMaintenance':
- return host
- self.fail_json(msg="Polling for maintenance timed out")
-
- def get_result(self, host):
- super(AnsibleCloudStackHost, self).get_result(host)
- if host:
- self.result['allocation_state'] = host['resourcestate'].lower()
- self.result['host_tags'] = host['hosttags'].split(',') if host.get('hosttags') else []
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True, aliases=['ip_address']),
- url=dict(),
- password=dict(no_log=True),
- username=dict(),
- hypervisor=dict(),
- allocation_state=dict(choices=['enabled', 'disabled', 'maintenance']),
- pod=dict(),
- cluster=dict(),
- host_tags=dict(type='list', aliases=['host_tag']),
- zone=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_host = AnsibleCloudStackHost(module)
-
- state = module.params.get('state')
- if state == 'absent':
- host = acs_host.absent_host()
- else:
- host = acs_host.present_host()
-
- result = acs_host.get_result(host)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_image_store.py b/lib/ansible/modules/cloud/cloudstack/cs_image_store.py
deleted file mode 100644
index f54bba2e1b..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_image_store.py
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/python
-
-# Copyright: (c) 2019, Patryk Cichy @PatTheSilent
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {
- 'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'
-}
-
-DOCUMENTATION = '''
----
-module: cs_image_store
-
-short_description: Manages CloudStack Image Stores.
-
-version_added: "2.8"
-
-description:
- - Deploy, remove, recreate CloudStack Image Stores.
-
-options:
- url:
- description:
- - The URL for the Image Store.
- - Required when I(state=present).
- type: str
- name:
- description:
- - The ID of the Image Store. Required when deleting a Image Store.
- required: true
- type: str
- zone:
- description:
- - The Zone name for the Image Store.
- required: true
- type: str
- state:
- description:
- - Stage of the Image Store
- choices: [present, absent]
- default: present
- type: str
- provider:
- description:
- - The image store provider name. Required when creating a new Image Store
- type: str
- force_recreate:
- description:
- - Set to C(yes) if you're changing an existing Image Store.
- - This will force the recreation of the Image Store.
- - Recreation might fail if there are snapshots present on the Image Store. Delete them before running the recreation.
- type: bool
- default: no
-
-extends_documentation_fragment: cloudstack
-
-author:
- - Patryk Cichy (@PatTheSilent)
-'''
-
-EXAMPLES = '''
-- name: Add a Image Store (NFS)
- cs_image_store:
- zone: zone-01
- name: nfs-01
- provider: NFS
- url: nfs://192.168.21.16/exports/secondary
- delegate_to: localhost
-
-# Change the NFS share URL and force a Image Store recreation
-- name: Change the NFS url
- cs_image_store:
- zone: zone-01
- name: nfs-01
- provider: NFS
- force_recreate: yes
- url: nfs://192.168.21.10/shares/secondary
- delegate_to: localhost
-
-- name: delete the image store
- cs_image_store:
- name: nfs-01
- zone: zone-01
- state: absent
- delegate_to: localhost
-
-'''
-
-RETURN = '''
-id:
- description: the ID of the image store
- type: str
- returned: success
- sample: feb11a84-a093-45eb-b84d-7f680313c40b
-name:
- description: the name of the image store
- type: str
- returned: success
- sample: nfs-01
-protocol:
- description: the protocol of the image store
- type: str
- returned: success
- sample: nfs
-provider_name:
- description: the provider name of the image store
- type: str
- returned: success
- sample: NFS
-scope:
- description: the scope of the image store
- type: str
- returned: success
- sample: ZONE
-url:
- description: the url of the image store
- type: str
- sample: nfs://192.168.21.16/exports/secondary
- returned: success
-zone:
- description: the Zone name of the image store
- type: str
- returned: success
- sample: zone-01
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec, cs_required_together
-
-
-class AnsibleCloudstackImageStore(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudstackImageStore, self).__init__(module)
- self.returns = {
- 'protocol': 'protocol',
- 'providername': 'provider_name',
- 'scope': 'scope',
- 'url': 'url'
- }
- self.image_store = None
-
- def get_storage_providers(self, storage_type="image"):
- args = {
- 'type': storage_type
- }
- storage_provides = self.query_api('listStorageProviders', **args)
- return [provider.get('name') for provider in storage_provides.get('dataStoreProvider')]
-
- def get_image_store(self):
- if self.image_store:
- return self.image_store
- image_store = self.module.params.get('name')
- args = {
- 'name': self.module.params.get('name'),
- 'zoneid': self.get_zone(key='id')
- }
-
- image_stores = self.query_api('listImageStores', **args)
- if image_stores:
- for img_s in image_stores.get('imagestore'):
- if image_store.lower() in [img_s['name'].lower(), img_s['id']]:
- self.image_store = img_s
- break
-
- return self.image_store
-
- def present_image_store(self):
- provider_list = self.get_storage_providers()
- image_store = self.get_image_store()
-
- if self.module.params.get('provider') not in provider_list:
- self.module.fail_json(
- msg='Provider %s is not in the provider list (%s). Please specify a correct provider' % (
- self.module.params.get('provider'), provider_list))
- args = {
- 'name': self.module.params.get('name'),
- 'url': self.module.params.get('url'),
- 'zoneid': self.get_zone(key='id'),
- 'provider': self.module.params.get('provider')
- }
- if not image_store:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('addImageStore', **args)
- self.image_store = res.get('imagestore')
- else:
- # Cloudstack API expects 'provider' but returns 'providername'
- args['providername'] = args.pop('provider')
- if self.has_changed(args, image_store):
- if self.module.params.get('force_recreate'):
- self.absent_image_store()
- self.image_store = None
- self.image_store = self.present_image_store()
- else:
- self.module.warn("Changes to the Image Store won't be applied"
- "Use force_recreate=yes to allow the store to be recreated")
-
- return self.image_store
-
- def absent_image_store(self):
- image_store = self.get_image_store()
- if image_store:
- self.result['changed'] = True
- if not self.module.check_mode:
- args = {
- 'id': image_store.get('id')
- }
- self.query_api('deleteImageStore', **args)
- return image_store
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- url=dict(),
- name=dict(required=True),
- zone=dict(required=True),
- provider=dict(),
- force_recreate=dict(type='bool', default=False),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- required_if=[
- ('state', 'present', ['url', 'provider']),
- ],
- supports_check_mode=True
- )
-
- acis_do = AnsibleCloudstackImageStore(module)
-
- state = module.params.get('state')
- if state == "absent":
- image_store = acis_do.absent_image_store()
- else:
- image_store = acis_do.present_image_store()
-
- result = acis_do.get_result(image_store)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance.py b/lib/ansible/modules/cloud/cloudstack/cs_instance.py
deleted file mode 100644
index 468549e698..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instance.py
+++ /dev/null
@@ -1,1114 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance
-short_description: Manages instances and virtual machines on Apache CloudStack based clouds.
-description:
- - Deploy, start, update, scale, restart, restore, stop and destroy instances.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Host name of the instance. C(name) can only contain ASCII letters.
- - Name will be generated (UUID) by CloudStack if not specified and can not be changed afterwards.
- - Either C(name) or C(display_name) is required.
- type: str
- display_name:
- description:
- - Custom display name of the instances.
- - Display name will be set to I(name) if not specified.
- - Either I(name) or I(display_name) is required.
- type: str
- group:
- description:
- - Group in where the new instance should be in.
- type: str
- state:
- description:
- - State of the instance.
- type: str
- default: present
- choices: [ deployed, started, stopped, restarted, restored, destroyed, expunged, present, absent ]
- service_offering:
- description:
- - Name or id of the service offering of the new instance.
- - If not set, first found service offering is used.
- type: str
- cpu:
- description:
- - The number of CPUs to allocate to the instance, used with custom service offerings
- type: int
- cpu_speed:
- description:
- - The clock speed/shares allocated to the instance, used with custom service offerings
- type: int
- memory:
- description:
- - The memory allocated to the instance, used with custom service offerings
- type: int
- template:
- description:
- - Name, display text or id of the template to be used for creating the new instance.
- - Required when using I(state=present).
- - Mutually exclusive with I(iso) option.
- type: str
- iso:
- description:
- - Name or id of the ISO to be used for creating the new instance.
- - Required when using I(state=present).
- - Mutually exclusive with I(template) option.
- type: str
- template_filter:
- description:
- - Name of the filter used to search for the template or iso.
- - Used for params I(iso) or I(template) on I(state=present).
- - The filter C(all) was added in 2.6.
- type: str
- default: executable
- choices: [ all, featured, self, selfexecutable, sharedexecutable, executable, community ]
- aliases: [ iso_filter ]
- version_added: '2.1'
- hypervisor:
- description:
- - Name the hypervisor to be used for creating the new instance.
- - Relevant when using I(state=present), but only considered if not set on ISO/template.
- - If not set or found on ISO/template, first found hypervisor will be used.
- - Possible values are C(KVM), C(VMware), C(BareMetal), C(XenServer), C(LXC), C(HyperV), C(UCS), C(OVM), C(Simulator).
- type: str
- keyboard:
- description:
- - Keyboard device type for the instance.
- type: str
- choices: [ 'de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us' ]
- networks:
- description:
- - List of networks to use for the new instance.
- type: list
- aliases: [ network ]
- ip_address:
- description:
- - IPv4 address for default instance's network during creation.
- type: str
- ip6_address:
- description:
- - IPv6 address for default instance's network.
- type: str
- ip_to_networks:
- description:
- - "List of mappings in the form I({'network': NetworkName, 'ip': 1.2.3.4})"
- - Mutually exclusive with I(networks) option.
- type: list
- aliases: [ ip_to_network ]
- disk_offering:
- description:
- - Name of the disk offering to be used.
- type: str
- disk_size:
- description:
- - Disk size in GByte required if deploying instance from ISO.
- type: int
- root_disk_size:
- description:
- - Root disk size in GByte required if deploying instance with KVM hypervisor and want resize the root disk size at startup
- (need CloudStack >= 4.4, cloud-initramfs-growroot installed and enabled in the template)
- type: int
- security_groups:
- description:
- - List of security groups the instance to be applied to.
- type: list
- aliases: [ security_group ]
- host:
- description:
- - Host on which an instance should be deployed or started on.
- - Only considered when I(state=started) or instance is running.
- - Requires root admin privileges.
- type: str
- version_added: '2.6'
- domain:
- description:
- - Domain the instance is related to.
- type: str
- account:
- description:
- - Account the instance is related to.
- type: str
- project:
- description:
- - Name of the project the instance to be deployed in.
- type: str
- zone:
- description:
- - Name of the zone in which the instance should be deployed.
- - If not set, default zone is used.
- type: str
- ssh_key:
- description:
- - Name of the SSH key to be deployed on the new instance.
- type: str
- affinity_groups:
- description:
- - Affinity groups names to be applied to the new instance.
- type: list
- aliases: [ affinity_group ]
- user_data:
- description:
- - Optional data (ASCII) that can be sent to the instance upon a successful deployment.
- - The data will be automatically base64 encoded.
- - Consider switching to HTTP_POST by using I(CLOUDSTACK_METHOD=post) to increase the HTTP_GET size limit of 2KB to 32 KB.
- type: str
- force:
- description:
- - Force stop/start the instance if required to apply changes, otherwise a running instance will not be changed.
- type: bool
- default: no
- allow_root_disk_shrink:
- description:
- - Enables a volume shrinkage when the new size is smaller than the old one.
- type: bool
- default: no
- version_added: '2.7'
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys C(key) and C(value).
- - "If you want to delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
- details:
- description:
- - Map to specify custom parameters.
- type: dict
- version_added: '2.6'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-# NOTE: Names of offerings and ISOs depending on the CloudStack configuration.
-- name: create a instance from an ISO
- cs_instance:
- name: web-vm-1
- iso: Linux Debian 7 64-bit
- hypervisor: VMware
- project: Integration
- zone: ch-zrh-ix-01
- service_offering: 1cpu_1gb
- disk_offering: PerfPlus Storage
- disk_size: 20
- networks:
- - Server Integration
- - Sync Integration
- - Storage Integration
- delegate_to: localhost
-
-- name: for changing a running instance, use the 'force' parameter
- cs_instance:
- name: web-vm-1
- display_name: web-vm-01.example.com
- iso: Linux Debian 7 64-bit
- service_offering: 2cpu_2gb
- force: yes
- delegate_to: localhost
-
-# NOTE: user_data can be used to kickstart the instance using cloud-init yaml config.
-- name: create or update a instance on Exoscale's public cloud using display_name.
- cs_instance:
- display_name: web-vm-1
- template: Linux Debian 7 64-bit
- service_offering: Tiny
- ssh_key: john@example.com
- tags:
- - key: admin
- value: john
- - key: foo
- value: bar
- user_data: |
- #cloud-config
- packages:
- - nginx
- delegate_to: localhost
-
-- name: create an instance with multiple interfaces specifying the IP addresses
- cs_instance:
- name: web-vm-1
- template: Linux Debian 7 64-bit
- service_offering: Tiny
- ip_to_networks:
- - network: NetworkA
- ip: 10.1.1.1
- - network: NetworkB
- ip: 192.0.2.1
- delegate_to: localhost
-
-- name: ensure an instance is stopped
- cs_instance:
- name: web-vm-1
- state: stopped
- delegate_to: localhost
-
-- name: ensure an instance is running
- cs_instance:
- name: web-vm-1
- state: started
- delegate_to: localhost
-
-- name: remove an instance
- cs_instance:
- name: web-vm-1
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the instance.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the instance.
- returned: success
- type: str
- sample: web-01
-display_name:
- description: Display name of the instance.
- returned: success
- type: str
- sample: web-01
-group:
- description: Group name of the instance is related.
- returned: success
- type: str
- sample: web
-created:
- description: Date of the instance was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-password_enabled:
- description: True if password setting is enabled.
- returned: success
- type: bool
- sample: true
-password:
- description: The password of the instance if exists.
- returned: if available
- type: str
- sample: Ge2oe7Do
-ssh_key:
- description: Name of SSH key deployed to instance.
- returned: if available
- type: str
- sample: key@work
-domain:
- description: Domain the instance is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the instance is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the instance is related to.
- returned: success
- type: str
- sample: Production
-default_ip:
- description: Default IP address of the instance.
- returned: success
- type: str
- sample: 10.23.37.42
-default_ip6:
- description: Default IPv6 address of the instance.
- returned: if available
- type: str
- sample: 2a04:c43:c00:a07:4b4:beff:fe00:74
- version_added: '2.6'
-public_ip:
- description: Public IP address with instance via static NAT rule.
- returned: if available
- type: str
- sample: 1.2.3.4
-iso:
- description: Name of ISO the instance was deployed with.
- returned: if available
- type: str
- sample: Debian-8-64bit
-template:
- description: Name of template the instance was deployed with.
- returned: success
- type: str
- sample: Linux Debian 9 64-bit
-template_display_text:
- description: Display text of template the instance was deployed with.
- returned: success
- type: str
- sample: Linux Debian 9 64-bit 200G Disk (2017-10-08-622866)
- version_added: '2.6'
-service_offering:
- description: Name of the service offering the instance has.
- returned: success
- type: str
- sample: 2cpu_2gb
-zone:
- description: Name of zone the instance is in.
- returned: success
- type: str
- sample: ch-gva-2
-state:
- description: State of the instance.
- returned: success
- type: str
- sample: Running
-security_groups:
- description: Security groups the instance is in.
- returned: success
- type: list
- sample: '[ "default" ]'
-affinity_groups:
- description: Affinity groups the instance is in.
- returned: success
- type: list
- sample: '[ "webservers" ]'
-tags:
- description: List of resource tags associated with the instance.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-hypervisor:
- description: Hypervisor related to this instance.
- returned: success
- type: str
- sample: KVM
-host:
- description: Hostname of hypervisor an instance is running on.
- returned: success and instance is running
- type: str
- sample: host-01.example.com
- version_added: '2.6'
-instance_name:
- description: Internal name of the instance (ROOT admin only).
- returned: success
- type: str
- sample: i-44-3992-VM
-user-data:
- description: Optional data sent to the instance.
- returned: success
- type: str
- sample: VXNlciBkYXRhIGV4YW1wbGUK
-'''
-
-import base64
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils._text import to_bytes, to_text
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackInstance(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstance, self).__init__(module)
- self.returns = {
- 'group': 'group',
- 'hypervisor': 'hypervisor',
- 'instancename': 'instance_name',
- 'publicip': 'public_ip',
- 'passwordenabled': 'password_enabled',
- 'password': 'password',
- 'serviceofferingname': 'service_offering',
- 'isoname': 'iso',
- 'templatename': 'template',
- 'templatedisplaytext': 'template_display_text',
- 'keypair': 'ssh_key',
- 'hostname': 'host',
- }
- self.instance = None
- self.template = None
- self.iso = None
-
- def get_service_offering_id(self):
- service_offering = self.module.params.get('service_offering')
-
- service_offerings = self.query_api('listServiceOfferings')
- if service_offerings:
- if not service_offering:
- return service_offerings['serviceoffering'][0]['id']
-
- for s in service_offerings['serviceoffering']:
- if service_offering in [s['name'], s['id']]:
- return s['id']
- self.fail_json(msg="Service offering '%s' not found" % service_offering)
-
- def get_host_id(self):
- host_name = self.module.params.get('host')
- if not host_name:
- return None
-
- args = {
- 'type': 'routing',
- 'zoneid': self.get_zone(key='id'),
- }
- hosts = self.query_api('listHosts', **args)
- if hosts:
- for h in hosts['host']:
- if h['name'] == host_name:
- return h['id']
-
- self.fail_json(msg="Host '%s' not found" % host_name)
-
- def get_template_or_iso(self, key=None):
- template = self.module.params.get('template')
- iso = self.module.params.get('iso')
-
- if not template and not iso:
- return None
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'isrecursive': True,
- 'fetch_list': True,
- }
-
- if template:
- if self.template:
- return self._get_by_key(key, self.template)
-
- rootdisksize = self.module.params.get('root_disk_size')
- args['templatefilter'] = self.module.params.get('template_filter')
- args['fetch_list'] = True
- templates = self.query_api('listTemplates', **args)
- if templates:
- for t in templates:
- if template in [t['displaytext'], t['name'], t['id']]:
- if rootdisksize and t['size'] > rootdisksize * 1024 ** 3:
- continue
- self.template = t
- return self._get_by_key(key, self.template)
-
- if rootdisksize:
- more_info = " (with size <= %s)" % rootdisksize
- else:
- more_info = ""
-
- self.module.fail_json(msg="Template '%s' not found%s" % (template, more_info))
-
- elif iso:
- if self.iso:
- return self._get_by_key(key, self.iso)
-
- args['isofilter'] = self.module.params.get('template_filter')
- args['fetch_list'] = True
- isos = self.query_api('listIsos', **args)
- if isos:
- for i in isos:
- if iso in [i['displaytext'], i['name'], i['id']]:
- self.iso = i
- return self._get_by_key(key, self.iso)
-
- self.module.fail_json(msg="ISO '%s' not found" % iso)
-
- def get_instance(self):
- instance = self.instance
- if not instance:
- instance_name = self.get_or_fallback('name', 'display_name')
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'fetch_list': True,
- }
- # Do not pass zoneid, as the instance name must be unique across zones.
- instances = self.query_api('listVirtualMachines', **args)
- if instances:
- for v in instances:
- if instance_name.lower() in [v['name'].lower(), v['displayname'].lower(), v['id']]:
- self.instance = v
- break
- return self.instance
-
- def _get_instance_user_data(self, instance):
- # Query the user data if we need to
- if 'userdata' in instance:
- return instance['userdata']
-
- user_data = ""
- if self.get_user_data() is not None and instance.get('id'):
- res = self.query_api('getVirtualMachineUserData', virtualmachineid=instance['id'])
- user_data = res['virtualmachineuserdata'].get('userdata', "")
- return user_data
-
- def get_iptonetwork_mappings(self):
- network_mappings = self.module.params.get('ip_to_networks')
- if network_mappings is None:
- return
-
- if network_mappings and self.module.params.get('networks'):
- self.module.fail_json(msg="networks and ip_to_networks are mutually exclusive.")
-
- network_names = [n['network'] for n in network_mappings]
- ids = self.get_network_ids(network_names)
- res = []
- for i, data in enumerate(network_mappings):
- res.append({'networkid': ids[i], 'ip': data['ip']})
- return res
-
- def get_ssh_keypair(self, key=None, name=None, fail_on_missing=True):
- ssh_key_name = name or self.module.params.get('ssh_key')
- if ssh_key_name is None:
- return
-
- args = {
- 'domainid': self.get_domain('id'),
- 'account': self.get_account('name'),
- 'projectid': self.get_project('id'),
- 'name': ssh_key_name,
- }
- ssh_key_pairs = self.query_api('listSSHKeyPairs', **args)
- if 'sshkeypair' in ssh_key_pairs:
- return self._get_by_key(key=key, my_dict=ssh_key_pairs['sshkeypair'][0])
-
- elif fail_on_missing:
- self.module.fail_json(msg="SSH key not found: %s" % ssh_key_name)
-
- def ssh_key_has_changed(self):
- ssh_key_name = self.module.params.get('ssh_key')
- if ssh_key_name is None:
- return False
-
- # Fails if keypair for param is inexistent
- param_ssh_key_fp = self.get_ssh_keypair(key='fingerprint')
-
- # CloudStack 4.5 does return keypair on instance for a non existent key.
- instance_ssh_key_name = self.instance.get('keypair')
- if instance_ssh_key_name is None:
- return True
-
- # Get fingerprint for keypair of instance but do not fail if inexistent.
- instance_ssh_key_fp = self.get_ssh_keypair(key='fingerprint', name=instance_ssh_key_name, fail_on_missing=False)
- if not instance_ssh_key_fp:
- return True
-
- # Compare fingerprints to ensure the keypair changed
- if instance_ssh_key_fp != param_ssh_key_fp:
- return True
- return False
-
- def security_groups_has_changed(self):
- security_groups = self.module.params.get('security_groups')
- if security_groups is None:
- return False
-
- security_groups = [s.lower() for s in security_groups]
- instance_security_groups = self.instance.get('securitygroup') or []
-
- instance_security_group_names = []
- for instance_security_group in instance_security_groups:
- if instance_security_group['name'].lower() not in security_groups:
- return True
- else:
- instance_security_group_names.append(instance_security_group['name'].lower())
-
- for security_group in security_groups:
- if security_group not in instance_security_group_names:
- return True
- return False
-
- def get_network_ids(self, network_names=None):
- if network_names is None:
- network_names = self.module.params.get('networks')
-
- if not network_names:
- return None
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'fetch_list': True,
- }
- networks = self.query_api('listNetworks', **args)
- if not networks:
- self.module.fail_json(msg="No networks available")
-
- network_ids = []
- network_displaytexts = []
- for network_name in network_names:
- for n in networks:
- if network_name in [n['displaytext'], n['name'], n['id']]:
- network_ids.append(n['id'])
- network_displaytexts.append(n['name'])
- break
-
- if len(network_ids) != len(network_names):
- self.module.fail_json(msg="Could not find all networks, networks list found: %s" % network_displaytexts)
-
- return network_ids
-
- def present_instance(self, start_vm=True):
- instance = self.get_instance()
-
- if not instance:
- instance = self.deploy_instance(start_vm=start_vm)
- else:
- instance = self.recover_instance(instance=instance)
- instance = self.update_instance(instance=instance, start_vm=start_vm)
-
- # In check mode, we do not necessarily have an instance
- if instance:
- instance = self.ensure_tags(resource=instance, resource_type='UserVm')
- # refresh instance data
- self.instance = instance
-
- return instance
-
- def get_user_data(self):
- user_data = self.module.params.get('user_data')
- if user_data is not None:
- user_data = to_text(base64.b64encode(to_bytes(user_data)))
- return user_data
-
- def get_details(self):
- details = self.module.params.get('details')
- cpu = self.module.params.get('cpu')
- cpu_speed = self.module.params.get('cpu_speed')
- memory = self.module.params.get('memory')
- if all([cpu, cpu_speed, memory]):
- details.extends({
- 'cpuNumber': cpu,
- 'cpuSpeed': cpu_speed,
- 'memory': memory,
- })
-
- return details
-
- def deploy_instance(self, start_vm=True):
- self.result['changed'] = True
- networkids = self.get_network_ids()
- if networkids is not None:
- networkids = ','.join(networkids)
-
- args = {}
- args['templateid'] = self.get_template_or_iso(key='id')
- if not args['templateid']:
- self.module.fail_json(msg="Template or ISO is required.")
-
- args['zoneid'] = self.get_zone(key='id')
- args['serviceofferingid'] = self.get_service_offering_id()
- args['account'] = self.get_account(key='name')
- args['domainid'] = self.get_domain(key='id')
- args['projectid'] = self.get_project(key='id')
- args['diskofferingid'] = self.get_disk_offering(key='id')
- args['networkids'] = networkids
- args['iptonetworklist'] = self.get_iptonetwork_mappings()
- args['userdata'] = self.get_user_data()
- args['keyboard'] = self.module.params.get('keyboard')
- args['ipaddress'] = self.module.params.get('ip_address')
- args['ip6address'] = self.module.params.get('ip6_address')
- args['name'] = self.module.params.get('name')
- args['displayname'] = self.get_or_fallback('display_name', 'name')
- args['group'] = self.module.params.get('group')
- args['keypair'] = self.get_ssh_keypair(key='name')
- args['size'] = self.module.params.get('disk_size')
- args['startvm'] = start_vm
- args['rootdisksize'] = self.module.params.get('root_disk_size')
- args['affinitygroupnames'] = self.module.params.get('affinity_groups')
- args['details'] = self.get_details()
- args['securitygroupnames'] = self.module.params.get('security_groups')
- args['hostid'] = self.get_host_id()
-
- template_iso = self.get_template_or_iso()
- if 'hypervisor' not in template_iso:
- args['hypervisor'] = self.get_hypervisor()
-
- instance = None
- if not self.module.check_mode:
- instance = self.query_api('deployVirtualMachine', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(instance, 'virtualmachine')
- return instance
-
- def update_instance(self, instance, start_vm=True):
- # Service offering data
- args_service_offering = {
- 'id': instance['id'],
- }
- if self.module.params.get('service_offering'):
- args_service_offering['serviceofferingid'] = self.get_service_offering_id()
- service_offering_changed = self.has_changed(args_service_offering, instance)
-
- # Instance data
- args_instance_update = {
- 'id': instance['id'],
- 'userdata': self.get_user_data(),
- }
- instance['userdata'] = self._get_instance_user_data(instance)
- args_instance_update['ostypeid'] = self.get_os_type(key='id')
- if self.module.params.get('group'):
- args_instance_update['group'] = self.module.params.get('group')
- if self.module.params.get('display_name'):
- args_instance_update['displayname'] = self.module.params.get('display_name')
- instance_changed = self.has_changed(args_instance_update, instance)
-
- ssh_key_changed = self.ssh_key_has_changed()
-
- security_groups_changed = self.security_groups_has_changed()
-
- # Volume data
- args_volume_update = {}
- root_disk_size = self.module.params.get('root_disk_size')
- root_disk_size_changed = False
-
- if root_disk_size is not None:
- res = self.query_api('listVolumes', type='ROOT', virtualmachineid=instance['id'])
- [volume] = res['volume']
-
- size = volume['size'] >> 30
-
- args_volume_update['id'] = volume['id']
- args_volume_update['size'] = root_disk_size
-
- shrinkok = self.module.params.get('allow_root_disk_shrink')
- if shrinkok:
- args_volume_update['shrinkok'] = shrinkok
-
- root_disk_size_changed = root_disk_size != size
-
- changed = [
- service_offering_changed,
- instance_changed,
- security_groups_changed,
- ssh_key_changed,
- root_disk_size_changed,
- ]
-
- if any(changed):
- force = self.module.params.get('force')
- instance_state = instance['state'].lower()
- if instance_state == 'stopped' or force:
- self.result['changed'] = True
- if not self.module.check_mode:
-
- # Ensure VM has stopped
- instance = self.stop_instance()
- instance = self.poll_job(instance, 'virtualmachine')
- self.instance = instance
-
- # Change service offering
- if service_offering_changed:
- res = self.query_api('changeServiceForVirtualMachine', **args_service_offering)
- instance = res['virtualmachine']
- self.instance = instance
-
- # Update VM
- if instance_changed or security_groups_changed:
- if security_groups_changed:
- args_instance_update['securitygroupnames'] = ','.join(self.module.params.get('security_groups'))
- res = self.query_api('updateVirtualMachine', **args_instance_update)
- instance = res['virtualmachine']
- self.instance = instance
-
- # Reset SSH key
- if ssh_key_changed:
- # SSH key data
- args_ssh_key = {}
- args_ssh_key['id'] = instance['id']
- args_ssh_key['projectid'] = self.get_project(key='id')
- args_ssh_key['keypair'] = self.module.params.get('ssh_key')
- instance = self.query_api('resetSSHKeyForVirtualMachine', **args_ssh_key)
- instance = self.poll_job(instance, 'virtualmachine')
- self.instance = instance
-
- # Root disk size
- if root_disk_size_changed:
- async_result = self.query_api('resizeVolume', **args_volume_update)
- self.poll_job(async_result, 'volume')
-
- # Start VM again if it was running before
- if instance_state == 'running' and start_vm:
- instance = self.start_instance()
- else:
- self.module.warn("Changes won't be applied to running instances. "
- "Use force=true to allow the instance %s to be stopped/started." % instance['name'])
-
- # migrate to other host
- host_changed = all([
- instance['state'].lower() in ['starting', 'running'],
- instance.get('hostname') is not None,
- self.module.params.get('host') is not None,
- self.module.params.get('host') != instance.get('hostname')
- ])
- if host_changed:
- self.result['changed'] = True
- args_host = {
- 'virtualmachineid': instance['id'],
- 'hostid': self.get_host_id(),
- }
- if not self.module.check_mode:
- res = self.query_api('migrateVirtualMachine', **args_host)
- instance = self.poll_job(res, 'virtualmachine')
-
- return instance
-
- def recover_instance(self, instance):
- if instance['state'].lower() in ['destroying', 'destroyed']:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('recoverVirtualMachine', id=instance['id'])
- instance = res['virtualmachine']
- return instance
-
- def absent_instance(self):
- instance = self.get_instance()
- if instance:
- if instance['state'].lower() not in ['expunging', 'destroying', 'destroyed']:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('destroyVirtualMachine', id=instance['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(res, 'virtualmachine')
- return instance
-
- def expunge_instance(self):
- instance = self.get_instance()
- if instance:
- res = {}
- if instance['state'].lower() in ['destroying', 'destroyed']:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('destroyVirtualMachine', id=instance['id'], expunge=True)
-
- elif instance['state'].lower() not in ['expunging']:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('destroyVirtualMachine', id=instance['id'], expunge=True)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- res = self.poll_job(res, 'virtualmachine')
- return instance
-
- def stop_instance(self):
- instance = self.get_instance()
- # in check mode instance may not be instantiated
- if instance:
- if instance['state'].lower() in ['stopping', 'stopped']:
- return instance
-
- if instance['state'].lower() in ['starting', 'running']:
- self.result['changed'] = True
- if not self.module.check_mode:
- instance = self.query_api('stopVirtualMachine', id=instance['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(instance, 'virtualmachine')
- return instance
-
- def start_instance(self):
- instance = self.get_instance()
- # in check mode instance may not be instantiated
- if instance:
- if instance['state'].lower() in ['starting', 'running']:
- return instance
-
- if instance['state'].lower() in ['stopped', 'stopping']:
- self.result['changed'] = True
- if not self.module.check_mode:
- args = {
- 'id': instance['id'],
- 'hostid': self.get_host_id(),
- }
- instance = self.query_api('startVirtualMachine', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(instance, 'virtualmachine')
- return instance
-
- def restart_instance(self):
- instance = self.get_instance()
- # in check mode instance may not be instantiated
- if instance:
- if instance['state'].lower() in ['running', 'starting']:
- self.result['changed'] = True
- if not self.module.check_mode:
- instance = self.query_api('rebootVirtualMachine', id=instance['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(instance, 'virtualmachine')
-
- elif instance['state'].lower() in ['stopping', 'stopped']:
- instance = self.start_instance()
- return instance
-
- def restore_instance(self):
- instance = self.get_instance()
- self.result['changed'] = True
- # in check mode instance may not be instantiated
- if instance:
- args = {}
- args['templateid'] = self.get_template_or_iso(key='id')
- args['virtualmachineid'] = instance['id']
- res = self.query_api('restoreVirtualMachine', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- instance = self.poll_job(res, 'virtualmachine')
- return instance
-
- def get_result(self, instance):
- super(AnsibleCloudStackInstance, self).get_result(instance)
- if instance:
- self.result['user_data'] = self._get_instance_user_data(instance)
- if 'securitygroup' in instance:
- security_groups = []
- for securitygroup in instance['securitygroup']:
- security_groups.append(securitygroup['name'])
- self.result['security_groups'] = security_groups
- if 'affinitygroup' in instance:
- affinity_groups = []
- for affinitygroup in instance['affinitygroup']:
- affinity_groups.append(affinitygroup['name'])
- self.result['affinity_groups'] = affinity_groups
- if 'nic' in instance:
- for nic in instance['nic']:
- if nic['isdefault']:
- if 'ipaddress' in nic:
- self.result['default_ip'] = nic['ipaddress']
- if 'ip6address' in nic:
- self.result['default_ip6'] = nic['ip6address']
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(),
- display_name=dict(),
- group=dict(),
- state=dict(choices=['present', 'deployed', 'started', 'stopped', 'restarted', 'restored', 'absent', 'destroyed', 'expunged'], default='present'),
- service_offering=dict(),
- cpu=dict(type='int'),
- cpu_speed=dict(type='int'),
- memory=dict(type='int'),
- template=dict(),
- iso=dict(),
- template_filter=dict(
- default="executable",
- aliases=['iso_filter'],
- choices=['all', 'featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community']
- ),
- networks=dict(type='list', aliases=['network']),
- ip_to_networks=dict(type='list', aliases=['ip_to_network']),
- ip_address=dict(),
- ip6_address=dict(),
- disk_offering=dict(),
- disk_size=dict(type='int'),
- root_disk_size=dict(type='int'),
- keyboard=dict(type='str', choices=['de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us']),
- hypervisor=dict(),
- host=dict(),
- security_groups=dict(type='list', aliases=['security_group']),
- affinity_groups=dict(type='list', aliases=['affinity_group']),
- domain=dict(),
- account=dict(),
- project=dict(),
- user_data=dict(),
- zone=dict(),
- ssh_key=dict(),
- force=dict(type='bool', default=False),
- tags=dict(type='list', aliases=['tag']),
- details=dict(type='dict'),
- poll_async=dict(type='bool', default=True),
- allow_root_disk_shrink=dict(type='bool', default=False),
- ))
-
- required_together = cs_required_together()
- required_together.extend([
- ['cpu', 'cpu_speed', 'memory'],
- ])
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=required_together,
- required_one_of=(
- ['display_name', 'name'],
- ),
- mutually_exclusive=(
- ['template', 'iso'],
- ),
- supports_check_mode=True
- )
-
- acs_instance = AnsibleCloudStackInstance(module)
-
- state = module.params.get('state')
-
- if state in ['absent', 'destroyed']:
- instance = acs_instance.absent_instance()
-
- elif state in ['expunged']:
- instance = acs_instance.expunge_instance()
-
- elif state in ['restored']:
- acs_instance.present_instance()
- instance = acs_instance.restore_instance()
-
- elif state in ['present', 'deployed']:
- instance = acs_instance.present_instance()
-
- elif state in ['stopped']:
- acs_instance.present_instance(start_vm=False)
- instance = acs_instance.stop_instance()
-
- elif state in ['started']:
- acs_instance.present_instance()
- instance = acs_instance.start_instance()
-
- elif state in ['restarted']:
- acs_instance.present_instance()
- instance = acs_instance.restart_instance()
-
- if instance and 'state' in instance and instance['state'].lower() == 'error':
- module.fail_json(msg="Instance named '%s' in error state." % module.params.get('name'))
-
- result = acs_instance.get_result(instance)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance_info.py b/lib/ansible/modules/cloud/cloudstack/cs_instance_info.py
deleted file mode 100644
index ea5435c6b3..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instance_info.py
+++ /dev/null
@@ -1,378 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance_info
-short_description: Gathering information from the API of instances from Apache CloudStack based clouds.
-description:
- - Gathering information from the API of an instance.
-version_added: '2.9'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name or display name of the instance.
- - If not specified, all instances are returned
- type: str
- required: false
- domain:
- description:
- - Domain the instance is related to.
- type: str
- account:
- description:
- - Account the instance is related to.
- type: str
- project:
- description:
- - Project the instance is related to.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Gather instance information
- cs_instance_info:
- name: web-vm-1
- delegate_to: localhost
- register: vm
-
-- name: Show the returned results of the registered variable
- debug:
- msg: "{{ vm }}"
-
-- name: Gather information from all instances
- cs_instance_info:
- delegate_to: localhost
- register: vms
-
-- name: Show information on all instances
- debug:
- msg: "{{ vms }}"
-'''
-
-RETURN = '''
----
-instances:
- description: A list of matching instances.
- type: list
- returned: success
- contains:
- id:
- description: UUID of the instance.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
- name:
- description: Name of the instance.
- returned: success
- type: str
- sample: web-01
- display_name:
- description: Display name of the instance.
- returned: success
- type: str
- sample: web-01
- group:
- description: Group name of the instance is related.
- returned: success
- type: str
- sample: web
- created:
- description: Date of the instance was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
- password_enabled:
- description: True if password setting is enabled.
- returned: success
- type: bool
- sample: true
- password:
- description: The password of the instance if exists.
- returned: success
- type: str
- sample: Ge2oe7Do
- ssh_key:
- description: Name of SSH key deployed to instance.
- returned: success
- type: str
- sample: key@work
- domain:
- description: Domain the instance is related to.
- returned: success
- type: str
- sample: example domain
- account:
- description: Account the instance is related to.
- returned: success
- type: str
- sample: example account
- project:
- description: Name of project the instance is related to.
- returned: success
- type: str
- sample: Production
- default_ip:
- description: Default IP address of the instance.
- returned: success
- type: str
- sample: 10.23.37.42
- public_ip:
- description: Public IP address with instance via static NAT rule.
- returned: success
- type: str
- sample: 1.2.3.4
- iso:
- description: Name of ISO the instance was deployed with.
- returned: success
- type: str
- sample: Debian-8-64bit
- template:
- description: Name of template the instance was deployed with.
- returned: success
- type: str
- sample: Debian-8-64bit
- service_offering:
- description: Name of the service offering the instance has.
- returned: success
- type: str
- sample: 2cpu_2gb
- zone:
- description: Name of zone the instance is in.
- returned: success
- type: str
- sample: ch-gva-2
- state:
- description: State of the instance.
- returned: success
- type: str
- sample: Running
- security_groups:
- description: Security groups the instance is in.
- returned: success
- type: list
- sample: '[ "default" ]'
- affinity_groups:
- description: Affinity groups the instance is in.
- returned: success
- type: list
- sample: '[ "webservers" ]'
- tags:
- description: List of resource tags associated with the instance.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
- hypervisor:
- description: Hypervisor related to this instance.
- returned: success
- type: str
- sample: KVM
- host:
- description: Host the instance is running on.
- returned: success and instance is running
- type: str
- sample: host01.example.com
- version_added: '2.6'
- instance_name:
- description: Internal name of the instance (ROOT admin only).
- returned: success
- type: str
- sample: i-44-3992-VM
- volumes:
- description: List of dictionaries of the volumes attached to the instance.
- returned: success
- type: list
- sample: '[ { name: "ROOT-1369", type: "ROOT", size: 10737418240 }, { name: "data01, type: "DATADISK", size: 10737418240 } ]'
- nic:
- description: List of dictionaries of the instance nics.
- returned: success
- type: complex
- version_added: '2.8'
- contains:
- broadcasturi:
- description: The broadcast uri of the nic.
- returned: success
- type: str
- sample: vlan://2250
- gateway:
- description: The gateway of the nic.
- returned: success
- type: str
- sample: 10.1.2.1
- id:
- description: The ID of the nic.
- returned: success
- type: str
- sample: 5dc74fa3-2ec3-48a0-9e0d-6f43365336a9
- ipaddress:
- description: The ip address of the nic.
- returned: success
- type: str
- sample: 10.1.2.3
- isdefault:
- description: True if nic is default, false otherwise.
- returned: success
- type: bool
- sample: true
- isolationuri:
- description: The isolation uri of the nic.
- returned: success
- type: str
- sample: vlan://2250
- macaddress:
- description: The mac address of the nic.
- returned: success
- type: str
- sample: 06:a2:03:00:08:12
- netmask:
- description: The netmask of the nic.
- returned: success
- type: str
- sample: 255.255.255.0
- networkid:
- description: The ID of the corresponding network.
- returned: success
- type: str
- sample: 432ce27b-c2bb-4e12-a88c-a919cd3a3017
- networkname:
- description: The name of the corresponding network.
- returned: success
- type: str
- sample: network1
- traffictype:
- description: The traffic type of the nic.
- returned: success
- type: str
- sample: Guest
- type:
- description: The type of the network.
- returned: success
- type: str
- sample: Shared
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec
-
-
-class AnsibleCloudStackInstanceInfo(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstanceInfo, self).__init__(module)
- self.returns = {
- 'group': 'group',
- 'hypervisor': 'hypervisor',
- 'instancename': 'instance_name',
- 'publicip': 'public_ip',
- 'passwordenabled': 'password_enabled',
- 'password': 'password',
- 'serviceofferingname': 'service_offering',
- 'isoname': 'iso',
- 'templatename': 'template',
- 'keypair': 'ssh_key',
- 'hostname': 'host',
- }
-
- def get_instances(self):
- instance_name = self.module.params.get('name')
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'fetch_list': True,
- }
- # Do not pass zoneid, as the instance name must be unique across zones.
- instances = self.query_api('listVirtualMachines', **args)
- if not instance_name:
- return instances or []
- if instances:
- for v in instances:
- if instance_name.lower() in [v['name'].lower(), v['displayname'].lower(), v['id']]:
- return [v]
- return []
-
- def get_volumes(self, instance):
- volume_details = []
- if instance:
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'virtualmachineid': instance['id'],
- 'fetch_list': True,
- }
-
- volumes = self.query_api('listVolumes', **args)
- if volumes:
- for vol in volumes:
- volume_details.append({'size': vol['size'], 'type': vol['type'], 'name': vol['name']})
- return volume_details
-
- def run(self):
- instances = self.get_instances()
- if self.module.params.get('name') and not instances:
- self.module.fail_json(msg="Instance not found: %s" % self.module.params.get('name'))
- return {
- 'instances': [self.update_result(resource) for resource in instances]
- }
-
- def update_result(self, instance, result=None):
- result = super(AnsibleCloudStackInstanceInfo, self).update_result(instance, result)
- if instance:
- if 'securitygroup' in instance:
- security_groups = []
- for securitygroup in instance['securitygroup']:
- security_groups.append(securitygroup['name'])
- result['security_groups'] = security_groups
- if 'affinitygroup' in instance:
- affinity_groups = []
- for affinitygroup in instance['affinitygroup']:
- affinity_groups.append(affinitygroup['name'])
- result['affinity_groups'] = affinity_groups
- if 'nic' in instance:
- for nic in instance['nic']:
- if nic['isdefault'] and 'ipaddress' in nic:
- result['default_ip'] = nic['ipaddress']
- result['nic'] = instance['nic']
- volumes = self.get_volumes(instance)
- if volumes:
- result['volumes'] = volumes
- return result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- acs_instance_info = AnsibleCloudStackInstanceInfo(module=module)
- cs_instance_info = acs_instance_info.run()
- module.exit_json(**cs_instance_info)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance_nic.py b/lib/ansible/modules/cloud/cloudstack/cs_instance_nic.py
deleted file mode 100644
index 69f45d0445..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instance_nic.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Marc-Aurèle Brothier @marcaurele
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance_nic
-short_description: Manages NICs of an instance on Apache CloudStack based clouds.
-description:
- - Add and remove nic to and from network
-version_added: '2.4'
-author:
- - Marc-Aurèle Brothier (@marcaurele)
- - René Moser (@resmo)
-options:
- vm:
- description:
- - Name of instance.
- required: true
- type: str
- aliases: [ name ]
- network:
- description:
- - Name of the network.
- type: str
- required: true
- ip_address:
- description:
- - IP address to be used for the nic.
- type: str
- vpc:
- description:
- - Name of the VPC the I(vm) is related to.
- type: str
- domain:
- description:
- - Domain the instance is related to.
- type: str
- account:
- description:
- - Account the instance is related to.
- type: str
- project:
- description:
- - Name of the project the instance is deployed in.
- type: str
- zone:
- description:
- - Name of the zone in which the instance is deployed in.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the nic.
- type: str
- default: present
- choices: [ present, absent ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Add a nic on another network
- cs_instance_nic:
- vm: privnet
- network: privNetForBasicZone
- delegate_to: localhost
-
-- name: Ensure IP address on a nic
- cs_instance_nic:
- vm: privnet
- ip_address: 10.10.11.32
- network: privNetForBasicZone
- delegate_to: localhost
-
-- name: Remove a secondary nic
- cs_instance_nic:
- vm: privnet
- state: absent
- network: privNetForBasicZone
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the nic.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-vm:
- description: Name of the VM.
- returned: success
- type: str
- sample: web-01
-ip_address:
- description: Primary IP of the NIC.
- returned: success
- type: str
- sample: 10.10.10.10
-netmask:
- description: Netmask of the NIC.
- returned: success
- type: str
- sample: 255.255.255.0
-mac_address:
- description: MAC address of the NIC.
- returned: success
- type: str
- sample: 02:00:33:31:00:e4
-network:
- description: Name of the network if not default.
- returned: success
- type: str
- sample: sync network
-domain:
- description: Domain the VM is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the VM is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the VM is related to.
- returned: success
- type: str
- sample: Production
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together)
-
-
-class AnsibleCloudStackInstanceNic(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstanceNic, self).__init__(module)
- self.nic = None
- self.returns = {
- 'ipaddress': 'ip_address',
- 'macaddress': 'mac_address',
- 'netmask': 'netmask',
- }
-
- def get_nic(self):
- if self.nic:
- return self.nic
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'networkid': self.get_network(key='id'),
- }
- nics = self.query_api('listNics', **args)
- if nics:
- self.nic = nics['nic'][0]
- return self.nic
- return None
-
- def get_nic_from_result(self, result):
- for nic in result.get('nic') or []:
- if nic['networkid'] == self.get_network(key='id'):
- return nic
-
- def add_nic(self):
- self.result['changed'] = True
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'networkid': self.get_network(key='id'),
- 'ipaddress': self.module.params.get('ip_address'),
- }
- if not self.module.check_mode:
- res = self.query_api('addNicToVirtualMachine', **args)
-
- if self.module.params.get('poll_async'):
- vm = self.poll_job(res, 'virtualmachine')
- self.nic = self.get_nic_from_result(result=vm)
- return self.nic
-
- def update_nic(self, nic):
- # Do not try to update if no IP address is given
- ip_address = self.module.params.get('ip_address')
- if not ip_address:
- return nic
-
- args = {
- 'nicid': nic['id'],
- 'ipaddress': ip_address,
- }
- if self.has_changed(args, nic, ['ipaddress']):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateVmNicIp', **args)
-
- if self.module.params.get('poll_async'):
- vm = self.poll_job(res, 'virtualmachine')
- self.nic = self.get_nic_from_result(result=vm)
- return self.nic
-
- def remove_nic(self, nic):
- self.result['changed'] = True
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'nicid': nic['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('removeNicFromVirtualMachine', **args)
-
- if self.module.params.get('poll_async'):
- self.poll_job(res, 'virtualmachine')
- return nic
-
- def present_nic(self):
- nic = self.get_nic()
- if not nic:
- nic = self.add_nic()
- else:
- nic = self.update_nic(nic)
- return nic
-
- def absent_nic(self):
- nic = self.get_nic()
- if nic:
- return self.remove_nic(nic)
- return nic
-
- def get_result(self, nic):
- super(AnsibleCloudStackInstanceNic, self).get_result(nic)
- if nic and not self.module.params.get('network'):
- self.module.params['network'] = nic.get('networkid')
- self.result['network'] = self.get_network(key='name')
- self.result['vm'] = self.get_vm(key='name')
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- vm=dict(required=True, aliases=['name']),
- network=dict(required=True),
- vpc=dict(),
- ip_address=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True,
- )
-
- acs_nic = AnsibleCloudStackInstanceNic(module)
-
- state = module.params.get('state')
- if state == 'absent':
- nic = acs_nic.absent_nic()
- else:
- nic = acs_nic.present_nic()
-
- result = acs_nic.get_result(nic)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance_nic_secondaryip.py b/lib/ansible/modules/cloud/cloudstack/cs_instance_nic_secondaryip.py
deleted file mode 100644
index a122e1994b..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instance_nic_secondaryip.py
+++ /dev/null
@@ -1,272 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance_nic_secondaryip
-short_description: Manages secondary IPs of an instance on Apache CloudStack based clouds.
-description:
- - Add and remove secondary IPs to and from a NIC of an instance.
-version_added: '2.4'
-author: René Moser (@resmo)
-options:
- vm:
- description:
- - Name of instance.
- type: str
- required: true
- aliases: [ name ]
- network:
- description:
- - Name of the network.
- - Required to find the NIC if instance has multiple networks assigned.
- type: str
- vm_guest_ip:
- description:
- - Secondary IP address to be added to the instance nic.
- - If not set, the API always returns a new IP address and idempotency is not given.
- type: str
- aliases: [ secondary_ip ]
- vpc:
- description:
- - Name of the VPC the I(vm) is related to.
- type: str
- domain:
- description:
- - Domain the instance is related to.
- type: str
- account:
- description:
- - Account the instance is related to.
- type: str
- project:
- description:
- - Name of the project the instance is deployed in.
- type: str
- zone:
- description:
- - Name of the zone in which the instance is deployed in.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the ipaddress.
- type: str
- default: present
- choices: [ present, absent ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Assign a specific IP to the default NIC of the VM
- cs_instance_nic_secondaryip:
- vm: customer_xy
- vm_guest_ip: 10.10.10.10
- delegate_to: localhost
-
-# Note: If vm_guest_ip is not set, you will get a new IP address on every run.
-- name: Assign an IP to the default NIC of the VM
- cs_instance_nic_secondaryip:
- vm: customer_xy
- delegate_to: localhost
-
-- name: Remove a specific IP from the default NIC
- cs_instance_nic_secondaryip:
- vm: customer_xy
- vm_guest_ip: 10.10.10.10
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the NIC.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-vm:
- description: Name of the VM.
- returned: success
- type: str
- sample: web-01
-ip_address:
- description: Primary IP of the NIC.
- returned: success
- type: str
- sample: 10.10.10.10
-netmask:
- description: Netmask of the NIC.
- returned: success
- type: str
- sample: 255.255.255.0
-mac_address:
- description: MAC address of the NIC.
- returned: success
- type: str
- sample: 02:00:33:31:00:e4
-vm_guest_ip:
- description: Secondary IP of the NIC.
- returned: success
- type: str
- sample: 10.10.10.10
-network:
- description: Name of the network if not default.
- returned: success
- type: str
- sample: sync network
-domain:
- description: Domain the VM is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the VM is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the VM is related to.
- returned: success
- type: str
- sample: Production
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackInstanceNicSecondaryIp(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstanceNicSecondaryIp, self).__init__(module)
- self.vm_guest_ip = self.module.params.get('vm_guest_ip')
- self.nic = None
- self.returns = {
- 'ipaddress': 'ip_address',
- 'macaddress': 'mac_address',
- 'netmask': 'netmask',
- }
-
- def get_nic(self):
- if self.nic:
- return self.nic
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'networkid': self.get_network(key='id'),
- }
- nics = self.query_api('listNics', **args)
- if nics:
- self.nic = nics['nic'][0]
- return self.nic
- self.fail_json(msg="NIC for VM %s in network %s not found" % (self.get_vm(key='name'), self.get_network(key='name')))
-
- def get_secondary_ip(self):
- nic = self.get_nic()
- if self.vm_guest_ip:
- secondary_ips = nic.get('secondaryip') or []
- for secondary_ip in secondary_ips:
- if secondary_ip['ipaddress'] == self.vm_guest_ip:
- return secondary_ip
- return None
-
- def present_nic_ip(self):
- nic = self.get_nic()
- if not self.get_secondary_ip():
- self.result['changed'] = True
- args = {
- 'nicid': nic['id'],
- 'ipaddress': self.vm_guest_ip,
- }
-
- if not self.module.check_mode:
- res = self.query_api('addIpToNic', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- nic = self.poll_job(res, 'nicsecondaryip')
- # Save result for RETURNS
- self.vm_guest_ip = nic['ipaddress']
- return nic
-
- def absent_nic_ip(self):
- nic = self.get_nic()
- secondary_ip = self.get_secondary_ip()
- if secondary_ip:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('removeIpFromNic', id=secondary_ip['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'nicsecondaryip')
- return nic
-
- def get_result(self, nic):
- super(AnsibleCloudStackInstanceNicSecondaryIp, self).get_result(nic)
- if nic and not self.module.params.get('network'):
- self.module.params['network'] = nic.get('networkid')
- self.result['network'] = self.get_network(key='name')
- self.result['vm'] = self.get_vm(key='name')
- self.result['vm_guest_ip'] = self.vm_guest_ip
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- vm=dict(required=True, aliases=['name']),
- vm_guest_ip=dict(aliases=['secondary_ip']),
- network=dict(),
- vpc=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True,
- required_if=([
- ('state', 'absent', ['vm_guest_ip'])
- ])
- )
-
- acs_instance_nic_secondaryip = AnsibleCloudStackInstanceNicSecondaryIp(module)
- state = module.params.get('state')
-
- if state == 'absent':
- nic = acs_instance_nic_secondaryip.absent_nic_ip()
- else:
- nic = acs_instance_nic_secondaryip.present_nic_ip()
-
- result = acs_instance_nic_secondaryip.get_result(nic)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance_password_reset.py b/lib/ansible/modules/cloud/cloudstack/cs_instance_password_reset.py
deleted file mode 100644
index 53f35d78aa..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instance_password_reset.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2018, Gregor Riepl <onitake@gmail.com>
-# based on cs_sshkeypair (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instance_password_reset
-short_description: Allows resetting VM the default passwords on Apache CloudStack based clouds.
-description:
- - Resets the default user account's password on an instance.
- - Requires cloud-init to be installed in the virtual machine.
- - The passwordenabled flag must be set on the template associated with the VM.
-version_added: '2.8'
-author: Gregor Riepl (@onitake)
-options:
- vm:
- description:
- - Name of the virtual machine to reset the password on.
- type: str
- required: true
- domain:
- description:
- - Name of the domain the virtual machine belongs to.
- type: str
- account:
- description:
- - Account the virtual machine belongs to.
- type: str
- project:
- description:
- - Name of the project the virtual machine belongs to.
- type: str
- zone:
- description:
- - Name of the zone in which the instance is deployed.
- - If not set, the default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: stop the virtual machine before resetting the password
- cs_instance:
- name: myvirtualmachine
- state: stopped
- delegate_to: localhost
-
-- name: reset and get new default password
- cs_instance_password_reset:
- vm: myvirtualmachine
- register: root
- delegate_to: localhost
-- debug:
- msg: "new default password is {{ root.password }}"
-
-- name: boot the virtual machine to activate the new password
- cs_instance:
- name: myvirtualmachine
- state: started
- delegate_to: localhost
- when: root is changed
-'''
-
-RETURN = '''
----
-id:
- description: ID of the virtual machine.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-password:
- description: The new default password.
- returned: success
- type: str
- sample: ahQu5nuNge3keesh
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_required_together,
- cs_argument_spec
-)
-
-
-class AnsibleCloudStackPasswordReset(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackPasswordReset, self).__init__(module)
- self.returns = {
- 'password': 'password',
- }
- self.password = None
-
- def reset_password(self):
- args = {
- 'id': self.get_vm(key='id'),
- }
-
- res = None
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('resetPasswordForVirtualMachine', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- res = self.poll_job(res, 'virtualmachine')
-
- if res and 'password' in res:
- self.password = res['password']
-
- return self.password
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- vm=dict(required=True),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_password = AnsibleCloudStackPasswordReset(module)
- password = acs_password.reset_password()
- result = acs_password.get_result({'password': password})
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instancegroup.py b/lib/ansible/modules/cloud/cloudstack/cs_instancegroup.py
deleted file mode 100644
index 997633a2c6..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_instancegroup.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_instancegroup
-short_description: Manages instance groups on Apache CloudStack based clouds.
-description:
- - Create and remove instance groups.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the instance group.
- type: str
- required: true
- domain:
- description:
- - Domain the instance group is related to.
- type: str
- account:
- description:
- - Account the instance group is related to.
- type: str
- project:
- description:
- - Project the instance group is related to.
- type: str
- state:
- description:
- - State of the instance group.
- type: str
- default: present
- choices: [ present, absent ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create an instance group
- cs_instancegroup:
- name: loadbalancers
- delegate_to: localhost
-
-- name: Remove an instance group
- cs_instancegroup:
- name: loadbalancers
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the instance group.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the instance group.
- returned: success
- type: str
- sample: webservers
-created:
- description: Date when the instance group was created.
- returned: success
- type: str
- sample: 2015-05-03T15:05:51+0200
-domain:
- description: Domain the instance group is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the instance group is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Project the instance group is related to.
- returned: success
- type: str
- sample: example project
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackInstanceGroup(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackInstanceGroup, self).__init__(module)
- self.instance_group = None
-
- def get_instance_group(self):
- if self.instance_group:
- return self.instance_group
-
- name = self.module.params.get('name')
-
- args = {
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id'),
- 'projectid': self.get_project('id'),
- 'fetch_list': True,
- }
- instance_groups = self.query_api('listInstanceGroups', **args)
- if instance_groups:
- for g in instance_groups:
- if name in [g['name'], g['id']]:
- self.instance_group = g
- break
- return self.instance_group
-
- def present_instance_group(self):
- instance_group = self.get_instance_group()
- if not instance_group:
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id'),
- 'projectid': self.get_project('id'),
- }
- if not self.module.check_mode:
- res = self.query_api('createInstanceGroup', **args)
- instance_group = res['instancegroup']
- return instance_group
-
- def absent_instance_group(self):
- instance_group = self.get_instance_group()
- if instance_group:
- self.result['changed'] = True
- if not self.module.check_mode:
- self.query_api('deleteInstanceGroup', id=instance_group['id'])
- return instance_group
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- state=dict(default='present', choices=['present', 'absent']),
- domain=dict(),
- account=dict(),
- project=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_ig = AnsibleCloudStackInstanceGroup(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- instance_group = acs_ig.absent_instance_group()
- else:
- instance_group = acs_ig.present_instance_group()
-
- result = acs_ig.get_result(instance_group)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_ip_address.py b/lib/ansible/modules/cloud/cloudstack/cs_ip_address.py
deleted file mode 100644
index 4d6b821a0c..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_ip_address.py
+++ /dev/null
@@ -1,286 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2015, Darren Worrall <darren@iweb.co.uk>
-# Copyright (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_ip_address
-short_description: Manages public IP address associations on Apache CloudStack based clouds.
-description:
- - Acquires and associates a public IP to an account or project.
- - Due to API limitations this is not an idempotent call, so be sure to only
- conditionally call this when I(state=present).
- - Tagging the IP address can also make the call idempotent.
-version_added: '2.0'
-author:
- - Darren Worrall (@dazworrall)
- - René Moser (@resmo)
-options:
- ip_address:
- description:
- - Public IP address.
- - Required if I(state=absent) and I(tags) is not set.
- type: str
- domain:
- description:
- - Domain the IP address is related to.
- type: str
- network:
- description:
- - Network the IP address is related to.
- - Mutually exclusive with I(vpc).
- type: str
- vpc:
- description:
- - VPC the IP address is related to.
- - Mutually exclusive with I(network).
- type: str
- version_added: '2.2'
- account:
- description:
- - Account the IP address is related to.
- type: str
- project:
- description:
- - Name of the project the IP address is related to.
- type: str
- zone:
- description:
- - Name of the zone in which the IP address is in.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the IP address.
- type: str
- default: present
- choices: [ present, absent ]
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - Tags can be used as an unique identifier for the IP Addresses.
- - In this case, at least one of them must be unique to ensure idempotency.
- type: list
- aliases: [ tag ]
- version_added: '2.6'
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Associate an IP address conditionally
- cs_ip_address:
- network: My Network
- register: ip_address
- when: instance.public_ip is undefined
- delegate_to: localhost
-
-- name: Disassociate an IP address
- cs_ip_address:
- ip_address: 1.2.3.4
- state: absent
- delegate_to: localhost
-
-- name: Associate an IP address with tags
- cs_ip_address:
- network: My Network
- tags:
- - key: myCustomID
- - value: 5510c31a-416e-11e8-9013-02000a6b00bf
- register: ip_address
- delegate_to: localhost
-
-- name: Disassociate an IP address with tags
- cs_ip_address:
- state: absent
- tags:
- - key: myCustomID
- - value: 5510c31a-416e-11e8-9013-02000a6b00bf
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the Public IP address.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-ip_address:
- description: Public IP address.
- returned: success
- type: str
- sample: 1.2.3.4
-zone:
- description: Name of zone the IP address is related to.
- returned: success
- type: str
- sample: ch-gva-2
-project:
- description: Name of project the IP address is related to.
- returned: success
- type: str
- sample: Production
-account:
- description: Account the IP address is related to.
- returned: success
- type: str
- sample: example account
-domain:
- description: Domain the IP address is related to.
- returned: success
- type: str
- sample: example domain
-tags:
- description: List of resource tags associated with the IP address.
- returned: success
- type: dict
- sample: '[ { "key": "myCustomID", "value": "5510c31a-416e-11e8-9013-02000a6b00bf" } ]'
- version_added: '2.6'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackIPAddress(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackIPAddress, self).__init__(module)
- self.returns = {
- 'ipaddress': 'ip_address',
- }
-
- def get_ip_address(self, key=None):
- if self.ip_address:
- return self._get_by_key(key, self.ip_address)
- args = {
- 'ipaddress': self.module.params.get('ip_address'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'vpcid': self.get_vpc(key='id'),
- }
- ip_addresses = self.query_api('listPublicIpAddresses', **args)
-
- if ip_addresses:
- tags = self.module.params.get('tags')
- for ip_addr in ip_addresses['publicipaddress']:
- if ip_addr['ipaddress'] == args['ipaddress'] != '':
- self.ip_address = ip_addresses['publicipaddress'][0]
- elif tags:
- if sorted([tag for tag in tags if tag in ip_addr['tags']]) == sorted(tags):
- self.ip_address = ip_addr
- return self._get_by_key(key, self.ip_address)
-
- def present_ip_address(self):
- ip_address = self.get_ip_address()
-
- if not ip_address:
- ip_address = self.associate_ip_address(ip_address)
-
- if ip_address:
- ip_address = self.ensure_tags(resource=ip_address, resource_type='publicipaddress')
-
- return ip_address
-
- def associate_ip_address(self, ip_address):
- self.result['changed'] = True
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- # For the VPC case networkid is irrelevant, special case and we have to ignore it here.
- 'networkid': self.get_network(key='id') if not self.module.params.get('vpc') else None,
- 'zoneid': self.get_zone(key='id'),
- 'vpcid': self.get_vpc(key='id'),
- }
- ip_address = None
- if not self.module.check_mode:
- res = self.query_api('associateIpAddress', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- ip_address = self.poll_job(res, 'ipaddress')
- return ip_address
-
- def disassociate_ip_address(self):
- ip_address = self.get_ip_address()
- if not ip_address:
- return None
- if ip_address['isstaticnat']:
- self.module.fail_json(msg="IP address is allocated via static nat")
-
- self.result['changed'] = True
- if not self.module.check_mode:
- self.module.params['tags'] = []
- ip_address = self.ensure_tags(resource=ip_address, resource_type='publicipaddress')
-
- res = self.query_api('disassociateIpAddress', id=ip_address['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'ipaddress')
- return ip_address
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- ip_address=dict(required=False),
- state=dict(choices=['present', 'absent'], default='present'),
- vpc=dict(),
- network=dict(),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- tags=dict(type='list', aliases=['tag']),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- required_if=[
- ('state', 'absent', ['ip_address', 'tags'], True),
- ],
- mutually_exclusive=(
- ['vpc', 'network'],
- ),
- supports_check_mode=True
- )
-
- acs_ip_address = AnsibleCloudStackIPAddress(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- ip_address = acs_ip_address.disassociate_ip_address()
- else:
- ip_address = acs_ip_address.present_ip_address()
-
- result = acs_ip_address.get_result(ip_address)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_iso.py b/lib/ansible/modules/cloud/cloudstack/cs_iso.py
deleted file mode 100644
index 5781a0ce06..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_iso.py
+++ /dev/null
@@ -1,453 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_iso
-short_description: Manages ISO images on Apache CloudStack based clouds.
-description:
- - Register and remove ISO images.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the ISO.
- type: str
- required: true
- display_text:
- description:
- - Display text of the ISO.
- - If not specified, I(name) will be used.
- type: str
- version_added: '2.4'
- url:
- description:
- - URL where the ISO can be downloaded from. Required if I(state) is present.
- type: str
- os_type:
- description:
- - Name of the OS that best represents the OS of this ISO. If the iso is bootable this parameter needs to be passed. Required if I(state) is present.
- type: str
- is_ready:
- description:
- - This flag is used for searching existing ISOs. If set to C(yes), it will only list ISO ready for deployment e.g.
- successfully downloaded and installed. Recommended to set it to C(no).
- type: bool
- default: no
- is_public:
- description:
- - Register the ISO to be publicly available to all users. Only used if I(state) is present.
- type: bool
- is_featured:
- description:
- - Register the ISO to be featured. Only used if I(state) is present.
- type: bool
- is_dynamically_scalable:
- description:
- - Register the ISO having XS/VMware tools installed inorder to support dynamic scaling of VM cpu/memory. Only used if I(state) is present.
- type: bool
- checksum:
- description:
- - The MD5 checksum value of this ISO. If set, we search by checksum instead of name.
- type: str
- bootable:
- description:
- - Register the ISO to be bootable. Only used if I(state) is present.
- type: bool
- domain:
- description:
- - Domain the ISO is related to.
- type: str
- account:
- description:
- - Account the ISO is related to.
- type: str
- project:
- description:
- - Name of the project the ISO to be registered in.
- type: str
- zone:
- description:
- - Name of the zone you wish the ISO to be registered or deleted from.
- - If not specified, first zone found will be used.
- type: str
- cross_zones:
- description:
- - Whether the ISO should be synced or removed across zones.
- - Mutually exclusive with I(zone).
- type: bool
- default: no
- version_added: '2.4'
- iso_filter:
- description:
- - Name of the filter used to search for the ISO.
- type: str
- default: self
- choices: [ featured, self, selfexecutable,sharedexecutable,executable, community ]
- state:
- description:
- - State of the ISO.
- type: str
- default: present
- choices: [ present, absent ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
- version_added: '2.3'
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Register an ISO if ISO name does not already exist
- cs_iso:
- name: Debian 7 64-bit
- url: http://mirror.switch.ch/ftp/mirror/debian-cd/current/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso
- os_type: Debian GNU/Linux 7(64-bit)
- delegate_to: localhost
-
-- name: Register an ISO with given name if ISO md5 checksum does not already exist
- cs_iso:
- name: Debian 7 64-bit
- url: http://mirror.switch.ch/ftp/mirror/debian-cd/current/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso
- os_type: Debian GNU/Linux 7(64-bit)
- checksum: 0b31bccccb048d20b551f70830bb7ad0
- delegate_to: localhost
-
-- name: Remove an ISO by name
- cs_iso:
- name: Debian 7 64-bit
- state: absent
- delegate_to: localhost
-
-- name: Remove an ISO by checksum
- cs_iso:
- name: Debian 7 64-bit
- checksum: 0b31bccccb048d20b551f70830bb7ad0
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the ISO.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: Name of the ISO.
- returned: success
- type: str
- sample: Debian 7 64-bit
-display_text:
- description: Text to be displayed of the ISO.
- returned: success
- type: str
- sample: Debian 7.7 64-bit minimal 2015-03-19
-zone:
- description: Name of zone the ISO is registered in.
- returned: success
- type: str
- sample: zuerich
-status:
- description: Status of the ISO.
- returned: success
- type: str
- sample: Successfully Installed
-is_ready:
- description: True if the ISO is ready to be deployed from.
- returned: success
- type: bool
- sample: true
-is_public:
- description: True if the ISO is public.
- returned: success
- type: bool
- sample: true
- version_added: '2.4'
-bootable:
- description: True if the ISO is bootable.
- returned: success
- type: bool
- sample: true
- version_added: '2.4'
-is_featured:
- description: True if the ISO is featured.
- returned: success
- type: bool
- sample: true
- version_added: '2.4'
-format:
- description: Format of the ISO.
- returned: success
- type: str
- sample: ISO
- version_added: '2.4'
-os_type:
- description: Typo of the OS.
- returned: success
- type: str
- sample: CentOS 6.5 (64-bit)
- version_added: '2.4'
-checksum:
- description: MD5 checksum of the ISO.
- returned: success
- type: str
- sample: 0b31bccccb048d20b551f70830bb7ad0
-created:
- description: Date of registering.
- returned: success
- type: str
- sample: 2015-03-29T14:57:06+0200
-cross_zones:
- description: true if the ISO is managed across all zones, false otherwise.
- returned: success
- type: bool
- sample: false
- version_added: '2.4'
-domain:
- description: Domain the ISO is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the ISO is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Project the ISO is related to.
- returned: success
- type: str
- sample: example project
-tags:
- description: List of resource tags associated with the ISO.
- returned: success
- type: dict
- sample: '[ { "key": "foo", "value": "bar" } ]'
- version_added: '2.4'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackIso(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackIso, self).__init__(module)
- self.returns = {
- 'checksum': 'checksum',
- 'status': 'status',
- 'isready': 'is_ready',
- 'crossZones': 'cross_zones',
- 'format': 'format',
- 'ostypename': 'os_type',
- 'isfeatured': 'is_featured',
- 'bootable': 'bootable',
- 'ispublic': 'is_public',
-
- }
- self.iso = None
-
- def _get_common_args(self):
- return {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'isdynamicallyscalable': self.module.params.get('is_dynamically_scalable'),
- 'ostypeid': self.get_os_type('id'),
- 'bootable': self.module.params.get('bootable'),
- }
-
- def register_iso(self):
- args = self._get_common_args()
- args.update({
- 'domainid': self.get_domain('id'),
- 'account': self.get_account('name'),
- 'projectid': self.get_project('id'),
- 'checksum': self.module.params.get('checksum'),
- 'isfeatured': self.module.params.get('is_featured'),
- 'ispublic': self.module.params.get('is_public'),
- })
-
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
- else:
- args['zoneid'] = -1
-
- if args['bootable'] and not args['ostypeid']:
- self.module.fail_json(msg="OS type 'os_type' is required if 'bootable=true'.")
-
- args['url'] = self.module.params.get('url')
- if not args['url']:
- self.module.fail_json(msg="URL is required.")
-
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('registerIso', **args)
- self.iso = res['iso'][0]
- return self.iso
-
- def present_iso(self):
- iso = self.get_iso()
- if not iso:
- iso = self.register_iso()
- else:
- iso = self.update_iso(iso)
-
- if iso:
- iso = self.ensure_tags(resource=iso, resource_type='ISO')
- self.iso = iso
- return iso
-
- def update_iso(self, iso):
- args = self._get_common_args()
- args.update({
- 'id': iso['id'],
- })
- if self.has_changed(args, iso):
- self.result['changed'] = True
-
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
- else:
- # Workaround API does not return cross_zones=true
- self.result['cross_zones'] = True
- args['zoneid'] = -1
-
- if not self.module.check_mode:
- res = self.query_api('updateIso', **args)
- self.iso = res['iso']
- return self.iso
-
- def get_iso(self):
- if not self.iso:
- args = {
- 'isready': self.module.params.get('is_ready'),
- 'isofilter': self.module.params.get('iso_filter'),
- 'domainid': self.get_domain('id'),
- 'account': self.get_account('name'),
- 'projectid': self.get_project('id'),
- }
-
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
-
- # if checksum is set, we only look on that.
- checksum = self.module.params.get('checksum')
- if not checksum:
- args['name'] = self.module.params.get('name')
-
- isos = self.query_api('listIsos', **args)
- if isos:
- if not checksum:
- self.iso = isos['iso'][0]
- else:
- for i in isos['iso']:
- if i['checksum'] == checksum:
- self.iso = i
- break
- return self.iso
-
- def absent_iso(self):
- iso = self.get_iso()
- if iso:
- self.result['changed'] = True
-
- args = {
- 'id': iso['id'],
- 'projectid': self.get_project('id'),
- }
-
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
-
- if not self.module.check_mode:
- res = self.query_api('deleteIso', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'iso')
- return iso
-
- def get_result(self, iso):
- super(AnsibleCloudStackIso, self).get_result(iso)
- # Workaround API does not return cross_zones=true
- if self.module.params.get('cross_zones'):
- self.result['cross_zones'] = True
- if 'zone' in self.result:
- del self.result['zone']
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- url=dict(),
- os_type=dict(),
- zone=dict(),
- cross_zones=dict(type='bool', default=False),
- iso_filter=dict(default='self', choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community']),
- domain=dict(),
- account=dict(),
- project=dict(),
- checksum=dict(),
- is_ready=dict(type='bool', default=False),
- bootable=dict(type='bool'),
- is_featured=dict(type='bool'),
- is_public=dict(type='bool'),
- is_dynamically_scalable=dict(type='bool'),
- state=dict(choices=['present', 'absent'], default='present'),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['zone', 'cross_zones'],
- ),
- supports_check_mode=True
- )
-
- acs_iso = AnsibleCloudStackIso(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- iso = acs_iso.absent_iso()
- else:
- iso = acs_iso.present_iso()
-
- result = acs_iso.get_result(iso)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule.py b/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule.py
deleted file mode 100644
index 702c20da47..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule.py
+++ /dev/null
@@ -1,379 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, Darren Worrall <darren@iweb.co.uk>
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_loadbalancer_rule
-short_description: Manages load balancer rules on Apache CloudStack based clouds.
-description:
- - Add, update and remove load balancer rules.
-version_added: '2.0'
-author:
- - Darren Worrall (@dazworrall)
- - René Moser (@resmo)
-options:
- name:
- description:
- - The name of the load balancer rule.
- type: str
- required: true
- description:
- description:
- - The description of the load balancer rule.
- type: str
- algorithm:
- description:
- - Load balancer algorithm
- - Required when using I(state=present).
- type: str
- choices: [ source, roundrobin, leastconn ]
- default: source
- private_port:
- description:
- - The private port of the private ip address/virtual machine where the network traffic will be load balanced to.
- - Required when using I(state=present).
- - Can not be changed once the rule exists due API limitation.
- type: int
- public_port:
- description:
- - The public port from where the network traffic will be load balanced from.
- - Required when using I(state=present).
- - Can not be changed once the rule exists due API limitation.
- type: int
- required: true
- ip_address:
- description:
- - Public IP address from where the network traffic will be load balanced from.
- type: str
- required: true
- aliases: [ public_ip ]
- open_firewall:
- description:
- - Whether the firewall rule for public port should be created, while creating the new rule.
- - Use M(cs_firewall) for managing firewall rules.
- type: bool
- default: no
- cidr:
- description:
- - CIDR (full notation) to be used for firewall rule if required.
- type: str
- protocol:
- description:
- - The protocol to be used on the load balancer
- type: str
- project:
- description:
- - Name of the project the load balancer IP address is related to.
- type: str
- state:
- description:
- - State of the rule.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the rule is related to.
- type: str
- account:
- description:
- - Account the rule is related to.
- type: str
- zone:
- description:
- - Name of the zone in which the rule should be created.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- network:
- description:
- - Name of the network.
- type: str
- version_added: '2.9'
- vpc:
- description:
- - Name of the VPC.
- type: str
- version_added: '2.9'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a load balancer rule
- cs_loadbalancer_rule:
- name: balance_http
- public_ip: 1.2.3.4
- algorithm: leastconn
- public_port: 80
- private_port: 8080
- delegate_to: localhost
-
-- name: Update algorithm of an existing load balancer rule
- cs_loadbalancer_rule:
- name: balance_http
- public_ip: 1.2.3.4
- algorithm: roundrobin
- public_port: 80
- private_port: 8080
- delegate_to: localhost
-
-- name: Delete a load balancer rule
- cs_loadbalancer_rule:
- name: balance_http
- public_ip: 1.2.3.4
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the rule.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-zone:
- description: Name of zone the rule is related to.
- returned: success
- type: str
- sample: ch-gva-2
-project:
- description: Name of project the rule is related to.
- returned: success
- type: str
- sample: Production
-account:
- description: Account the rule is related to.
- returned: success
- type: str
- sample: example account
-domain:
- description: Domain the rule is related to.
- returned: success
- type: str
- sample: example domain
-algorithm:
- description: Load balancer algorithm used.
- returned: success
- type: str
- sample: source
-cidr:
- description: CIDR to forward traffic from.
- returned: success
- type: str
- sample: 0.0.0.0/0
-name:
- description: Name of the rule.
- returned: success
- type: str
- sample: http-lb
-description:
- description: Description of the rule.
- returned: success
- type: str
- sample: http load balancer rule
-protocol:
- description: Protocol of the rule.
- returned: success
- type: str
- sample: tcp
-public_port:
- description: Public port.
- returned: success
- type: int
- sample: 80
-private_port:
- description: Private IP address.
- returned: success
- type: int
- sample: 80
-public_ip:
- description: Public IP address.
- returned: success
- type: str
- sample: 1.2.3.4
-tags:
- description: List of resource tags associated with the rule.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-state:
- description: State of the rule.
- returned: success
- type: str
- sample: Add
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackLBRule(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackLBRule, self).__init__(module)
- self.returns = {
- 'publicip': 'public_ip',
- 'algorithm': 'algorithm',
- 'cidrlist': 'cidr',
- 'protocol': 'protocol',
- }
- # these values will be casted to int
- self.returns_to_int = {
- 'publicport': 'public_port',
- 'privateport': 'private_port',
- }
-
- def get_rule(self, **kwargs):
- rules = self.query_api('listLoadBalancerRules', **kwargs)
- if rules:
- return rules['loadbalancerrule'][0]
-
- def _get_common_args(self):
- return {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id') if self.module.params.get('zone') else None,
- 'publicipid': self.get_ip_address(key='id'),
- 'name': self.module.params.get('name'),
- }
-
- def present_lb_rule(self):
- required_params = [
- 'algorithm',
- 'private_port',
- 'public_port',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- args = self._get_common_args()
- rule = self.get_rule(**args)
- if rule:
- rule = self._update_lb_rule(rule)
- else:
- rule = self._create_lb_rule(rule)
-
- if rule:
- rule = self.ensure_tags(resource=rule, resource_type='LoadBalancer')
- return rule
-
- def _create_lb_rule(self, rule):
- self.result['changed'] = True
- if not self.module.check_mode:
- args = self._get_common_args()
- args.update({
- 'algorithm': self.module.params.get('algorithm'),
- 'privateport': self.module.params.get('private_port'),
- 'publicport': self.module.params.get('public_port'),
- 'cidrlist': self.module.params.get('cidr'),
- 'description': self.module.params.get('description'),
- 'protocol': self.module.params.get('protocol'),
- 'networkid': self.get_network(key='id'),
- })
- res = self.query_api('createLoadBalancerRule', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- rule = self.poll_job(res, 'loadbalancer')
- return rule
-
- def _update_lb_rule(self, rule):
- args = {
- 'id': rule['id'],
- 'algorithm': self.module.params.get('algorithm'),
- 'description': self.module.params.get('description'),
- }
- if self.has_changed(args, rule):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateLoadBalancerRule', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- rule = self.poll_job(res, 'loadbalancer')
- return rule
-
- def absent_lb_rule(self):
- args = self._get_common_args()
- rule = self.get_rule(**args)
- if rule:
- self.result['changed'] = True
- if rule and not self.module.check_mode:
- res = self.query_api('deleteLoadBalancerRule', id=rule['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'loadbalancer')
- return rule
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- description=dict(),
- algorithm=dict(choices=['source', 'roundrobin', 'leastconn'], default='source'),
- private_port=dict(type='int'),
- public_port=dict(type='int'),
- protocol=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- ip_address=dict(required=True, aliases=['public_ip']),
- cidr=dict(),
- project=dict(),
- open_firewall=dict(type='bool', default=False),
- tags=dict(type='list', aliases=['tag']),
- zone=dict(),
- domain=dict(),
- account=dict(),
- vpc=dict(),
- network=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_lb_rule = AnsibleCloudStackLBRule(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- rule = acs_lb_rule.absent_lb_rule()
- else:
- rule = acs_lb_rule.present_lb_rule()
-
- result = acs_lb_rule.get_result(rule)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule_member.py b/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule_member.py
deleted file mode 100644
index 8a9249eecc..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_loadbalancer_rule_member.py
+++ /dev/null
@@ -1,349 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2015, Darren Worrall <darren@iweb.co.uk>
-# Copyright (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_loadbalancer_rule_member
-short_description: Manages load balancer rule members on Apache CloudStack based clouds.
-description:
- - Add and remove load balancer rule members.
-version_added: '2.0'
-author:
- - Darren Worrall (@dazworrall)
- - René Moser (@resmo)
-options:
- name:
- description:
- - The name of the load balancer rule.
- type: str
- required: true
- ip_address:
- description:
- - Public IP address from where the network traffic will be load balanced from.
- - Only needed to find the rule if I(name) is not unique.
- type: str
- aliases: [ public_ip ]
- vms:
- description:
- - List of VMs to assign to or remove from the rule.
- type: list
- required: true
- aliases: [ vm ]
- state:
- description:
- - Should the VMs be present or absent from the rule.
- type: str
- default: present
- choices: [ present, absent ]
- project:
- description:
- - Name of the project the firewall rule is related to.
- type: str
- domain:
- description:
- - Domain the rule is related to.
- type: str
- account:
- description:
- - Account the rule is related to.
- type: str
- zone:
- description:
- - Name of the zone in which the rule should be located.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Add VMs to an existing load balancer
- cs_loadbalancer_rule_member:
- name: balance_http
- vms:
- - web01
- - web02
- delegate_to: localhost
-
-- name: Remove a VM from an existing load balancer
- cs_loadbalancer_rule_member:
- name: balance_http
- vms:
- - web01
- - web02
- state: absent
- delegate_to: localhost
-
-# Rolling upgrade of hosts
-- hosts: webservers
- serial: 1
- pre_tasks:
- - name: Remove from load balancer
- cs_loadbalancer_rule_member:
- name: balance_http
- vm: "{{ ansible_hostname }}"
- state: absent
- delegate_to: localhost
- tasks:
- # Perform update
- post_tasks:
- - name: Add to load balancer
- cs_loadbalancer_rule_member:
- name: balance_http
- vm: "{{ ansible_hostname }}"
- state: present
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the rule.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-zone:
- description: Name of zone the rule is related to.
- returned: success
- type: str
- sample: ch-gva-2
-project:
- description: Name of project the rule is related to.
- returned: success
- type: str
- sample: Production
-account:
- description: Account the rule is related to.
- returned: success
- type: str
- sample: example account
-domain:
- description: Domain the rule is related to.
- returned: success
- type: str
- sample: example domain
-algorithm:
- description: Load balancer algorithm used.
- returned: success
- type: str
- sample: source
-cidr:
- description: CIDR to forward traffic from.
- returned: success
- type: str
- sample: 0.0.0.0/0
-name:
- description: Name of the rule.
- returned: success
- type: str
- sample: http-lb
-description:
- description: Description of the rule.
- returned: success
- type: str
- sample: http load balancer rule
-protocol:
- description: Protocol of the rule.
- returned: success
- type: str
- sample: tcp
-public_port:
- description: Public port.
- returned: success
- type: int
- sample: 80
-private_port:
- description: Private IP address.
- returned: success
- type: int
- sample: 80
-public_ip:
- description: Public IP address.
- returned: success
- type: str
- sample: 1.2.3.4
-vms:
- description: Rule members.
- returned: success
- type: list
- sample: '[ "web01", "web02" ]'
-tags:
- description: List of resource tags associated with the rule.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-state:
- description: State of the rule.
- returned: success
- type: str
- sample: Add
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackLBRuleMember(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackLBRuleMember, self).__init__(module)
- self.returns = {
- 'publicip': 'public_ip',
- 'algorithm': 'algorithm',
- 'cidrlist': 'cidr',
- 'protocol': 'protocol',
- }
- # these values will be casted to int
- self.returns_to_int = {
- 'publicport': 'public_port',
- 'privateport': 'private_port',
- }
-
- def get_rule(self):
- args = self._get_common_args()
- args.update({
- 'name': self.module.params.get('name'),
- 'zoneid': self.get_zone(key='id') if self.module.params.get('zone') else None,
- })
- if self.module.params.get('ip_address'):
- args['publicipid'] = self.get_ip_address(key='id')
-
- rules = self.query_api('listLoadBalancerRules', **args)
- if rules:
- if len(rules['loadbalancerrule']) > 1:
- self.module.fail_json(msg="More than one rule having name %s. Please pass 'ip_address' as well." % args['name'])
- return rules['loadbalancerrule'][0]
- return None
-
- def _get_common_args(self):
- return {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- }
-
- def _get_members_of_rule(self, rule):
- res = self.query_api('listLoadBalancerRuleInstances', id=rule['id'])
- return res.get('loadbalancerruleinstance', [])
-
- def _ensure_members(self, operation):
- if operation not in ['add', 'remove']:
- self.module.fail_json(msg="Bad operation: %s" % operation)
-
- rule = self.get_rule()
- if not rule:
- self.module.fail_json(msg="Unknown rule: %s" % self.module.params.get('name'))
-
- existing = {}
- for vm in self._get_members_of_rule(rule=rule):
- existing[vm['name']] = vm['id']
-
- wanted_names = self.module.params.get('vms')
-
- if operation == 'add':
- cs_func = 'assignToLoadBalancerRule'
- to_change = set(wanted_names) - set(existing.keys())
- else:
- cs_func = 'removeFromLoadBalancerRule'
- to_change = set(wanted_names) & set(existing.keys())
-
- if not to_change:
- return rule
-
- args = self._get_common_args()
- args['fetch_list'] = True
- vms = self.query_api('listVirtualMachines', **args)
- to_change_ids = []
- for name in to_change:
- for vm in vms:
- if vm['name'] == name:
- to_change_ids.append(vm['id'])
- break
- else:
- self.module.fail_json(msg="Unknown VM: %s" % name)
-
- if to_change_ids:
- self.result['changed'] = True
-
- if to_change_ids and not self.module.check_mode:
- res = self.query_api(
- cs_func,
- id=rule['id'],
- virtualmachineids=to_change_ids,
- )
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res)
- rule = self.get_rule()
- return rule
-
- def add_members(self):
- return self._ensure_members('add')
-
- def remove_members(self):
- return self._ensure_members('remove')
-
- def get_result(self, rule):
- super(AnsibleCloudStackLBRuleMember, self).get_result(rule)
- if rule:
- self.result['vms'] = []
- for vm in self._get_members_of_rule(rule=rule):
- self.result['vms'].append(vm['name'])
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- ip_address=dict(aliases=['public_ip']),
- vms=dict(required=True, aliases=['vm'], type='list'),
- state=dict(choices=['present', 'absent'], default='present'),
- zone=dict(),
- domain=dict(),
- project=dict(),
- account=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_lb_rule_member = AnsibleCloudStackLBRuleMember(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- rule = acs_lb_rule_member.remove_members()
- else:
- rule = acs_lb_rule_member.add_members()
-
- result = acs_lb_rule_member.get_result(rule)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_network.py b/lib/ansible/modules/cloud/cloudstack/cs_network.py
deleted file mode 100644
index 8231881e24..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_network.py
+++ /dev/null
@@ -1,644 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_network
-short_description: Manages networks on Apache CloudStack based clouds.
-description:
- - Create, update, restart and delete networks.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name (case sensitive) of the network.
- type: str
- required: true
- display_text:
- description:
- - Display text of the network.
- - If not specified, I(name) will be used as I(display_text).
- type: str
- network_offering:
- description:
- - Name of the offering for the network.
- - Required if I(state=present).
- type: str
- start_ip:
- description:
- - The beginning IPv4 address of the network belongs to.
- - Only considered on create.
- type: str
- end_ip:
- description:
- - The ending IPv4 address of the network belongs to.
- - If not specified, value of I(start_ip) is used.
- - Only considered on create.
- type: str
- gateway:
- description:
- - The gateway of the network.
- - Required for shared networks and isolated networks when it belongs to a VPC.
- - Only considered on create.
- type: str
- netmask:
- description:
- - The netmask of the network.
- - Required for shared networks and isolated networks when it belongs to a VPC.
- - Only considered on create.
- type: str
- start_ipv6:
- description:
- - The beginning IPv6 address of the network belongs to.
- - Only considered on create.
- type: str
- end_ipv6:
- description:
- - The ending IPv6 address of the network belongs to.
- - If not specified, value of I(start_ipv6) is used.
- - Only considered on create.
- type: str
- cidr_ipv6:
- description:
- - CIDR of IPv6 network, must be at least /64.
- - Only considered on create.
- type: str
- gateway_ipv6:
- description:
- - The gateway of the IPv6 network.
- - Required for shared networks.
- - Only considered on create.
- type: str
- vlan:
- description:
- - The ID or VID of the network.
- type: str
- vpc:
- description:
- - Name of the VPC of the network.
- type: str
- isolated_pvlan:
- description:
- - The isolated private VLAN for this network.
- type: str
- clean_up:
- description:
- - Cleanup old network elements.
- - Only considered on I(state=restarted).
- default: no
- type: bool
- acl_type:
- description:
- - Access control type for the network.
- - If not specified, Cloudstack will default to C(account) for isolated networks
- - and C(domain) for shared networks.
- - Only considered on create.
- type: str
- choices: [ account, domain ]
- acl:
- description:
- - The name of the access control list for the VPC network tier.
- type: str
- version_added: '2.5'
- subdomain_access:
- description:
- - Defines whether to allow subdomains to use networks dedicated to their parent domain(s).
- - Should be used with I(acl_type=domain).
- - Only considered on create.
- type: bool
- version_added: '2.5'
- network_domain:
- description:
- - The network domain.
- type: str
- state:
- description:
- - State of the network.
- type: str
- default: present
- choices: [ present, absent, restarted ]
- zone:
- description:
- - Name of the zone in which the network should be deployed.
- - If not set, default zone is used.
- type: str
- project:
- description:
- - Name of the project the network to be deployed in.
- type: str
- domain:
- description:
- - Domain the network is related to.
- type: str
- account:
- description:
- - Account the network is related to.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.9'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a network
- cs_network:
- name: my network
- zone: gva-01
- network_offering: DefaultIsolatedNetworkOfferingWithSourceNatService
- network_domain: example.com
- delegate_to: localhost
-
-- name: Create a VPC tier
- cs_network:
- name: my VPC tier 1
- zone: gva-01
- vpc: my VPC
- network_offering: DefaultIsolatedNetworkOfferingForVpcNetworks
- gateway: 10.43.0.1
- netmask: 255.255.255.0
- acl: my web acl
- delegate_to: localhost
-
-- name: Update a network
- cs_network:
- name: my network
- display_text: network of domain example.local
- network_domain: example.local
- delegate_to: localhost
-
-- name: Restart a network with clean up
- cs_network:
- name: my network
- clean_up: yes
- state: restarted
- delegate_to: localhost
-
-- name: Remove a network
- cs_network:
- name: my network
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the network.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the network.
- returned: success
- type: str
- sample: web project
-display_text:
- description: Display text of the network.
- returned: success
- type: str
- sample: web project
-dns1:
- description: IP address of the 1st nameserver.
- returned: success
- type: str
- sample: 1.2.3.4
-dns2:
- description: IP address of the 2nd nameserver.
- returned: success
- type: str
- sample: 1.2.3.4
-cidr:
- description: IPv4 network CIDR.
- returned: success
- type: str
- sample: 10.101.64.0/24
-gateway:
- description: IPv4 gateway.
- returned: success
- type: str
- sample: 10.101.64.1
-netmask:
- description: IPv4 netmask.
- returned: success
- type: str
- sample: 255.255.255.0
-cidr_ipv6:
- description: IPv6 network CIDR.
- returned: if available
- type: str
- sample: 2001:db8::/64
-gateway_ipv6:
- description: IPv6 gateway.
- returned: if available
- type: str
- sample: 2001:db8::1
-zone:
- description: Name of zone.
- returned: success
- type: str
- sample: ch-gva-2
-domain:
- description: Domain the network is related to.
- returned: success
- type: str
- sample: ROOT
-account:
- description: Account the network is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project.
- returned: success
- type: str
- sample: Production
-tags:
- description: List of resource tags associated with the network.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-acl_type:
- description: Access type of the network (Domain, Account).
- returned: success
- type: str
- sample: Account
-acl:
- description: Name of the access control list for the VPC network tier.
- returned: success
- type: str
- sample: My ACL
- version_added: '2.5'
-acl_id:
- description: ID of the access control list for the VPC network tier.
- returned: success
- type: str
- sample: dfafcd55-0510-4b8c-b6c5-b8cedb4cfd88
- version_added: '2.5'
-broadcast_domain_type:
- description: Broadcast domain type of the network.
- returned: success
- type: str
- sample: Vlan
-type:
- description: Type of the network.
- returned: success
- type: str
- sample: Isolated
-traffic_type:
- description: Traffic type of the network.
- returned: success
- type: str
- sample: Guest
-state:
- description: State of the network (Allocated, Implemented, Setup).
- returned: success
- type: str
- sample: Allocated
-is_persistent:
- description: Whether the network is persistent or not.
- returned: success
- type: bool
- sample: false
-network_domain:
- description: The network domain
- returned: success
- type: str
- sample: example.local
-network_offering:
- description: The network offering name.
- returned: success
- type: str
- sample: DefaultIsolatedNetworkOfferingWithSourceNatService
-network_offering_display_text:
- description: The network offering display text.
- returned: success
- type: str
- sample: Offering for Isolated Vpc networks with Source Nat service enabled
- version_added: '2.5'
-network_offering_conserve_mode:
- description: Whether the network offering has IP conserve mode enabled or not.
- returned: success
- type: bool
- sample: false
- version_added: '2.5'
-network_offering_availability:
- description: The availability of the network offering the network is created from
- returned: success
- type: str
- sample: Optional
- version_added: '2.5'
-is_system:
- description: Whether the network is system related or not.
- returned: success
- type: bool
- sample: false
- version_added: '2.5'
-vpc:
- description: Name of the VPC.
- returned: if available
- type: str
- sample: My VPC
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackNetwork(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackNetwork, self).__init__(module)
- self.returns = {
- 'networkdomain': 'network_domain',
- 'networkofferingname': 'network_offering',
- 'networkofferingdisplaytext': 'network_offering_display_text',
- 'networkofferingconservemode': 'network_offering_conserve_mode',
- 'networkofferingavailability': 'network_offering_availability',
- 'aclid': 'acl_id',
- 'issystem': 'is_system',
- 'ispersistent': 'is_persistent',
- 'acltype': 'acl_type',
- 'type': 'type',
- 'traffictype': 'traffic_type',
- 'ip6gateway': 'gateway_ipv6',
- 'ip6cidr': 'cidr_ipv6',
- 'gateway': 'gateway',
- 'cidr': 'cidr',
- 'netmask': 'netmask',
- 'broadcastdomaintype': 'broadcast_domain_type',
- 'dns1': 'dns1',
- 'dns2': 'dns2',
- }
- self.network = None
-
- def get_network_acl(self, key=None, acl_id=None):
- if acl_id is not None:
- args = {
- 'id': acl_id,
- 'vpcid': self.get_vpc(key='id'),
- }
- else:
- acl_name = self.module.params.get('acl')
- if not acl_name:
- return
-
- args = {
- 'name': acl_name,
- 'vpcid': self.get_vpc(key='id'),
- }
- network_acls = self.query_api('listNetworkACLLists', **args)
- if network_acls:
- acl = network_acls['networkacllist'][0]
- return self._get_by_key(key, acl)
-
- def get_network_offering(self, key=None):
- network_offering = self.module.params.get('network_offering')
- if not network_offering:
- self.module.fail_json(msg="missing required arguments: network_offering")
-
- args = {
- 'zoneid': self.get_zone(key='id'),
- 'fetch_list': True,
- }
-
- network_offerings = self.query_api('listNetworkOfferings', **args)
- if network_offerings:
- for no in network_offerings:
- if network_offering in [no['name'], no['displaytext'], no['id']]:
- return self._get_by_key(key, no)
- self.module.fail_json(msg="Network offering '%s' not found" % network_offering)
-
- def _get_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'networkdomain': self.module.params.get('network_domain'),
- 'networkofferingid': self.get_network_offering(key='id')
- }
- return args
-
- def get_network(self, refresh=False):
- if not self.network or refresh:
- network = self.module.params.get('name')
- args = {
- 'zoneid': self.get_zone(key='id'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'vpcid': self.get_vpc(key='id'),
- 'fetch_list': True,
- }
- networks = self.query_api('listNetworks', **args)
- if networks:
- for n in networks:
- if network in [n['name'], n['displaytext'], n['id']]:
- self.network = n
- self.network['acl'] = self.get_network_acl(key='name', acl_id=n.get('aclid'))
- break
- return self.network
-
- def present_network(self):
- if self.module.params.get('acl') is not None and self.module.params.get('vpc') is None:
- self.module.fail_json(msg="Missing required params: vpc")
-
- network = self.get_network()
- if not network:
- network = self.create_network(network)
- else:
- network = self.update_network(network)
-
- if network:
- network = self.ensure_tags(resource=network, resource_type='Network')
-
- return network
-
- def update_network(self, network):
- args = self._get_args()
- args['id'] = network['id']
-
- if self.has_changed(args, network):
- self.result['changed'] = True
- if not self.module.check_mode:
- network = self.query_api('updateNetwork', **args)
-
- poll_async = self.module.params.get('poll_async')
- if network and poll_async:
- network = self.poll_job(network, 'network')
-
- # Skip ACL check if the network is not a VPC tier
- if network.get('aclid') != self.get_network_acl(key='id'):
- self.result['changed'] = True
- if not self.module.check_mode:
- args = {
- 'aclid': self.get_network_acl(key='id'),
- 'networkid': network['id'],
- }
- network = self.query_api('replaceNetworkACLList', **args)
- if self.module.params.get('poll_async'):
- self.poll_job(network, 'networkacllist')
- network = self.get_network(refresh=True)
- return network
-
- def create_network(self, network):
- self.result['changed'] = True
-
- args = self._get_args()
- args.update({
- 'acltype': self.module.params.get('acl_type'),
- 'aclid': self.get_network_acl(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'startip': self.module.params.get('start_ip'),
- 'endip': self.get_or_fallback('end_ip', 'start_ip'),
- 'netmask': self.module.params.get('netmask'),
- 'gateway': self.module.params.get('gateway'),
- 'startipv6': self.module.params.get('start_ipv6'),
- 'endipv6': self.get_or_fallback('end_ipv6', 'start_ipv6'),
- 'ip6cidr': self.module.params.get('cidr_ipv6'),
- 'ip6gateway': self.module.params.get('gateway_ipv6'),
- 'vlan': self.module.params.get('vlan'),
- 'isolatedpvlan': self.module.params.get('isolated_pvlan'),
- 'subdomainaccess': self.module.params.get('subdomain_access'),
- 'vpcid': self.get_vpc(key='id')
- })
-
- if not self.module.check_mode:
- res = self.query_api('createNetwork', **args)
-
- network = res['network']
- return network
-
- def restart_network(self):
- network = self.get_network()
-
- if not network:
- self.module.fail_json(msg="No network named '%s' found." % self.module.params('name'))
-
- # Restarting only available for these states
- if network['state'].lower() in ['implemented', 'setup']:
- self.result['changed'] = True
-
- args = {
- 'id': network['id'],
- 'cleanup': self.module.params.get('clean_up')
- }
-
- if not self.module.check_mode:
- network = self.query_api('restartNetwork', **args)
-
- poll_async = self.module.params.get('poll_async')
- if network and poll_async:
- network = self.poll_job(network, 'network')
- return network
-
- def absent_network(self):
- network = self.get_network()
- if network:
- self.result['changed'] = True
-
- args = {
- 'id': network['id']
- }
-
- if not self.module.check_mode:
- res = self.query_api('deleteNetwork', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- self.poll_job(res, 'network')
- return network
-
- def get_result(self, network):
- super(AnsibleCloudStackNetwork, self).get_result(network)
- if network:
- self.result['acl'] = self.get_network_acl(key='name', acl_id=network.get('aclid'))
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- network_offering=dict(),
- zone=dict(),
- start_ip=dict(),
- end_ip=dict(),
- gateway=dict(),
- netmask=dict(),
- start_ipv6=dict(),
- end_ipv6=dict(),
- cidr_ipv6=dict(),
- gateway_ipv6=dict(),
- vlan=dict(),
- vpc=dict(),
- isolated_pvlan=dict(),
- clean_up=dict(type='bool', default=False),
- network_domain=dict(),
- subdomain_access=dict(type='bool'),
- state=dict(choices=['present', 'absent', 'restarted'], default='present'),
- acl=dict(),
- acl_type=dict(choices=['account', 'domain']),
- project=dict(),
- domain=dict(),
- account=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
- required_together = cs_required_together()
- required_together.extend([
- ['netmask', 'gateway'],
- ])
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=required_together,
- supports_check_mode=True
- )
-
- acs_network = AnsibleCloudStackNetwork(module)
-
- state = module.params.get('state')
- if state == 'absent':
- network = acs_network.absent_network()
-
- elif state == 'restarted':
- network = acs_network.restart_network()
-
- else:
- network = acs_network.present_network()
-
- result = acs_network.get_result(network)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_network_acl.py b/lib/ansible/modules/cloud/cloudstack/cs_network_acl.py
deleted file mode 100644
index debb767741..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_network_acl.py
+++ /dev/null
@@ -1,201 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_network_acl
-short_description: Manages network access control lists (ACL) on Apache CloudStack based clouds.
-description:
- - Create and remove network ACLs.
-version_added: '2.4'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the network ACL.
- type: str
- required: true
- description:
- description:
- - Description of the network ACL.
- - If not set, identical to I(name).
- type: str
- vpc:
- description:
- - VPC the network ACL is related to.
- type: str
- required: true
- state:
- description:
- - State of the network ACL.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the network ACL rule is related to.
- type: str
- account:
- description:
- - Account the network ACL rule is related to.
- type: str
- project:
- description:
- - Name of the project the network ACL is related to.
- type: str
- zone:
- description:
- - Name of the zone the VPC is related to.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a network ACL
- cs_network_acl:
- name: Webserver ACL
- description: a more detailed description of the ACL
- vpc: customers
- delegate_to: localhost
-
-- name: remove a network ACL
- cs_network_acl:
- name: Webserver ACL
- vpc: customers
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-name:
- description: Name of the network ACL.
- returned: success
- type: str
- sample: customer acl
-description:
- description: Description of the network ACL.
- returned: success
- type: str
- sample: Example description of a network ACL
-vpc:
- description: VPC of the network ACL.
- returned: success
- type: str
- sample: customer vpc
-zone:
- description: Zone the VPC is related to.
- returned: success
- type: str
- sample: ch-gva-2
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackNetworkAcl(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackNetworkAcl, self).__init__(module)
-
- def get_network_acl(self):
- args = {
- 'name': self.module.params.get('name'),
- 'vpcid': self.get_vpc(key='id'),
- }
- network_acls = self.query_api('listNetworkACLLists', **args)
- if network_acls:
- return network_acls['networkacllist'][0]
- return None
-
- def present_network_acl(self):
- network_acl = self.get_network_acl()
- if not network_acl:
- self.result['changed'] = True
- args = {
- 'name': self.module.params.get('name'),
- 'description': self.get_or_fallback('description', 'name'),
- 'vpcid': self.get_vpc(key='id')
- }
- if not self.module.check_mode:
- res = self.query_api('createNetworkACLList', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- network_acl = self.poll_job(res, 'networkacllist')
-
- return network_acl
-
- def absent_network_acl(self):
- network_acl = self.get_network_acl()
- if network_acl:
- self.result['changed'] = True
- args = {
- 'id': network_acl['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('deleteNetworkACLList', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'networkacllist')
-
- return network_acl
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- description=dict(),
- vpc=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_network_acl = AnsibleCloudStackNetworkAcl(module)
-
- state = module.params.get('state')
- if state == 'absent':
- network_acl = acs_network_acl.absent_network_acl()
- else:
- network_acl = acs_network_acl.present_network_acl()
-
- result = acs_network_acl.get_result(network_acl)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_network_acl_rule.py b/lib/ansible/modules/cloud/cloudstack/cs_network_acl_rule.py
deleted file mode 100644
index 2300e80dc2..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_network_acl_rule.py
+++ /dev/null
@@ -1,461 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_network_acl_rule
-short_description: Manages network access control list (ACL) rules on Apache CloudStack based clouds.
-description:
- - Add, update and remove network ACL rules.
-version_added: '2.4'
-author: René Moser (@resmo)
-options:
- network_acl:
- description:
- - Name of the network ACL.
- type: str
- required: true
- aliases: [ acl ]
- cidrs:
- description:
- - CIDRs of the rule.
- type: list
- default: [ 0.0.0.0/0 ]
- aliases: [ cidr ]
- rule_position:
- description:
- - The position of the network ACL rule.
- type: int
- required: true
- aliases: [ number ]
- protocol:
- description:
- - Protocol of the rule
- choices: [ tcp, udp, icmp, all, by_number ]
- type: str
- default: tcp
- protocol_number:
- description:
- - Protocol number from 1 to 256 required if I(protocol=by_number).
- type: int
- start_port:
- description:
- - Start port for this rule.
- - Considered if I(protocol=tcp) or I(protocol=udp).
- type: int
- aliases: [ port ]
- end_port:
- description:
- - End port for this rule.
- - Considered if I(protocol=tcp) or I(protocol=udp).
- - If not specified, equal I(start_port).
- type: int
- icmp_type:
- description:
- - Type of the icmp message being sent.
- - Considered if I(protocol=icmp).
- type: int
- icmp_code:
- description:
- - Error code for this icmp message.
- - Considered if I(protocol=icmp).
- type: int
- vpc:
- description:
- - VPC the network ACL is related to.
- type: str
- required: true
- traffic_type:
- description:
- - Traffic type of the rule.
- type: str
- choices: [ ingress, egress ]
- default: ingress
- aliases: [ type ]
- action_policy:
- description:
- - Action policy of the rule.
- type: str
- choices: [ allow, deny ]
- default: allow
- aliases: [ action ]
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "If you want to delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- domain:
- description:
- - Domain the VPC is related to.
- type: str
- account:
- description:
- - Account the VPC is related to.
- type: str
- project:
- description:
- - Name of the project the VPC is related to.
- type: str
- zone:
- description:
- - Name of the zone the VPC related to.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the network ACL rule.
- type: str
- default: present
- choices: [ present, absent ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a network ACL rule, allow port 80 ingress
- cs_network_acl_rule:
- network_acl: web
- rule_position: 1
- vpc: my vpc
- traffic_type: ingress
- action_policy: allow
- port: 80
- cidr: 0.0.0.0/0
- delegate_to: localhost
-
-- name: create a network ACL rule, deny port range 8000-9000 ingress for 10.20.0.0/16 and 10.22.0.0/16
- cs_network_acl_rule:
- network_acl: web
- rule_position: 1
- vpc: my vpc
- traffic_type: ingress
- action_policy: deny
- start_port: 8000
- end_port: 9000
- cidrs:
- - 10.20.0.0/16
- - 10.22.0.0/16
- delegate_to: localhost
-
-- name: remove a network ACL rule
- cs_network_acl_rule:
- network_acl: web
- rule_position: 1
- vpc: my vpc
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-network_acl:
- description: Name of the network ACL.
- returned: success
- type: str
- sample: customer acl
-cidr:
- description: CIDR of the network ACL rule.
- returned: success
- type: str
- sample: 0.0.0.0/0
-cidrs:
- description: CIDRs of the network ACL rule.
- returned: success
- type: list
- sample: [ 0.0.0.0/0 ]
- version_added: '2.9'
-rule_position:
- description: Position of the network ACL rule.
- returned: success
- type: int
- sample: 1
-action_policy:
- description: Action policy of the network ACL rule.
- returned: success
- type: str
- sample: deny
-traffic_type:
- description: Traffic type of the network ACL rule.
- returned: success
- type: str
- sample: ingress
-protocol:
- description: Protocol of the network ACL rule.
- returned: success
- type: str
- sample: tcp
-protocol_number:
- description: Protocol number in case protocol is by number.
- returned: success
- type: int
- sample: 8
-start_port:
- description: Start port of the network ACL rule.
- returned: success
- type: int
- sample: 80
-end_port:
- description: End port of the network ACL rule.
- returned: success
- type: int
- sample: 80
-icmp_code:
- description: ICMP code of the network ACL rule.
- returned: success
- type: int
- sample: 8
-icmp_type:
- description: ICMP type of the network ACL rule.
- returned: success
- type: int
- sample: 0
-state:
- description: State of the network ACL rule.
- returned: success
- type: str
- sample: Active
-vpc:
- description: VPC of the network ACL.
- returned: success
- type: str
- sample: customer vpc
-tags:
- description: List of resource tags associated with the network ACL rule.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-domain:
- description: Domain the network ACL rule is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the network ACL rule is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the network ACL rule is related to.
- returned: success
- type: str
- sample: Production
-zone:
- description: Zone the VPC is related to.
- returned: success
- type: str
- sample: ch-gva-2
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackNetworkAclRule(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackNetworkAclRule, self).__init__(module)
- self.returns = {
- 'cidrlist': 'cidr',
- 'action': 'action_policy',
- 'protocol': 'protocol',
- 'icmpcode': 'icmp_code',
- 'icmptype': 'icmp_type',
- 'number': 'rule_position',
- 'traffictype': 'traffic_type',
- }
- # these values will be casted to int
- self.returns_to_int = {
- 'startport': 'start_port',
- 'endport': 'end_port',
- }
-
- def get_network_acl_rule(self):
- args = {
- 'aclid': self.get_network_acl(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- }
- network_acl_rules = self.query_api('listNetworkACLs', **args)
- for acl_rule in network_acl_rules.get('networkacl', []):
- if acl_rule['number'] == self.module.params.get('rule_position'):
- return acl_rule
- return None
-
- def present_network_acl_rule(self):
- network_acl_rule = self.get_network_acl_rule()
-
- protocol = self.module.params.get('protocol')
- start_port = self.module.params.get('start_port')
- end_port = self.get_or_fallback('end_port', 'start_port')
- icmp_type = self.module.params.get('icmp_type')
- icmp_code = self.module.params.get('icmp_code')
-
- if protocol in ['tcp', 'udp'] and (start_port is None or end_port is None):
- self.module.fail_json(msg="protocol is %s but the following are missing: start_port, end_port" % protocol)
-
- elif protocol == 'icmp' and (icmp_type is None or icmp_code is None):
- self.module.fail_json(msg="protocol is icmp but the following are missing: icmp_type, icmp_code")
-
- elif protocol == 'by_number' and self.module.params.get('protocol_number') is None:
- self.module.fail_json(msg="protocol is by_number but the following are missing: protocol_number")
-
- if not network_acl_rule:
- network_acl_rule = self._create_network_acl_rule(network_acl_rule)
- else:
- network_acl_rule = self._update_network_acl_rule(network_acl_rule)
-
- if network_acl_rule:
- network_acl_rule = self.ensure_tags(resource=network_acl_rule, resource_type='NetworkACL')
- return network_acl_rule
-
- def absent_network_acl_rule(self):
- network_acl_rule = self.get_network_acl_rule()
- if network_acl_rule:
- self.result['changed'] = True
- args = {
- 'id': network_acl_rule['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('deleteNetworkACL', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'networkacl')
-
- return network_acl_rule
-
- def _create_network_acl_rule(self, network_acl_rule):
- self.result['changed'] = True
- protocol = self.module.params.get('protocol')
- args = {
- 'aclid': self.get_network_acl(key='id'),
- 'action': self.module.params.get('action_policy'),
- 'protocol': protocol if protocol != 'by_number' else self.module.params.get('protocol_number'),
- 'startport': self.module.params.get('start_port'),
- 'endport': self.get_or_fallback('end_port', 'start_port'),
- 'number': self.module.params.get('rule_position'),
- 'icmpcode': self.module.params.get('icmp_code'),
- 'icmptype': self.module.params.get('icmp_type'),
- 'traffictype': self.module.params.get('traffic_type'),
- 'cidrlist': self.module.params.get('cidrs'),
- }
- if not self.module.check_mode:
- res = self.query_api('createNetworkACL', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- network_acl_rule = self.poll_job(res, 'networkacl')
-
- return network_acl_rule
-
- def _update_network_acl_rule(self, network_acl_rule):
- protocol = self.module.params.get('protocol')
- args = {
- 'id': network_acl_rule['id'],
- 'action': self.module.params.get('action_policy'),
- 'protocol': protocol if protocol != 'by_number' else str(self.module.params.get('protocol_number')),
- 'startport': self.module.params.get('start_port'),
- 'endport': self.get_or_fallback('end_port', 'start_port'),
- 'icmpcode': self.module.params.get('icmp_code'),
- 'icmptype': self.module.params.get('icmp_type'),
- 'traffictype': self.module.params.get('traffic_type'),
- 'cidrlist': ",".join(self.module.params.get('cidrs')),
- }
- if self.has_changed(args, network_acl_rule):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateNetworkACLItem', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- network_acl_rule = self.poll_job(res, 'networkacl')
-
- return network_acl_rule
-
- def get_result(self, network_acl_rule):
- super(AnsibleCloudStackNetworkAclRule, self).get_result(network_acl_rule)
- if network_acl_rule:
- if 'cidrlist' in network_acl_rule:
- self.result['cidrs'] = network_acl_rule['cidrlist'].split(',') or [network_acl_rule['cidrlist']]
- if network_acl_rule['protocol'] not in ['tcp', 'udp', 'icmp', 'all']:
- self.result['protocol_number'] = int(network_acl_rule['protocol'])
- self.result['protocol'] = 'by_number'
- self.result['action_policy'] = self.result['action_policy'].lower()
- self.result['traffic_type'] = self.result['traffic_type'].lower()
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- network_acl=dict(required=True, aliases=['acl']),
- rule_position=dict(required=True, type='int', aliases=['number']),
- vpc=dict(required=True),
- cidrs=dict(type='list', default=['0.0.0.0/0'], aliases=['cidr']),
- protocol=dict(choices=['tcp', 'udp', 'icmp', 'all', 'by_number'], default='tcp'),
- protocol_number=dict(type='int'),
- traffic_type=dict(choices=['ingress', 'egress'], aliases=['type'], default='ingress'),
- action_policy=dict(choices=['allow', 'deny'], aliases=['action'], default='allow'),
- icmp_type=dict(type='int'),
- icmp_code=dict(type='int'),
- start_port=dict(type='int', aliases=['port']),
- end_port=dict(type='int'),
- state=dict(choices=['present', 'absent'], default='present'),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- tags=dict(type='list', aliases=['tag']),
- poll_async=dict(type='bool', default=True),
- ))
-
- required_together = cs_required_together()
- required_together.extend([
- ['icmp_type', 'icmp_code'],
- ])
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['icmp_type', 'start_port'],
- ['icmp_type', 'end_port'],
- ),
- supports_check_mode=True
- )
-
- acs_network_acl_rule = AnsibleCloudStackNetworkAclRule(module)
-
- state = module.params.get('state')
- if state == 'absent':
- network_acl_rule = acs_network_acl_rule.absent_network_acl_rule()
- else:
- network_acl_rule = acs_network_acl_rule.present_network_acl_rule()
-
- result = acs_network_acl_rule.get_result(network_acl_rule)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_network_offering.py b/lib/ansible/modules/cloud/cloudstack/cs_network_offering.py
deleted file mode 100644
index 9677ead4c7..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_network_offering.py
+++ /dev/null
@@ -1,425 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, David Passante (@dpassante)
-# Copyright (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_network_offering
-short_description: Manages network offerings on Apache CloudStack based clouds.
-description:
- - Create, update, enable, disable and remove network offerings.
-version_added: '2.5'
-author: David Passante (@dpassante)
-options:
- state:
- description:
- - State of the network offering.
- type: str
- choices: [ enabled, present, disabled, absent]
- default: present
- display_text:
- description:
- - Display text of the network offerings.
- type: str
- guest_ip_type:
- description:
- - Guest type of the network offering.
- type: str
- choices: [ Shared, Isolated ]
- name:
- description:
- - The name of the network offering.
- type: str
- required: true
- supported_services:
- description:
- - Services supported by the network offering.
- - A list of one or more items from the choice list.
- type: list
- choices: [ Dns, PortForwarding, Dhcp, SourceNat, UserData, Firewall, StaticNat, Vpn, Lb ]
- aliases: [ supported_service ]
- traffic_type:
- description:
- - The traffic type for the network offering.
- type: str
- default: Guest
- availability:
- description:
- - The availability of network offering. Default value is Optional
- type: str
- conserve_mode:
- description:
- - Whether the network offering has IP conserve mode enabled.
- type: bool
- details:
- description:
- - Network offering details in key/value pairs.
- - with service provider as a value
- type: list
- egress_default_policy:
- description:
- - Whether the default egress policy is allow or to deny.
- type: str
- choices: [ allow, deny ]
- persistent:
- description:
- - True if network offering supports persistent networks
- - defaulted to false if not specified
- type: bool
- keepalive_enabled:
- description:
- - If true keepalive will be turned on in the loadbalancer.
- - At the time of writing this has only an effect on haproxy.
- - the mode http and httpclose options are unset in the haproxy conf file.
- type: bool
- max_connections:
- description:
- - Maximum number of concurrent connections supported by the network offering.
- type: int
- network_rate:
- description:
- - Data transfer rate in megabits per second allowed.
- type: int
- service_capabilities:
- description:
- - Desired service capabilities as part of network offering.
- type: list
- aliases: [ service_capability ]
- service_offering:
- description:
- - The service offering name or ID used by virtual router provider.
- type: str
- service_providers:
- description:
- - Provider to service mapping.
- - If not specified, the provider for the service will be mapped to the default provider on the physical network.
- type: list
- aliases: [ service_provider ]
- specify_ip_ranges:
- description:
- - Whether the network offering supports specifying IP ranges.
- - Defaulted to C(no) by the API if not specified.
- type: bool
- specify_vlan:
- description:
- - Whether the network offering supports vlans or not.
- type: bool
- for_vpc:
- description:
- - Whether the offering is meant to be used for VPC or not.
- type: bool
- version_added: '2.8'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a network offering and enable it
- cs_network_offering:
- name: my_network_offering
- display_text: network offering description
- state: enabled
- guest_ip_type: Isolated
- supported_services: [ Dns, PortForwarding, Dhcp, SourceNat, UserData, Firewall, StaticNat, Vpn, Lb ]
- service_providers:
- - { service: 'dns', provider: 'virtualrouter' }
- - { service: 'dhcp', provider: 'virtualrouter' }
- delegate_to: localhost
-
-
-- name: Remove a network offering
- cs_network_offering:
- name: my_network_offering
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the network offering.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: The name of the network offering.
- returned: success
- type: str
- sample: MyCustomNetworkOffering
-display_text:
- description: The display text of the network offering.
- returned: success
- type: str
- sample: My network offering
-state:
- description: The state of the network offering.
- returned: success
- type: str
- sample: Enabled
-guest_ip_type:
- description: Guest type of the network offering.
- returned: success
- type: str
- sample: Isolated
-availability:
- description: The availability of network offering.
- returned: success
- type: str
- sample: Optional
-service_offering_id:
- description: The service offering ID.
- returned: success
- type: str
- sample: c5f7a5fc-43f8-11e5-a151-feff819cdc9f
-max_connections:
- description: The maximum number of concurrent connections to be handled by LB.
- returned: success
- type: int
- sample: 300
-network_rate:
- description: The network traffic transfer ate in Mbit/s.
- returned: success
- type: int
- sample: 200
-traffic_type:
- description: The traffic type.
- returned: success
- type: str
- sample: Guest
-egress_default_policy:
- description: Default egress policy.
- returned: success
- type: str
- sample: allow
-is_persistent:
- description: Whether persistent networks are supported or not.
- returned: success
- type: bool
- sample: false
-is_default:
- description: Whether network offering is the default offering or not.
- returned: success
- type: bool
- sample: false
-for_vpc:
- description: Whether the offering is meant to be used for VPC or not.
- returned: success
- type: bool
- sample: false
- version_added: '2.8'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackNetworkOffering(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackNetworkOffering, self).__init__(module)
- self.returns = {
- 'guestiptype': 'guest_ip_type',
- 'availability': 'availability',
- 'serviceofferingid': 'service_offering_id',
- 'networkrate': 'network_rate',
- 'maxconnections': 'max_connections',
- 'traffictype': 'traffic_type',
- 'isdefault': 'is_default',
- 'ispersistent': 'is_persistent',
- 'forvpc': 'for_vpc'
- }
- self.network_offering = None
-
- def get_service_offering_id(self):
- service_offering = self.module.params.get('service_offering')
- if not service_offering:
- return None
-
- args = {
- 'issystem': True
- }
-
- service_offerings = self.query_api('listServiceOfferings', **args)
- if service_offerings:
- for s in service_offerings['serviceoffering']:
- if service_offering in [s['name'], s['id']]:
- return s['id']
- self.fail_json(msg="Service offering '%s' not found" % service_offering)
-
- def get_network_offering(self):
- if self.network_offering:
- return self.network_offering
-
- args = {
- 'name': self.module.params.get('name'),
- 'guestiptype': self.module.params.get('guest_type'),
- }
- no = self.query_api('listNetworkOfferings', **args)
- if no:
- self.network_offering = no['networkoffering'][0]
-
- return self.network_offering
-
- def create_or_update(self):
- network_offering = self.get_network_offering()
-
- if not network_offering:
- network_offering = self.create_network_offering()
-
- return self.update_network_offering(network_offering=network_offering)
-
- def create_network_offering(self):
- network_offering = None
- self.result['changed'] = True
-
- args = {
- 'state': self.module.params.get('state'),
- 'displaytext': self.module.params.get('display_text'),
- 'guestiptype': self.module.params.get('guest_ip_type'),
- 'name': self.module.params.get('name'),
- 'supportedservices': self.module.params.get('supported_services'),
- 'traffictype': self.module.params.get('traffic_type'),
- 'availability': self.module.params.get('availability'),
- 'conservemode': self.module.params.get('conserve_mode'),
- 'details': self.module.params.get('details'),
- 'egressdefaultpolicy': self.module.params.get('egress_default_policy') == 'allow',
- 'ispersistent': self.module.params.get('persistent'),
- 'keepaliveenabled': self.module.params.get('keepalive_enabled'),
- 'maxconnections': self.module.params.get('max_connections'),
- 'networkrate': self.module.params.get('network_rate'),
- 'servicecapabilitylist': self.module.params.get('service_capabilities'),
- 'serviceofferingid': self.get_service_offering_id(),
- 'serviceproviderlist': self.module.params.get('service_providers'),
- 'specifyipranges': self.module.params.get('specify_ip_ranges'),
- 'specifyvlan': self.module.params.get('specify_vlan'),
- 'forvpc': self.module.params.get('for_vpc'),
- }
-
- required_params = [
- 'display_text',
- 'guest_ip_type',
- 'supported_services',
- 'service_providers',
- ]
-
- self.module.fail_on_missing_params(required_params=required_params)
-
- if not self.module.check_mode:
- res = self.query_api('createNetworkOffering', **args)
- network_offering = res['networkoffering']
-
- return network_offering
-
- def delete_network_offering(self):
- network_offering = self.get_network_offering()
-
- if network_offering:
- self.result['changed'] = True
- if not self.module.check_mode:
- self.query_api('deleteNetworkOffering', id=network_offering['id'])
-
- return network_offering
-
- def update_network_offering(self, network_offering):
- if not network_offering:
- return network_offering
-
- args = {
- 'id': network_offering['id'],
- 'state': self.module.params.get('state'),
- 'displaytext': self.module.params.get('display_text'),
- 'name': self.module.params.get('name'),
- 'availability': self.module.params.get('availability'),
- 'maxconnections': self.module.params.get('max_connections'),
- }
-
- if args['state'] in ['enabled', 'disabled']:
- args['state'] = args['state'].title()
- else:
- del args['state']
-
- if self.has_changed(args, network_offering):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateNetworkOffering', **args)
- network_offering = res['networkoffering']
-
- return network_offering
-
- def get_result(self, network_offering):
- super(AnsibleCloudStackNetworkOffering, self).get_result(network_offering)
- if network_offering:
- self.result['egress_default_policy'] = 'allow' if network_offering.get('egressdefaultpolicy') else 'deny'
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- state=dict(choices=['enabled', 'present', 'disabled', 'absent'], default='present'),
- display_text=dict(),
- guest_ip_type=dict(choices=['Shared', 'Isolated']),
- name=dict(required=True),
- supported_services=dict(type='list', aliases=['supported_service'], choices=[
- 'Dns',
- 'PortForwarding',
- 'Dhcp',
- 'SourceNat',
- 'UserData',
- 'Firewall',
- 'StaticNat',
- 'Vpn',
- 'Lb',
- ]),
- traffic_type=dict(default='Guest'),
- availability=dict(),
- conserve_mode=dict(type='bool'),
- details=dict(type='list'),
- egress_default_policy=dict(choices=['allow', 'deny']),
- persistent=dict(type='bool'),
- keepalive_enabled=dict(type='bool'),
- max_connections=dict(type='int'),
- network_rate=dict(type='int'),
- service_capabilities=dict(type='list', aliases=['service_capability']),
- service_offering=dict(),
- service_providers=dict(type='list', aliases=['service_provider']),
- specify_ip_ranges=dict(type='bool'),
- specify_vlan=dict(type='bool'),
- for_vpc=dict(type='bool'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_network_offering = AnsibleCloudStackNetworkOffering(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- network_offering = acs_network_offering.delete_network_offering()
- else:
- network_offering = acs_network_offering.create_or_update()
-
- result = acs_network_offering.get_result(network_offering)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_physical_network.py b/lib/ansible/modules/cloud/cloudstack/cs_physical_network.py
deleted file mode 100644
index a7b2e05a68..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_physical_network.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Netservers Ltd. <support@netservers.co.uk>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_physical_network
-short_description: Manages physical networks on Apache CloudStack based clouds.
-description:
- - Create, update and remove networks.
- - Enabled and disabled Network Service Providers
- - Enables Internal LoadBalancer and VPC/VirtualRouter elements as required
-version_added: "2.8"
-author:
- - Netservers Ltd. (@netservers)
- - Patryk Cichy (@PatTheSilent)
-options:
- name:
- description:
- - Name of the physical network.
- required: true
- aliases:
- - physical_network
- type: str
- zone:
- description:
- - Name of the zone in which the network belongs.
- - If not set, default zone is used.
- type: str
- broadcast_domain_range:
- description:
- - broadcast domain range for the physical network[Pod or Zone].
- choices: [ POD, ZONE ]
- type: str
- domain:
- description:
- - Domain the network is owned by.
- type: str
- isolation_method:
- description:
- - Isolation method for the physical network.
- choices: [ VLAN, GRE, L3 ]
- type: str
- network_speed:
- description:
- - The speed for the physical network.
- choices: [1G, 10G]
- type: str
- tags:
- description:
- - A tag to identify this network.
- - Physical networks support only one tag.
- - To remove an existing tag pass an empty string.
- aliases:
- - tag
- type: str
- vlan:
- description:
- - The VLAN/VNI Ranges of the physical network.
- type: str
- nsps_enabled:
- description:
- - List of Network Service Providers to enable.
- type: list
- nsps_disabled:
- description:
- - List of Network Service Providers to disable.
- type: list
- state:
- description:
- - State of the physical network.
- default: present
- type: str
- choices: [ present, absent, disabled, enabled ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a network is present
- cs_physical_network:
- name: net01
- zone: zone01
- isolation_method: VLAN
- broadcast_domain_range: ZONE
- delegate_to: localhost
-
-- name: Set a tag on a network
- cs_physical_network:
- name: net01
- tag: overlay
- delegate_to: localhost
-
-- name: Remove tag on a network
- cs_physical_network:
- name: net01
- tag: ""
- delegate_to: localhost
-
-- name: Ensure a network is enabled with specific nsps enabled
- cs_physical_network:
- name: net01
- zone: zone01
- isolation_method: VLAN
- vlan: 100-200,300-400
- broadcast_domain_range: ZONE
- state: enabled
- nsps_enabled:
- - virtualrouter
- - internallbvm
- - vpcvirtualrouter
- delegate_to: localhost
-
-- name: Ensure a network is disabled
- cs_physical_network:
- name: net01
- zone: zone01
- state: disabled
- delegate_to: localhost
-
-- name: Ensure a network is enabled
- cs_physical_network:
- name: net01
- zone: zone01
- state: enabled
- delegate_to: localhost
-
-- name: Ensure a network is absent
- cs_physical_network:
- name: net01
- zone: zone01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the network.
- returned: success
- type: str
- sample: 3f8f25cd-c498-443f-9058-438cfbcbff50
-name:
- description: Name of the network.
- returned: success
- type: str
- sample: net01
-state:
- description: State of the network [Enabled/Disabled].
- returned: success
- type: str
- sample: Enabled
-broadcast_domain_range:
- description: broadcastdomainrange of the network [POD / ZONE].
- returned: success
- type: str
- sample: ZONE
-isolation_method:
- description: isolationmethod of the network [VLAN/GRE/L3].
- returned: success
- type: str
- sample: VLAN
-network_speed:
- description: networkspeed of the network [1G/10G].
- returned: success
- type: str
- sample: 1G
-zone:
- description: Name of zone the physical network is in.
- returned: success
- type: str
- sample: ch-gva-2
-domain:
- description: Name of domain the network is in.
- returned: success
- type: str
- sample: domain1
-nsps:
- description: list of enabled or disabled Network Service Providers
- type: complex
- returned: on enabling/disabling of Network Service Providers
- contains:
- enabled:
- description: list of Network Service Providers that were enabled
- returned: on Network Service Provider enabling
- type: list
- sample:
- - virtualrouter
- disabled:
- description: list of Network Service Providers that were disabled
- returned: on Network Service Provider disabling
- type: list
- sample:
- - internallbvm
-
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackPhysicalNetwork(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackPhysicalNetwork, self).__init__(module)
- self.returns = {
- 'isolationmethods': 'isolation_method',
- 'broadcastdomainrange': 'broadcast_domain_range',
- 'networkspeed': 'network_speed',
- 'vlan': 'vlan',
- 'tags': 'tags',
- }
- self.nsps = []
- self.vrouters = None
- self.loadbalancers = None
-
- def _get_common_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'isolationmethods': self.module.params.get('isolation_method'),
- 'broadcastdomainrange': self.module.params.get('broadcast_domain_range'),
- 'networkspeed': self.module.params.get('network_speed'),
- 'tags': self.module.params.get('tags'),
- 'vlan': self.module.params.get('vlan'),
- }
-
- state = self.module.params.get('state')
- if state in ['enabled', 'disabled']:
- args['state'] = state.capitalize()
- return args
-
- def get_physical_network(self, key=None):
- physical_network = self.module.params.get('name')
- if self.physical_network:
- return self._get_by_key(key, self.physical_network)
-
- args = {
- 'zoneid': self.get_zone(key='id')
- }
- physical_networks = self.query_api('listPhysicalNetworks', **args)
- if physical_networks:
- for net in physical_networks['physicalnetwork']:
- if physical_network.lower() in [net['name'].lower(), net['id']]:
- self.physical_network = net
- self.result['physical_network'] = net['name']
- break
-
- return self._get_by_key(key, self.physical_network)
-
- def get_nsp(self, name=None):
- if not self.nsps:
- args = {
- 'physicalnetworkid': self.get_physical_network(key='id')
- }
- res = self.query_api('listNetworkServiceProviders', **args)
-
- self.nsps = res['networkserviceprovider']
-
- names = []
- for nsp in self.nsps:
- names.append(nsp['name'])
- if nsp['name'].lower() == name.lower():
- return nsp
-
- self.module.fail_json(msg="Failed: '{0}' not in network service providers list '[{1}]'".format(name, names))
-
- def update_nsp(self, name=None, state=None, service_list=None):
- nsp = self.get_nsp(name)
- if not service_list and nsp['state'] == state:
- return nsp
-
- args = {
- 'id': nsp['id'],
- 'servicelist': service_list,
- 'state': state
- }
- if not self.module.check_mode:
- res = self.query_api('updateNetworkServiceProvider', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- nsp = self.poll_job(res, 'networkserviceprovider')
-
- self.result['changed'] = True
- return nsp
-
- def get_vrouter_element(self, nsp_name='virtualrouter'):
- nsp = self.get_nsp(nsp_name)
- nspid = nsp['id']
- if self.vrouters is None:
- self.vrouters = dict()
- res = self.query_api('listVirtualRouterElements', )
- for vrouter in res['virtualrouterelement']:
- self.vrouters[vrouter['nspid']] = vrouter
-
- if nspid not in self.vrouters:
- self.module.fail_json(msg="Failed: No VirtualRouterElement found for nsp '%s'" % nsp_name)
-
- return self.vrouters[nspid]
-
- def get_loadbalancer_element(self, nsp_name='internallbvm'):
- nsp = self.get_nsp(nsp_name)
- nspid = nsp['id']
- if self.loadbalancers is None:
- self.loadbalancers = dict()
- res = self.query_api('listInternalLoadBalancerElements', )
- for loadbalancer in res['internalloadbalancerelement']:
- self.loadbalancers[loadbalancer['nspid']] = loadbalancer
-
- if nspid not in self.loadbalancers:
- self.module.fail_json(msg="Failed: No Loadbalancer found for nsp '%s'" % nsp_name)
-
- return self.loadbalancers[nspid]
-
- def set_vrouter_element_state(self, enabled, nsp_name='virtualrouter'):
- vrouter = self.get_vrouter_element(nsp_name)
- if vrouter['enabled'] == enabled:
- return vrouter
-
- args = {
- 'id': vrouter['id'],
- 'enabled': enabled
- }
- if not self.module.check_mode:
- res = self.query_api('configureVirtualRouterElement', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vrouter = self.poll_job(res, 'virtualrouterelement')
-
- self.result['changed'] = True
- return vrouter
-
- def set_loadbalancer_element_state(self, enabled, nsp_name='internallbvm'):
- loadbalancer = self.get_loadbalancer_element(nsp_name=nsp_name)
- if loadbalancer['enabled'] == enabled:
- return loadbalancer
-
- args = {
- 'id': loadbalancer['id'],
- 'enabled': enabled
- }
- if not self.module.check_mode:
- res = self.query_api('configureInternalLoadBalancerElement', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- loadbalancer = self.poll_job(res, 'internalloadbalancerelement')
-
- self.result['changed'] = True
- return loadbalancer
-
- def present_network(self):
- network = self.get_physical_network()
- if network:
- network = self._update_network()
- else:
- network = self._create_network()
- return network
-
- def _create_network(self):
- self.result['changed'] = True
- args = dict(zoneid=self.get_zone(key='id'))
- args.update(self._get_common_args())
- if self.get_domain(key='id'):
- args['domainid'] = self.get_domain(key='id')
-
- if not self.module.check_mode:
- resource = self.query_api('createPhysicalNetwork', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.network = self.poll_job(resource, 'physicalnetwork')
-
- return self.network
-
- def _update_network(self):
- network = self.get_physical_network()
-
- args = dict(id=network['id'])
- args.update(self._get_common_args())
-
- if self.has_changed(args, network):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- resource = self.query_api('updatePhysicalNetwork', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.physical_network = self.poll_job(resource, 'physicalnetwork')
- return self.physical_network
-
- def absent_network(self):
- physical_network = self.get_physical_network()
- if physical_network:
- self.result['changed'] = True
- args = {
- 'id': physical_network['id'],
- }
- if not self.module.check_mode:
- resource = self.query_api('deletePhysicalNetwork', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(resource, 'success')
-
- return physical_network
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True, aliases=['physical_network']),
- zone=dict(),
- domain=dict(),
- vlan=dict(),
- nsps_disabled=dict(type='list'),
- nsps_enabled=dict(type='list'),
- network_speed=dict(choices=['1G', '10G']),
- broadcast_domain_range=dict(choices=['POD', 'ZONE']),
- isolation_method=dict(choices=['VLAN', 'GRE', 'L3']),
- state=dict(choices=['present', 'enabled', 'disabled', 'absent'], default='present'),
- tags=dict(aliases=['tag']),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_network = AnsibleCloudStackPhysicalNetwork(module)
- state = module.params.get('state')
- nsps_disabled = module.params.get('nsps_disabled', [])
- nsps_enabled = module.params.get('nsps_enabled', [])
-
- if state in ['absent']:
- network = acs_network.absent_network()
- else:
- network = acs_network.present_network()
- if nsps_disabled is not None:
- for name in nsps_disabled:
- acs_network.update_nsp(name=name, state='Disabled')
-
- if nsps_enabled is not None:
- for nsp_name in nsps_enabled:
- if nsp_name.lower() in ['virtualrouter', 'vpcvirtualrouter']:
- acs_network.set_vrouter_element_state(enabled=True, nsp_name=nsp_name)
- elif nsp_name.lower() == 'internallbvm':
- acs_network.set_loadbalancer_element_state(enabled=True, nsp_name=nsp_name)
-
- acs_network.update_nsp(name=nsp_name, state='Enabled')
-
- result = acs_network.get_result(network)
-
- if nsps_enabled:
- result['nsps_enabled'] = nsps_enabled
- if nsps_disabled:
- result['nsps_disabled'] = nsps_disabled
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_pod.py b/lib/ansible/modules/cloud/cloudstack/cs_pod.py
deleted file mode 100644
index 141491e89b..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_pod.py
+++ /dev/null
@@ -1,296 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_pod
-short_description: Manages pods on Apache CloudStack based clouds.
-description:
- - Create, update, delete pods.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the pod.
- type: str
- required: true
- id:
- description:
- - uuid of the existing pod.
- type: str
- start_ip:
- description:
- - Starting IP address for the Pod.
- - Required on I(state=present)
- type: str
- end_ip:
- description:
- - Ending IP address for the Pod.
- type: str
- netmask:
- description:
- - Netmask for the Pod.
- - Required on I(state=present)
- type: str
- gateway:
- description:
- - Gateway for the Pod.
- - Required on I(state=present)
- type: str
- zone:
- description:
- - Name of the zone in which the pod belongs to.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the pod.
- type: str
- default: present
- choices: [ present, enabled, disabled, absent ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a pod is present
- cs_pod:
- name: pod1
- zone: ch-zrh-ix-01
- start_ip: 10.100.10.101
- gateway: 10.100.10.1
- netmask: 255.255.255.0
- delegate_to: localhost
-
-- name: Ensure a pod is disabled
- cs_pod:
- name: pod1
- zone: ch-zrh-ix-01
- state: disabled
- delegate_to: localhost
-
-- name: Ensure a pod is enabled
- cs_pod:
- name: pod1
- zone: ch-zrh-ix-01
- state: enabled
- delegate_to: localhost
-
-- name: Ensure a pod is absent
- cs_pod:
- name: pod1
- zone: ch-zrh-ix-01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the pod.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the pod.
- returned: success
- type: str
- sample: pod01
-start_ip:
- description: Starting IP of the pod.
- returned: success
- type: str
- sample: 10.100.1.101
-end_ip:
- description: Ending IP of the pod.
- returned: success
- type: str
- sample: 10.100.1.254
-netmask:
- description: Netmask of the pod.
- returned: success
- type: str
- sample: 255.255.255.0
-gateway:
- description: Gateway of the pod.
- returned: success
- type: str
- sample: 10.100.1.1
-allocation_state:
- description: State of the pod.
- returned: success
- type: str
- sample: Enabled
-zone:
- description: Name of zone the pod is in.
- returned: success
- type: str
- sample: ch-gva-2
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackPod(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackPod, self).__init__(module)
- self.returns = {
- 'endip': 'end_ip',
- 'startip': 'start_ip',
- 'gateway': 'gateway',
- 'netmask': 'netmask',
- 'allocationstate': 'allocation_state',
- }
- self.pod = None
-
- def _get_common_pod_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'zoneid': self.get_zone(key='id'),
- 'startip': self.module.params.get('start_ip'),
- 'endip': self.module.params.get('end_ip'),
- 'netmask': self.module.params.get('netmask'),
- 'gateway': self.module.params.get('gateway')
- }
- state = self.module.params.get('state')
- if state in ['enabled', 'disabled']:
- args['allocationstate'] = state.capitalize()
- return args
-
- def get_pod(self):
- if not self.pod:
- args = {
- 'zoneid': self.get_zone(key='id')
- }
-
- uuid = self.module.params.get('id')
- if uuid:
- args['id'] = uuid
- else:
- args['name'] = self.module.params.get('name')
-
- pods = self.query_api('listPods', **args)
- if pods:
- for pod in pods['pod']:
- if not args['name']:
- self.pod = self._transform_ip_list(pod)
- break
- elif args['name'] == pod['name']:
- self.pod = self._transform_ip_list(pod)
- break
- return self.pod
-
- def present_pod(self):
- pod = self.get_pod()
- if pod:
- pod = self._update_pod()
- else:
- pod = self._create_pod()
- return pod
-
- def _create_pod(self):
- required_params = [
- 'start_ip',
- 'netmask',
- 'gateway',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- pod = None
- self.result['changed'] = True
- args = self._get_common_pod_args()
- if not self.module.check_mode:
- res = self.query_api('createPod', **args)
- pod = res['pod']
- return pod
-
- def _update_pod(self):
- pod = self.get_pod()
- args = self._get_common_pod_args()
- args['id'] = pod['id']
-
- if self.has_changed(args, pod):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updatePod', **args)
- pod = res['pod']
- return pod
-
- def absent_pod(self):
- pod = self.get_pod()
- if pod:
- self.result['changed'] = True
-
- args = {
- 'id': pod['id']
- }
- if not self.module.check_mode:
- self.query_api('deletePod', **args)
- return pod
-
- def _transform_ip_list(self, resource):
- """ Workaround for 4.11 return API break """
- keys = ['endip', 'startip']
- if resource:
- for key in keys:
- if key in resource and isinstance(resource[key], list):
- resource[key] = resource[key][0]
- return resource
-
- def get_result(self, pod):
- pod = self._transform_ip_list(pod)
- super(AnsibleCloudStackPod, self).get_result(pod)
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- id=dict(),
- name=dict(required=True),
- gateway=dict(),
- netmask=dict(),
- start_ip=dict(),
- end_ip=dict(),
- zone=dict(),
- state=dict(choices=['present', 'enabled', 'disabled', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_pod = AnsibleCloudStackPod(module)
- state = module.params.get('state')
- if state in ['absent']:
- pod = acs_pod.absent_pod()
- else:
- pod = acs_pod.present_pod()
-
- result = acs_pod.get_result(pod)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_portforward.py b/lib/ansible/modules/cloud/cloudstack/cs_portforward.py
deleted file mode 100644
index a735b050e9..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_portforward.py
+++ /dev/null
@@ -1,398 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_portforward
-short_description: Manages port forwarding rules on Apache CloudStack based clouds.
-description:
- - Create, update and remove port forwarding rules.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- ip_address:
- description:
- - Public IP address the rule is assigned to.
- type: str
- required: true
- vm:
- description:
- - Name of virtual machine which we make the port forwarding rule for.
- - Required if I(state=present).
- type: str
- state:
- description:
- - State of the port forwarding rule.
- type: str
- default: present
- choices: [ present, absent ]
- protocol:
- description:
- - Protocol of the port forwarding rule.
- type: str
- default: tcp
- choices: [ tcp, udp ]
- public_port:
- description:
- - Start public port for this rule.
- type: int
- required: true
- public_end_port:
- description:
- - End public port for this rule.
- - If not specified equal I(public_port).
- type: int
- private_port:
- description:
- - Start private port for this rule.
- type: int
- required: true
- private_end_port:
- description:
- - End private port for this rule.
- - If not specified equal I(private_port).
- type: int
- open_firewall:
- description:
- - Whether the firewall rule for public port should be created, while creating the new rule.
- - Use M(cs_firewall) for managing firewall rules.
- default: no
- type: bool
- vm_guest_ip:
- description:
- - VM guest NIC secondary IP address for the port forwarding rule.
- type: str
- network:
- description:
- - Name of the network.
- type: str
- version_added: '2.3'
- vpc:
- description:
- - Name of the VPC.
- version_added: '2.3'
- type: str
- domain:
- description:
- - Domain the I(vm) is related to.
- type: str
- account:
- description:
- - Account the I(vm) is related to.
- type: str
- project:
- description:
- - Name of the project the I(vm) is located in.
- type: str
- zone:
- description:
- - Name of the zone in which the virtual machine is in.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: 1.2.3.4:80 -> web01:8080
- cs_portforward:
- ip_address: 1.2.3.4
- vm: web01
- public_port: 80
- private_port: 8080
- delegate_to: localhost
-
-- name: forward SSH and open firewall
- cs_portforward:
- ip_address: '{{ public_ip }}'
- vm: '{{ inventory_hostname }}'
- public_port: '{{ ansible_ssh_port }}'
- private_port: 22
- open_firewall: true
- delegate_to: localhost
-
-- name: forward DNS traffic, but do not open firewall
- cs_portforward:
- ip_address: 1.2.3.4
- vm: '{{ inventory_hostname }}'
- public_port: 53
- private_port: 53
- protocol: udp
- delegate_to: localhost
-
-- name: remove ssh port forwarding
- cs_portforward:
- ip_address: 1.2.3.4
- public_port: 22
- private_port: 22
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the public IP address.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-ip_address:
- description: Public IP address.
- returned: success
- type: str
- sample: 1.2.3.4
-protocol:
- description: Protocol.
- returned: success
- type: str
- sample: tcp
-private_port:
- description: Start port on the virtual machine's IP address.
- returned: success
- type: int
- sample: 80
-private_end_port:
- description: End port on the virtual machine's IP address.
- returned: success
- type: int
- sample: 80
-public_port:
- description: Start port on the public IP address.
- returned: success
- type: int
- sample: 80
-public_end_port:
- description: End port on the public IP address.
- returned: success
- type: int
- sample: 80
-tags:
- description: Tags related to the port forwarding.
- returned: success
- type: list
- sample: []
-vm_name:
- description: Name of the virtual machine.
- returned: success
- type: str
- sample: web-01
-vm_display_name:
- description: Display name of the virtual machine.
- returned: success
- type: str
- sample: web-01
-vm_guest_ip:
- description: IP of the virtual machine.
- returned: success
- type: str
- sample: 10.101.65.152
-vpc:
- description: Name of the VPC.
- returned: success
- type: str
- sample: my_vpc
-network:
- description: Name of the network.
- returned: success
- type: str
- sample: dmz
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec, cs_required_together
-
-
-class AnsibleCloudStackPortforwarding(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackPortforwarding, self).__init__(module)
- self.returns = {
- 'virtualmachinedisplayname': 'vm_display_name',
- 'virtualmachinename': 'vm_name',
- 'ipaddress': 'ip_address',
- 'vmguestip': 'vm_guest_ip',
- 'publicip': 'public_ip',
- 'protocol': 'protocol',
- }
- # these values will be casted to int
- self.returns_to_int = {
- 'publicport': 'public_port',
- 'publicendport': 'public_end_port',
- 'privateport': 'private_port',
- 'privateendport': 'private_end_port',
- }
- self.portforwarding_rule = None
-
- def get_portforwarding_rule(self):
- if not self.portforwarding_rule:
- protocol = self.module.params.get('protocol')
- public_port = self.module.params.get('public_port')
-
- args = {
- 'ipaddressid': self.get_ip_address(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- }
- portforwarding_rules = self.query_api('listPortForwardingRules', **args)
-
- if portforwarding_rules and 'portforwardingrule' in portforwarding_rules:
- for rule in portforwarding_rules['portforwardingrule']:
- if (protocol == rule['protocol'] and
- public_port == int(rule['publicport'])):
- self.portforwarding_rule = rule
- break
- return self.portforwarding_rule
-
- def present_portforwarding_rule(self):
- portforwarding_rule = self.get_portforwarding_rule()
- if portforwarding_rule:
- portforwarding_rule = self.update_portforwarding_rule(portforwarding_rule)
- else:
- portforwarding_rule = self.create_portforwarding_rule()
-
- if portforwarding_rule:
- portforwarding_rule = self.ensure_tags(resource=portforwarding_rule, resource_type='PortForwardingRule')
- self.portforwarding_rule = portforwarding_rule
-
- return portforwarding_rule
-
- def create_portforwarding_rule(self):
- args = {
- 'protocol': self.module.params.get('protocol'),
- 'publicport': self.module.params.get('public_port'),
- 'publicendport': self.get_or_fallback('public_end_port', 'public_port'),
- 'privateport': self.module.params.get('private_port'),
- 'privateendport': self.get_or_fallback('private_end_port', 'private_port'),
- 'openfirewall': self.module.params.get('open_firewall'),
- 'vmguestip': self.get_vm_guest_ip(),
- 'ipaddressid': self.get_ip_address(key='id'),
- 'virtualmachineid': self.get_vm(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'networkid': self.get_network(key='id'),
- }
-
- portforwarding_rule = None
- self.result['changed'] = True
- if not self.module.check_mode:
- portforwarding_rule = self.query_api('createPortForwardingRule', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- portforwarding_rule = self.poll_job(portforwarding_rule, 'portforwardingrule')
- return portforwarding_rule
-
- def update_portforwarding_rule(self, portforwarding_rule):
- args = {
- 'protocol': self.module.params.get('protocol'),
- 'publicport': self.module.params.get('public_port'),
- 'publicendport': self.get_or_fallback('public_end_port', 'public_port'),
- 'privateport': self.module.params.get('private_port'),
- 'privateendport': self.get_or_fallback('private_end_port', 'private_port'),
- 'vmguestip': self.get_vm_guest_ip(),
- 'ipaddressid': self.get_ip_address(key='id'),
- 'virtualmachineid': self.get_vm(key='id'),
- 'networkid': self.get_network(key='id'),
- }
-
- if self.has_changed(args, portforwarding_rule):
- self.result['changed'] = True
- if not self.module.check_mode:
- # API broken in 4.2.1?, workaround using remove/create instead of update
- # portforwarding_rule = self.query_api('updatePortForwardingRule', **args)
- self.absent_portforwarding_rule()
- portforwarding_rule = self.query_api('createPortForwardingRule', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- portforwarding_rule = self.poll_job(portforwarding_rule, 'portforwardingrule')
- return portforwarding_rule
-
- def absent_portforwarding_rule(self):
- portforwarding_rule = self.get_portforwarding_rule()
-
- if portforwarding_rule:
- self.result['changed'] = True
- args = {
- 'id': portforwarding_rule['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('deletePortForwardingRule', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'portforwardingrule')
- return portforwarding_rule
-
- def get_result(self, portforwarding_rule):
- super(AnsibleCloudStackPortforwarding, self).get_result(portforwarding_rule)
- if portforwarding_rule:
- for search_key, return_key in self.returns_to_int.items():
- if search_key in portforwarding_rule:
- self.result[return_key] = int(portforwarding_rule[search_key])
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- ip_address=dict(required=True),
- protocol=dict(choices=['tcp', 'udp'], default='tcp'),
- public_port=dict(type='int', required=True),
- public_end_port=dict(type='int'),
- private_port=dict(type='int', required=True),
- private_end_port=dict(type='int'),
- state=dict(choices=['present', 'absent'], default='present'),
- open_firewall=dict(type='bool', default=False),
- vm_guest_ip=dict(),
- vm=dict(),
- vpc=dict(),
- network=dict(),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_pf = AnsibleCloudStackPortforwarding(module)
- state = module.params.get('state')
- if state in ['absent']:
- pf_rule = acs_pf.absent_portforwarding_rule()
- else:
- pf_rule = acs_pf.present_portforwarding_rule()
-
- result = acs_pf.get_result(pf_rule)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_project.py b/lib/ansible/modules/cloud/cloudstack/cs_project.py
deleted file mode 100644
index 509b30aa04..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_project.py
+++ /dev/null
@@ -1,279 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_project
-short_description: Manages projects on Apache CloudStack based clouds.
-description:
- - Create, update, suspend, activate and remove projects.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the project.
- type: str
- required: true
- display_text:
- description:
- - Display text of the project.
- - If not specified, I(name) will be used as I(display_text).
- type: str
- state:
- description:
- - State of the project.
- type: str
- default: present
- choices: [ present, absent, active, suspended ]
- domain:
- description:
- - Domain the project is related to.
- type: str
- account:
- description:
- - Account the project is related to.
- type: str
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "If you want to delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.2'
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a project
- cs_project:
- name: web
- tags:
- - { key: admin, value: john }
- - { key: foo, value: bar }
- delegate_to: localhost
-
-- name: Rename a project
- cs_project:
- name: web
- display_text: my web project
- delegate_to: localhost
-
-- name: Suspend an existing project
- cs_project:
- name: web
- state: suspended
- delegate_to: localhost
-
-- name: Activate an existing project
- cs_project:
- name: web
- state: active
- delegate_to: localhost
-
-- name: Remove a project
- cs_project:
- name: web
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the project.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the project.
- returned: success
- type: str
- sample: web project
-display_text:
- description: Display text of the project.
- returned: success
- type: str
- sample: web project
-state:
- description: State of the project.
- returned: success
- type: str
- sample: Active
-domain:
- description: Domain the project is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the project is related to.
- returned: success
- type: str
- sample: example account
-tags:
- description: List of resource tags associated with the project.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackProject(AnsibleCloudStack):
-
- def get_project(self):
- if not self.project:
- project = self.module.params.get('name')
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'fetch_list': True,
- }
- projects = self.query_api('listProjects', **args)
- if projects:
- for p in projects:
- if project.lower() in [p['name'].lower(), p['id']]:
- self.project = p
- break
- return self.project
-
- def present_project(self):
- project = self.get_project()
- if not project:
- project = self.create_project(project)
- else:
- project = self.update_project(project)
- if project:
- project = self.ensure_tags(resource=project, resource_type='project')
- # refresh resource
- self.project = project
- return project
-
- def update_project(self, project):
- args = {
- 'id': project['id'],
- 'displaytext': self.get_or_fallback('display_text', 'name')
- }
- if self.has_changed(args, project):
- self.result['changed'] = True
- if not self.module.check_mode:
- project = self.query_api('updateProject', **args)
-
- poll_async = self.module.params.get('poll_async')
- if project and poll_async:
- project = self.poll_job(project, 'project')
- return project
-
- def create_project(self, project):
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id')
- }
- if not self.module.check_mode:
- project = self.query_api('createProject', **args)
-
- poll_async = self.module.params.get('poll_async')
- if project and poll_async:
- project = self.poll_job(project, 'project')
- return project
-
- def state_project(self, state='active'):
- project = self.present_project()
-
- if project['state'].lower() != state:
- self.result['changed'] = True
-
- args = {
- 'id': project['id']
- }
- if not self.module.check_mode:
- if state == 'suspended':
- project = self.query_api('suspendProject', **args)
- else:
- project = self.query_api('activateProject', **args)
-
- poll_async = self.module.params.get('poll_async')
- if project and poll_async:
- project = self.poll_job(project, 'project')
- return project
-
- def absent_project(self):
- project = self.get_project()
- if project:
- self.result['changed'] = True
-
- args = {
- 'id': project['id']
- }
- if not self.module.check_mode:
- res = self.query_api('deleteProject', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- res = self.poll_job(res, 'project')
- return project
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- state=dict(choices=['present', 'absent', 'active', 'suspended'], default='present'),
- domain=dict(),
- account=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_project = AnsibleCloudStackProject(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- project = acs_project.absent_project()
-
- elif state in ['active', 'suspended']:
- project = acs_project.state_project(state=state)
-
- else:
- project = acs_project.present_project()
-
- result = acs_project.get_result(project)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_region.py b/lib/ansible/modules/cloud/cloudstack/cs_region.py
deleted file mode 100644
index 6ff481fc87..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_region.py
+++ /dev/null
@@ -1,192 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_region
-short_description: Manages regions on Apache CloudStack based clouds.
-description:
- - Add, update and remove regions.
-version_added: '2.3'
-author: René Moser (@resmo)
-options:
- id:
- description:
- - ID of the region.
- - Must be an number (int).
- type: int
- required: true
- name:
- description:
- - Name of the region.
- - Required if I(state=present)
- type: str
- endpoint:
- description:
- - Endpoint URL of the region.
- - Required if I(state=present)
- type: str
- state:
- description:
- - State of the region.
- type: str
- default: present
- choices: [ present, absent ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a region
- cs_region:
- id: 2
- name: geneva
- endpoint: https://cloud.gva.example.com
- delegate_to: localhost
-
-- name: remove a region with ID 2
- cs_region:
- id: 2
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: ID of the region.
- returned: success
- type: int
- sample: 1
-name:
- description: Name of the region.
- returned: success
- type: str
- sample: local
-endpoint:
- description: Endpoint of the region.
- returned: success
- type: str
- sample: http://cloud.example.com
-gslb_service_enabled:
- description: Whether the GSLB service is enabled or not.
- returned: success
- type: bool
- sample: true
-portable_ip_service_enabled:
- description: Whether the portable IP service is enabled or not.
- returned: success
- type: bool
- sample: true
-'''
-
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackRegion(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackRegion, self).__init__(module)
- self.returns = {
- 'endpoint': 'endpoint',
- 'gslbserviceenabled': 'gslb_service_enabled',
- 'portableipserviceenabled': 'portable_ip_service_enabled',
- }
-
- def get_region(self):
- id = self.module.params.get('id')
- regions = self.query_api('listRegions', id=id)
- if regions:
- return regions['region'][0]
- return None
-
- def present_region(self):
- region = self.get_region()
- if not region:
- region = self._create_region(region=region)
- else:
- region = self._update_region(region=region)
- return region
-
- def _create_region(self, region):
- self.result['changed'] = True
- args = {
- 'id': self.module.params.get('id'),
- 'name': self.module.params.get('name'),
- 'endpoint': self.module.params.get('endpoint')
- }
- if not self.module.check_mode:
- res = self.query_api('addRegion', **args)
- region = res['region']
- return region
-
- def _update_region(self, region):
- args = {
- 'id': self.module.params.get('id'),
- 'name': self.module.params.get('name'),
- 'endpoint': self.module.params.get('endpoint')
- }
- if self.has_changed(args, region):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateRegion', **args)
- region = res['region']
- return region
-
- def absent_region(self):
- region = self.get_region()
- if region:
- self.result['changed'] = True
- if not self.module.check_mode:
- self.query_api('removeRegion', id=region['id'])
- return region
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- id=dict(required=True, type='int'),
- name=dict(),
- endpoint=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- required_if=[
- ('state', 'present', ['name', 'endpoint']),
- ],
- supports_check_mode=True
- )
-
- acs_region = AnsibleCloudStackRegion(module)
-
- state = module.params.get('state')
- if state == 'absent':
- region = acs_region.absent_region()
- else:
- region = acs_region.present_region()
-
- result = acs_region.get_result(region)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_resourcelimit.py b/lib/ansible/modules/cloud/cloudstack/cs_resourcelimit.py
deleted file mode 100644
index ea354065cb..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_resourcelimit.py
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_resourcelimit
-short_description: Manages resource limits on Apache CloudStack based clouds.
-description:
- - Manage limits of resources for domains, accounts and projects.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- resource_type:
- description:
- - Type of the resource.
- type: str
- required: true
- choices:
- - instance
- - ip_address
- - volume
- - snapshot
- - template
- - network
- - vpc
- - cpu
- - memory
- - primary_storage
- - secondary_storage
- aliases: [ type ]
- limit:
- description:
- - Maximum number of the resource.
- - Default is unlimited C(-1).
- type: int
- default: -1
- aliases: [ max ]
- domain:
- description:
- - Domain the resource is related to.
- type: str
- account:
- description:
- - Account the resource is related to.
- type: str
- project:
- description:
- - Name of the project the resource is related to.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Update a resource limit for instances of a domain
- cs_resourcelimit:
- type: instance
- limit: 10
- domain: customers
- delegate_to: localhost
-
-- name: Update a resource limit for instances of an account
- cs_resourcelimit:
- type: instance
- limit: 12
- account: moserre
- domain: customers
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-recource_type:
- description: Type of the resource
- returned: success
- type: str
- sample: instance
-limit:
- description: Maximum number of the resource.
- returned: success
- type: int
- sample: -1
-domain:
- description: Domain the resource is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the resource is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Project the resource is related to.
- returned: success
- type: str
- sample: example project
-'''
-
-# import cloudstack common
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_required_together,
- cs_argument_spec
-)
-
-
-RESOURCE_TYPES = {
- 'instance': 0,
- 'ip_address': 1,
- 'volume': 2,
- 'snapshot': 3,
- 'template': 4,
- 'network': 6,
- 'vpc': 7,
- 'cpu': 8,
- 'memory': 9,
- 'primary_storage': 10,
- 'secondary_storage': 11,
-}
-
-
-class AnsibleCloudStackResourceLimit(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackResourceLimit, self).__init__(module)
- self.returns = {
- 'max': 'limit',
- }
-
- def get_resource_type(self):
- resource_type = self.module.params.get('resource_type')
- return RESOURCE_TYPES.get(resource_type)
-
- def get_resource_limit(self):
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'resourcetype': self.get_resource_type()
- }
- resource_limit = self.query_api('listResourceLimits', **args)
- if resource_limit:
- if 'limit' in resource_limit['resourcelimit'][0]:
- resource_limit['resourcelimit'][0]['limit'] = int(resource_limit['resourcelimit'][0])
- return resource_limit['resourcelimit'][0]
- self.module.fail_json(msg="Resource limit type '%s' not found." % self.module.params.get('resource_type'))
-
- def update_resource_limit(self):
- resource_limit = self.get_resource_limit()
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'resourcetype': self.get_resource_type(),
- 'max': self.module.params.get('limit', -1)
- }
-
- if self.has_changed(args, resource_limit):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateResourceLimit', **args)
- resource_limit = res['resourcelimit']
- return resource_limit
-
- def get_result(self, resource_limit):
- self.result = super(AnsibleCloudStackResourceLimit, self).get_result(resource_limit)
- self.result['resource_type'] = self.module.params.get('resource_type')
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- resource_type=dict(required=True, choices=RESOURCE_TYPES.keys(), aliases=['type']),
- limit=dict(default=-1, aliases=['max'], type='int'),
- domain=dict(),
- account=dict(),
- project=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_resource_limit = AnsibleCloudStackResourceLimit(module)
- resource_limit = acs_resource_limit.update_resource_limit()
- result = acs_resource_limit.get_result(resource_limit)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_role.py b/lib/ansible/modules/cloud/cloudstack/cs_role.py
deleted file mode 100644
index 6db295bd81..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_role.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_role
-short_description: Manages user roles on Apache CloudStack based clouds.
-description:
- - Create, update, delete user roles.
-version_added: '2.3'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the role.
- type: str
- required: true
- uuid:
- description:
- - ID of the role.
- - If provided, I(uuid) is used as key.
- type: str
- aliases: [ id ]
- role_type:
- description:
- - Type of the role.
- - Only considered for creation.
- type: str
- default: User
- choices: [ User, DomainAdmin, ResourceAdmin, Admin ]
- description:
- description:
- - Description of the role.
- type: str
- state:
- description:
- - State of the role.
- type: str
- default: present
- choices: [ present, absent ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure an user role is present
- cs_role:
- name: myrole_user
- delegate_to: localhost
-
-- name: Ensure a role having particular ID is named as myrole_user
- cs_role:
- name: myrole_user
- id: 04589590-ac63-4ffc-93f5-b698b8ac38b6
- delegate_to: localhost
-
-- name: Ensure a role is absent
- cs_role:
- name: myrole_user
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the role.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the role.
- returned: success
- type: str
- sample: myrole
-description:
- description: Description of the role.
- returned: success
- type: str
- sample: "This is my role description"
-role_type:
- description: Type of the role.
- returned: success
- type: str
- sample: User
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackRole(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackRole, self).__init__(module)
- self.returns = {
- 'type': 'role_type',
- }
-
- def get_role(self):
- uuid = self.module.params.get('uuid')
- if uuid:
- args = {
- 'id': uuid,
- }
- roles = self.query_api('listRoles', **args)
- if roles:
- return roles['role'][0]
- else:
- args = {
- 'name': self.module.params.get('name'),
- }
- roles = self.query_api('listRoles', **args)
- if roles:
- return roles['role'][0]
- return None
-
- def present_role(self):
- role = self.get_role()
- if role:
- role = self._update_role(role)
- else:
- role = self._create_role(role)
- return role
-
- def _create_role(self, role):
- self.result['changed'] = True
- args = {
- 'name': self.module.params.get('name'),
- 'type': self.module.params.get('role_type'),
- 'description': self.module.params.get('description'),
- }
- if not self.module.check_mode:
- res = self.query_api('createRole', **args)
- role = res['role']
- return role
-
- def _update_role(self, role):
- args = {
- 'id': role['id'],
- 'name': self.module.params.get('name'),
- 'description': self.module.params.get('description'),
- }
- if self.has_changed(args, role):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateRole', **args)
-
- # The API as in 4.9 does not return an updated role yet
- if 'role' not in res:
- role = self.get_role()
- else:
- role = res['role']
- return role
-
- def absent_role(self):
- role = self.get_role()
- if role:
- self.result['changed'] = True
- args = {
- 'id': role['id'],
- }
- if not self.module.check_mode:
- self.query_api('deleteRole', **args)
- return role
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- uuid=dict(aliases=['id']),
- name=dict(required=True),
- description=dict(),
- role_type=dict(choices=['User', 'DomainAdmin', 'ResourceAdmin', 'Admin'], default='User'),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_role = AnsibleCloudStackRole(module)
- state = module.params.get('state')
- if state == 'absent':
- role = acs_role.absent_role()
- else:
- role = acs_role.present_role()
-
- result = acs_role.get_result(role)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_role_permission.py b/lib/ansible/modules/cloud/cloudstack/cs_role_permission.py
deleted file mode 100644
index 30392b2f87..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_role_permission.py
+++ /dev/null
@@ -1,351 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, David Passante (@dpassante)
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_role_permission
-short_description: Manages role permissions on Apache CloudStack based clouds.
-description:
- - Create, update and remove CloudStack role permissions.
- - Managing role permissions only supported in CloudStack >= 4.9.
-version_added: '2.6'
-author: David Passante (@dpassante)
-options:
- name:
- description:
- - The API name of the permission.
- type: str
- required: true
- role:
- description:
- - Name or ID of the role.
- type: str
- required: true
- permission:
- description:
- - The rule permission, allow or deny. Defaulted to deny.
- type: str
- choices: [ allow, deny ]
- default: deny
- state:
- description:
- - State of the role permission.
- type: str
- choices: [ present, absent ]
- default: present
- description:
- description:
- - The description of the role permission.
- type: str
- parent:
- description:
- - The parent role permission uuid. use 0 to move this rule at the top of the list.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a role permission
- cs_role_permission:
- role: My_Custom_role
- name: createVPC
- permission: allow
- description: My comments
- delegate_to: localhost
-
-- name: Remove a role permission
- cs_role_permission:
- state: absent
- role: My_Custom_role
- name: createVPC
- delegate_to: localhost
-
-- name: Update a system role permission
- cs_role_permission:
- role: Domain Admin
- name: createVPC
- permission: deny
- delegate_to: localhost
-
-- name: Update rules order. Move the rule at the top of list
- cs_role_permission:
- role: Domain Admin
- name: createVPC
- parent: 0
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: The ID of the role permission.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: The API name of the permission.
- returned: success
- type: str
- sample: createVPC
-permission:
- description: The permission type of the api name.
- returned: success
- type: str
- sample: allow
-role_id:
- description: The ID of the role to which the role permission belongs.
- returned: success
- type: str
- sample: c6f7a5fc-43f8-11e5-a151-feff819cdc7f
-description:
- description: The description of the role permission
- returned: success
- type: str
- sample: Deny createVPC for users
-'''
-
-from distutils.version import LooseVersion
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackRolePermission(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackRolePermission, self).__init__(module)
- cloudstack_min_version = LooseVersion('4.9.2')
-
- self.returns = {
- 'id': 'id',
- 'roleid': 'role_id',
- 'rule': 'name',
- 'permission': 'permission',
- 'description': 'description',
- }
- self.role_permission = None
-
- self.cloudstack_version = self._cloudstack_ver()
-
- if self.cloudstack_version < cloudstack_min_version:
- self.fail_json(msg="This module requires CloudStack >= %s." % cloudstack_min_version)
-
- def _cloudstack_ver(self):
- capabilities = self.get_capabilities()
- return LooseVersion(capabilities['cloudstackversion'])
-
- def _get_role_id(self):
- role = self.module.params.get('role')
- if not role:
- return None
-
- res = self.query_api('listRoles')
- roles = res['role']
- if roles:
- for r in roles:
- if role in [r['name'], r['id']]:
- return r['id']
- self.fail_json(msg="Role '%s' not found" % role)
-
- def _get_role_perm(self):
- role_permission = self.role_permission
-
- args = {
- 'roleid': self._get_role_id(),
- }
-
- rp = self.query_api('listRolePermissions', **args)
-
- if rp:
- role_permission = rp['rolepermission']
-
- return role_permission
-
- def _get_rule(self, rule=None):
- if not rule:
- rule = self.module.params.get('name')
-
- if self._get_role_perm():
- for _rule in self._get_role_perm():
- if rule == _rule['rule'] or rule == _rule['id']:
- return _rule
-
- return None
-
- def _get_rule_order(self):
- perms = self._get_role_perm()
- rules = []
-
- if perms:
- for i, rule in enumerate(perms):
- rules.append(rule['id'])
-
- return rules
-
- def replace_rule(self):
- old_rule = self._get_rule()
-
- if old_rule:
- rules_order = self._get_rule_order()
- old_pos = rules_order.index(old_rule['id'])
-
- self.remove_role_perm()
-
- new_rule = self.create_role_perm()
-
- if new_rule:
- perm_order = self.order_permissions(int(old_pos - 1), new_rule['id'])
-
- return perm_order
-
- return None
-
- def order_permissions(self, parent, rule_id):
- rules = self._get_rule_order()
-
- if isinstance(parent, int):
- parent_pos = parent
- elif parent == '0':
- parent_pos = -1
- else:
- parent_rule = self._get_rule(parent)
- if not parent_rule:
- self.fail_json(msg="Parent rule '%s' not found" % parent)
-
- parent_pos = rules.index(parent_rule['id'])
-
- r_id = rules.pop(rules.index(rule_id))
-
- rules.insert((parent_pos + 1), r_id)
- rules = ','.join(map(str, rules))
-
- return rules
-
- def create_or_update_role_perm(self):
- role_permission = self._get_rule()
-
- if not role_permission:
- role_permission = self.create_role_perm()
- else:
- role_permission = self.update_role_perm(role_permission)
-
- return role_permission
-
- def create_role_perm(self):
- role_permission = None
-
- self.result['changed'] = True
-
- args = {
- 'rule': self.module.params.get('name'),
- 'description': self.module.params.get('description'),
- 'roleid': self._get_role_id(),
- 'permission': self.module.params.get('permission'),
- }
-
- if not self.module.check_mode:
- res = self.query_api('createRolePermission', **args)
- role_permission = res['rolepermission']
-
- return role_permission
-
- def update_role_perm(self, role_perm):
- perm_order = None
-
- if not self.module.params.get('parent'):
- args = {
- 'ruleid': role_perm['id'],
- 'roleid': role_perm['roleid'],
- 'permission': self.module.params.get('permission'),
- }
-
- if self.has_changed(args, role_perm, only_keys=['permission']):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- if self.cloudstack_version >= LooseVersion('4.11.0'):
- self.query_api('updateRolePermission', **args)
- role_perm = self._get_rule()
- else:
- perm_order = self.replace_rule()
- else:
- perm_order = self.order_permissions(self.module.params.get('parent'), role_perm['id'])
-
- if perm_order:
- args = {
- 'roleid': role_perm['roleid'],
- 'ruleorder': perm_order,
- }
-
- self.result['changed'] = True
-
- if not self.module.check_mode:
- self.query_api('updateRolePermission', **args)
- role_perm = self._get_rule()
-
- return role_perm
-
- def remove_role_perm(self):
- role_permission = self._get_rule()
-
- if role_permission:
- self.result['changed'] = True
-
- args = {
- 'id': role_permission['id'],
- }
-
- if not self.module.check_mode:
- self.query_api('deleteRolePermission', **args)
-
- return role_permission
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- role=dict(required=True),
- name=dict(required=True),
- permission=dict(choices=['allow', 'deny'], default='deny'),
- description=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- parent=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['permission', 'parent'],
- ),
- supports_check_mode=True
- )
-
- acs_role_perm = AnsibleCloudStackRolePermission(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- role_permission = acs_role_perm.remove_role_perm()
- else:
- role_permission = acs_role_perm.create_or_update_role_perm()
-
- result = acs_role_perm.get_result(role_permission)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_router.py b/lib/ansible/modules/cloud/cloudstack/cs_router.py
deleted file mode 100644
index db4240a7b8..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_router.py
+++ /dev/null
@@ -1,377 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_router
-short_description: Manages routers on Apache CloudStack based clouds.
-description:
- - Start, restart, stop and destroy routers.
- - I(state=present) is not able to create routers, use M(cs_network) instead.
-version_added: '2.2'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the router.
- type: str
- required: true
- service_offering:
- description:
- - Name or id of the service offering of the router.
- type: str
- domain:
- description:
- - Domain the router is related to.
- type: str
- account:
- description:
- - Account the router is related to.
- type: str
- project:
- description:
- - Name of the project the router is related to.
- type: str
- zone:
- description:
- - Name of the zone the router is deployed in.
- - If not set, all zones are used.
- type: str
- version_added: '2.4'
- state:
- description:
- - State of the router.
- type: str
- default: present
- choices: [ present, absent, started, stopped, restarted ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-# Ensure the router has the desired service offering, no matter if
-# the router is running or not.
-- name: Present router
- cs_router:
- name: r-40-VM
- service_offering: System Offering for Software Router
- delegate_to: localhost
-
-- name: Ensure started
- cs_router:
- name: r-40-VM
- state: started
- delegate_to: localhost
-
-# Ensure started with desired service offering.
-# If the service offerings changes, router will be rebooted.
-- name: Ensure started with desired service offering
- cs_router:
- name: r-40-VM
- service_offering: System Offering for Software Router
- state: started
- delegate_to: localhost
-
-- name: Ensure stopped
- cs_router:
- name: r-40-VM
- state: stopped
- delegate_to: localhost
-
-- name: Remove a router
- cs_router:
- name: r-40-VM
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the router.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the router.
- returned: success
- type: str
- sample: r-40-VM
-created:
- description: Date of the router was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-template_version:
- description: Version of the system VM template.
- returned: success
- type: str
- sample: 4.5.1
-requires_upgrade:
- description: Whether the router needs to be upgraded to the new template.
- returned: success
- type: bool
- sample: false
-redundant_state:
- description: Redundant state of the router.
- returned: success
- type: str
- sample: UNKNOWN
-role:
- description: Role of the router.
- returned: success
- type: str
- sample: VIRTUAL_ROUTER
-zone:
- description: Name of zone the router is in.
- returned: success
- type: str
- sample: ch-gva-2
-service_offering:
- description: Name of the service offering the router has.
- returned: success
- type: str
- sample: System Offering For Software Router
-state:
- description: State of the router.
- returned: success
- type: str
- sample: Active
-domain:
- description: Domain the router is related to.
- returned: success
- type: str
- sample: ROOT
-account:
- description: Account the router is related to.
- returned: success
- type: str
- sample: admin
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackRouter(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackRouter, self).__init__(module)
- self.returns = {
- 'serviceofferingname': 'service_offering',
- 'version': 'template_version',
- 'requiresupgrade': 'requires_upgrade',
- 'redundantstate': 'redundant_state',
- 'role': 'role'
- }
- self.router = None
-
- def get_service_offering_id(self):
- service_offering = self.module.params.get('service_offering')
- if not service_offering:
- return None
-
- args = {
- 'issystem': True
- }
-
- service_offerings = self.query_api('listServiceOfferings', **args)
- if service_offerings:
- for s in service_offerings['serviceoffering']:
- if service_offering in [s['name'], s['id']]:
- return s['id']
- self.module.fail_json(msg="Service offering '%s' not found" % service_offering)
-
- def get_router(self):
- if not self.router:
- router = self.module.params.get('name')
-
- args = {
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'listall': True,
- 'fetch_list': True,
- }
-
- if self.module.params.get('zone'):
- args['zoneid'] = self.get_zone(key='id')
-
- routers = self.query_api('listRouters', **args)
- if routers:
- for r in routers:
- if router.lower() in [r['name'].lower(), r['id']]:
- self.router = r
- break
- return self.router
-
- def start_router(self):
- router = self.get_router()
- if not router:
- self.module.fail_json(msg="Router not found")
-
- if router['state'].lower() != "running":
- self.result['changed'] = True
-
- args = {
- 'id': router['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('startRouter', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- router = self.poll_job(res, 'router')
- return router
-
- def stop_router(self):
- router = self.get_router()
- if not router:
- self.module.fail_json(msg="Router not found")
-
- if router['state'].lower() != "stopped":
- self.result['changed'] = True
-
- args = {
- 'id': router['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('stopRouter', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- router = self.poll_job(res, 'router')
- return router
-
- def reboot_router(self):
- router = self.get_router()
- if not router:
- self.module.fail_json(msg="Router not found")
-
- self.result['changed'] = True
-
- args = {
- 'id': router['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('rebootRouter', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- router = self.poll_job(res, 'router')
- return router
-
- def absent_router(self):
- router = self.get_router()
- if router:
- self.result['changed'] = True
-
- args = {
- 'id': router['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('destroyRouter', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'router')
- return router
-
- def present_router(self):
- router = self.get_router()
- if not router:
- self.module.fail_json(msg="Router can not be created using the API, see cs_network.")
-
- args = {
- 'id': router['id'],
- 'serviceofferingid': self.get_service_offering_id(),
- }
-
- state = self.module.params.get('state')
-
- if self.has_changed(args, router):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- current_state = router['state'].lower()
-
- self.stop_router()
- router = self.query_api('changeServiceForRouter', **args)
-
- if state in ['restarted', 'started']:
- router = self.start_router()
-
- # if state=present we get to the state before the service
- # offering change.
- elif state == "present" and current_state == "running":
- router = self.start_router()
-
- elif state == "started":
- router = self.start_router()
-
- elif state == "stopped":
- router = self.stop_router()
-
- elif state == "restarted":
- router = self.reboot_router()
-
- return router
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- service_offering=dict(),
- state=dict(choices=['present', 'started', 'stopped', 'restarted', 'absent'], default="present"),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_router = AnsibleCloudStackRouter(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- router = acs_router.absent_router()
- else:
- router = acs_router.present_router()
-
- result = acs_router.get_result(router)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_securitygroup.py b/lib/ansible/modules/cloud/cloudstack/cs_securitygroup.py
deleted file mode 100644
index 9567516aa0..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_securitygroup.py
+++ /dev/null
@@ -1,199 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_securitygroup
-short_description: Manages security groups on Apache CloudStack based clouds.
-description:
- - Create and remove security groups.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the security group.
- type: str
- required: true
- description:
- description:
- - Description of the security group.
- type: str
- state:
- description:
- - State of the security group.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the security group is related to.
- type: str
- account:
- description:
- - Account the security group is related to.
- type: str
- project:
- description:
- - Name of the project the security group to be created in.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a security group
- cs_securitygroup:
- name: default
- description: default security group
- delegate_to: localhost
-
-- name: remove a security group
- cs_securitygroup:
- name: default
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the security group.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: Name of security group.
- returned: success
- type: str
- sample: app
-description:
- description: Description of security group.
- returned: success
- type: str
- sample: application security group
-tags:
- description: List of resource tags associated with the security group.
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-project:
- description: Name of project the security group is related to.
- returned: success
- type: str
- sample: Production
-domain:
- description: Domain the security group is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the security group is related to.
- returned: success
- type: str
- sample: example account
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec, cs_required_together
-
-
-class AnsibleCloudStackSecurityGroup(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackSecurityGroup, self).__init__(module)
- self.security_group = None
-
- def get_security_group(self):
- if not self.security_group:
-
- args = {
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'securitygroupname': self.module.params.get('name'),
- }
- sgs = self.query_api('listSecurityGroups', **args)
- if sgs:
- self.security_group = sgs['securitygroup'][0]
- return self.security_group
-
- def create_security_group(self):
- security_group = self.get_security_group()
- if not security_group:
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'description': self.module.params.get('description'),
- }
-
- if not self.module.check_mode:
- res = self.query_api('createSecurityGroup', **args)
- security_group = res['securitygroup']
-
- return security_group
-
- def remove_security_group(self):
- security_group = self.get_security_group()
- if security_group:
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- }
-
- if not self.module.check_mode:
- self.query_api('deleteSecurityGroup', **args)
-
- return security_group
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- description=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- project=dict(),
- account=dict(),
- domain=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_sg = AnsibleCloudStackSecurityGroup(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- sg = acs_sg.remove_security_group()
- else:
- sg = acs_sg.create_security_group()
-
- result = acs_sg.get_result(sg)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_securitygroup_rule.py b/lib/ansible/modules/cloud/cloudstack/cs_securitygroup_rule.py
deleted file mode 100644
index 27ee88d433..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_securitygroup_rule.py
+++ /dev/null
@@ -1,388 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_securitygroup_rule
-short_description: Manages security group rules on Apache CloudStack based clouds.
-description:
- - Add and remove security group rules.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- security_group:
- description:
- - Name of the security group the rule is related to. The security group must be existing.
- type: str
- required: true
- state:
- description:
- - State of the security group rule.
- type: str
- default: present
- choices: [ present, absent ]
- protocol:
- description:
- - Protocol of the security group rule.
- type: str
- default: tcp
- choices: [ tcp, udp, icmp, ah, esp, gre ]
- type:
- description:
- - Ingress or egress security group rule.
- type: str
- default: ingress
- choices: [ ingress, egress ]
- cidr:
- description:
- - CIDR (full notation) to be used for security group rule.
- type: str
- default: 0.0.0.0/0
- user_security_group:
- description:
- - Security group this rule is based of.
- type: str
- start_port:
- description:
- - Start port for this rule. Required if I(protocol=tcp) or I(protocol=udp).
- type: int
- aliases: [ port ]
- end_port:
- description:
- - End port for this rule. Required if I(protocol=tcp) or I(protocol=udp), but I(start_port) will be used if not set.
- type: int
- icmp_type:
- description:
- - Type of the icmp message being sent. Required if I(protocol=icmp).
- type: int
- icmp_code:
- description:
- - Error code for this icmp message. Required if I(protocol=icmp).
- type: int
- project:
- description:
- - Name of the project the security group to be created in.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
----
-- name: allow inbound port 80/tcp from 1.2.3.4 added to security group 'default'
- cs_securitygroup_rule:
- security_group: default
- port: 80
- cidr: 1.2.3.4/32
- delegate_to: localhost
-
-- name: allow tcp/udp outbound added to security group 'default'
- cs_securitygroup_rule:
- security_group: default
- type: egress
- start_port: 1
- end_port: 65535
- protocol: '{{ item }}'
- with_items:
- - tcp
- - udp
- delegate_to: localhost
-
-- name: allow inbound icmp from 0.0.0.0/0 added to security group 'default'
- cs_securitygroup_rule:
- security_group: default
- protocol: icmp
- icmp_code: -1
- icmp_type: -1
- delegate_to: localhost
-
-- name: remove rule inbound port 80/tcp from 0.0.0.0/0 from security group 'default'
- cs_securitygroup_rule:
- security_group: default
- port: 80
- state: absent
- delegate_to: localhost
-
-- name: allow inbound port 80/tcp from security group web added to security group 'default'
- cs_securitygroup_rule:
- security_group: default
- port: 80
- user_security_group: web
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the of the rule.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-security_group:
- description: security group of the rule.
- returned: success
- type: str
- sample: default
-type:
- description: type of the rule.
- returned: success
- type: str
- sample: ingress
-cidr:
- description: CIDR of the rule.
- returned: success and cidr is defined
- type: str
- sample: 0.0.0.0/0
-user_security_group:
- description: user security group of the rule.
- returned: success and user_security_group is defined
- type: str
- sample: default
-protocol:
- description: protocol of the rule.
- returned: success
- type: str
- sample: tcp
-start_port:
- description: start port of the rule.
- returned: success
- type: int
- sample: 80
-end_port:
- description: end port of the rule.
- returned: success
- type: int
- sample: 80
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec, cs_required_together
-
-
-class AnsibleCloudStackSecurityGroupRule(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackSecurityGroupRule, self).__init__(module)
- self.returns = {
- 'icmptype': 'icmp_type',
- 'icmpcode': 'icmp_code',
- 'endport': 'end_port',
- 'startport': 'start_port',
- 'protocol': 'protocol',
- 'cidr': 'cidr',
- 'securitygroupname': 'user_security_group',
- }
-
- def _tcp_udp_match(self, rule, protocol, start_port, end_port):
- return (protocol in ['tcp', 'udp'] and
- protocol == rule['protocol'] and
- start_port == int(rule['startport']) and
- end_port == int(rule['endport']))
-
- def _icmp_match(self, rule, protocol, icmp_code, icmp_type):
- return (protocol == 'icmp' and
- protocol == rule['protocol'] and
- icmp_code == int(rule['icmpcode']) and
- icmp_type == int(rule['icmptype']))
-
- def _ah_esp_gre_match(self, rule, protocol):
- return (protocol in ['ah', 'esp', 'gre'] and
- protocol == rule['protocol'])
-
- def _type_security_group_match(self, rule, security_group_name):
- return (security_group_name and
- 'securitygroupname' in rule and
- security_group_name == rule['securitygroupname'])
-
- def _type_cidr_match(self, rule, cidr):
- return ('cidr' in rule and
- cidr == rule['cidr'])
-
- def _get_rule(self, rules):
- user_security_group_name = self.module.params.get('user_security_group')
- cidr = self.module.params.get('cidr')
- protocol = self.module.params.get('protocol')
- start_port = self.module.params.get('start_port')
- end_port = self.get_or_fallback('end_port', 'start_port')
- icmp_code = self.module.params.get('icmp_code')
- icmp_type = self.module.params.get('icmp_type')
-
- if protocol in ['tcp', 'udp'] and (start_port is None or end_port is None):
- self.module.fail_json(msg="no start_port or end_port set for protocol '%s'" % protocol)
-
- if protocol == 'icmp' and (icmp_type is None or icmp_code is None):
- self.module.fail_json(msg="no icmp_type or icmp_code set for protocol '%s'" % protocol)
-
- for rule in rules:
- if user_security_group_name:
- type_match = self._type_security_group_match(rule, user_security_group_name)
- else:
- type_match = self._type_cidr_match(rule, cidr)
-
- protocol_match = (self._tcp_udp_match(rule, protocol, start_port, end_port) or
- self._icmp_match(rule, protocol, icmp_code, icmp_type) or
- self._ah_esp_gre_match(rule, protocol))
-
- if type_match and protocol_match:
- return rule
- return None
-
- def get_security_group(self, security_group_name=None):
- if not security_group_name:
- security_group_name = self.module.params.get('security_group')
- args = {
- 'securitygroupname': security_group_name,
- 'projectid': self.get_project('id'),
- }
- sgs = self.query_api('listSecurityGroups', **args)
- if not sgs or 'securitygroup' not in sgs:
- self.module.fail_json(msg="security group '%s' not found" % security_group_name)
- return sgs['securitygroup'][0]
-
- def add_rule(self):
- security_group = self.get_security_group()
-
- args = {}
- user_security_group_name = self.module.params.get('user_security_group')
-
- # the user_security_group and cidr are mutually_exclusive, but cidr is defaulted to 0.0.0.0/0.
- # that is why we ignore if we have a user_security_group.
- if user_security_group_name:
- args['usersecuritygrouplist'] = []
- user_security_group = self.get_security_group(user_security_group_name)
- args['usersecuritygrouplist'].append({
- 'group': user_security_group['name'],
- 'account': user_security_group['account'],
- })
- else:
- args['cidrlist'] = self.module.params.get('cidr')
-
- args['protocol'] = self.module.params.get('protocol')
- args['startport'] = self.module.params.get('start_port')
- args['endport'] = self.get_or_fallback('end_port', 'start_port')
- args['icmptype'] = self.module.params.get('icmp_type')
- args['icmpcode'] = self.module.params.get('icmp_code')
- args['projectid'] = self.get_project('id')
- args['securitygroupid'] = security_group['id']
-
- rule = None
- res = None
- sg_type = self.module.params.get('type')
- if sg_type == 'ingress':
- if 'ingressrule' in security_group:
- rule = self._get_rule(security_group['ingressrule'])
- if not rule:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('authorizeSecurityGroupIngress', **args)
-
- elif sg_type == 'egress':
- if 'egressrule' in security_group:
- rule = self._get_rule(security_group['egressrule'])
- if not rule:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('authorizeSecurityGroupEgress', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- security_group = self.poll_job(res, 'securitygroup')
- key = sg_type + "rule" # ingressrule / egressrule
- if key in security_group:
- rule = security_group[key][0]
- return rule
-
- def remove_rule(self):
- security_group = self.get_security_group()
- rule = None
- res = None
- sg_type = self.module.params.get('type')
- if sg_type == 'ingress':
- rule = self._get_rule(security_group['ingressrule'])
- if rule:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('revokeSecurityGroupIngress', id=rule['ruleid'])
-
- elif sg_type == 'egress':
- rule = self._get_rule(security_group['egressrule'])
- if rule:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('revokeSecurityGroupEgress', id=rule['ruleid'])
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- res = self.poll_job(res, 'securitygroup')
- return rule
-
- def get_result(self, security_group_rule):
- super(AnsibleCloudStackSecurityGroupRule, self).get_result(security_group_rule)
- self.result['type'] = self.module.params.get('type')
- self.result['security_group'] = self.module.params.get('security_group')
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- security_group=dict(required=True),
- type=dict(choices=['ingress', 'egress'], default='ingress'),
- cidr=dict(default='0.0.0.0/0'),
- user_security_group=dict(),
- protocol=dict(choices=['tcp', 'udp', 'icmp', 'ah', 'esp', 'gre'], default='tcp'),
- icmp_type=dict(type='int'),
- icmp_code=dict(type='int'),
- start_port=dict(type='int', aliases=['port']),
- end_port=dict(type='int'),
- state=dict(choices=['present', 'absent'], default='present'),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- ))
- required_together = cs_required_together()
- required_together.extend([
- ['icmp_type', 'icmp_code'],
- ])
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=required_together,
- mutually_exclusive=(
- ['icmp_type', 'start_port'],
- ['icmp_type', 'end_port'],
- ['icmp_code', 'start_port'],
- ['icmp_code', 'end_port'],
- ),
- supports_check_mode=True
- )
-
- acs_sg_rule = AnsibleCloudStackSecurityGroupRule(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- sg_rule = acs_sg_rule.remove_rule()
- else:
- sg_rule = acs_sg_rule.add_rule()
-
- result = acs_sg_rule.get_result(sg_rule)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_service_offering.py b/lib/ansible/modules/cloud/cloudstack/cs_service_offering.py
deleted file mode 100644
index 3b15fe7f1e..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_service_offering.py
+++ /dev/null
@@ -1,583 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_service_offering
-description:
- - Create and delete service offerings for guest and system VMs.
- - Update display_text of existing service offering.
-short_description: Manages service offerings on Apache CloudStack based clouds.
-version_added: '2.5'
-author: René Moser (@resmo)
-options:
- disk_bytes_read_rate:
- description:
- - Bytes read rate of the disk offering.
- type: int
- aliases: [ bytes_read_rate ]
- disk_bytes_write_rate:
- description:
- - Bytes write rate of the disk offering.
- type: int
- aliases: [ bytes_write_rate ]
- cpu_number:
- description:
- - The number of CPUs of the service offering.
- type: int
- cpu_speed:
- description:
- - The CPU speed of the service offering in MHz.
- type: int
- limit_cpu_usage:
- description:
- - Restrict the CPU usage to committed service offering.
- type: bool
- deployment_planner:
- description:
- - The deployment planner heuristics used to deploy a VM of this offering.
- - If not set, the value of global config I(vm.deployment.planner) is used.
- type: str
- display_text:
- description:
- - Display text of the service offering.
- - If not set, I(name) will be used as I(display_text) while creating.
- type: str
- domain:
- description:
- - Domain the service offering is related to.
- - Public for all domains and subdomains if not set.
- type: str
- host_tags:
- description:
- - The host tags for this service offering.
- type: list
- aliases:
- - host_tag
- hypervisor_snapshot_reserve:
- description:
- - Hypervisor snapshot reserve space as a percent of a volume.
- - Only for managed storage using Xen or VMware.
- type: int
- is_iops_customized:
- description:
- - Whether compute offering iops is custom or not.
- type: bool
- aliases: [ disk_iops_customized ]
- disk_iops_read_rate:
- description:
- - IO requests read rate of the disk offering.
- type: int
- disk_iops_write_rate:
- description:
- - IO requests write rate of the disk offering.
- type: int
- disk_iops_max:
- description:
- - Max. iops of the compute offering.
- type: int
- disk_iops_min:
- description:
- - Min. iops of the compute offering.
- type: int
- is_system:
- description:
- - Whether it is a system VM offering or not.
- type: bool
- default: no
- is_volatile:
- description:
- - Whether the virtual machine needs to be volatile or not.
- - Every reboot of VM the root disk is detached then destroyed and a fresh root disk is created and attached to VM.
- type: bool
- memory:
- description:
- - The total memory of the service offering in MB.
- type: int
- name:
- description:
- - Name of the service offering.
- type: str
- required: true
- network_rate:
- description:
- - Data transfer rate in Mb/s allowed.
- - Supported only for non-system offering and system offerings having I(system_vm_type=domainrouter).
- type: int
- offer_ha:
- description:
- - Whether HA is set for the service offering.
- type: bool
- default: no
- provisioning_type:
- description:
- - Provisioning type used to create volumes.
- type: str
- choices:
- - thin
- - sparse
- - fat
- service_offering_details:
- description:
- - Details for planner, used to store specific parameters.
- - A list of dictionaries having keys C(key) and C(value).
- type: list
- state:
- description:
- - State of the service offering.
- type: str
- choices:
- - present
- - absent
- default: present
- storage_type:
- description:
- - The storage type of the service offering.
- type: str
- choices:
- - local
- - shared
- system_vm_type:
- description:
- - The system VM type.
- - Required if I(is_system=yes).
- type: str
- choices:
- - domainrouter
- - consoleproxy
- - secondarystoragevm
- storage_tags:
- description:
- - The storage tags for this service offering.
- type: list
- aliases:
- - storage_tag
- is_customized:
- description:
- - Whether the offering is customizable or not.
- type: bool
- version_added: '2.8'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a non-volatile compute service offering with local storage
- cs_service_offering:
- name: Micro
- display_text: Micro 512mb 1cpu
- cpu_number: 1
- cpu_speed: 2198
- memory: 512
- host_tags: eco
- storage_type: local
- delegate_to: localhost
-
-- name: Create a volatile compute service offering with shared storage
- cs_service_offering:
- name: Tiny
- display_text: Tiny 1gb 1cpu
- cpu_number: 1
- cpu_speed: 2198
- memory: 1024
- storage_type: shared
- is_volatile: yes
- host_tags: eco
- storage_tags: eco
- delegate_to: localhost
-
-- name: Create or update a volatile compute service offering with shared storage
- cs_service_offering:
- name: Tiny
- display_text: Tiny 1gb 1cpu
- cpu_number: 1
- cpu_speed: 2198
- memory: 1024
- storage_type: shared
- is_volatile: yes
- host_tags: eco
- storage_tags: eco
- delegate_to: localhost
-
-- name: Create or update a custom compute service offering
- cs_service_offering:
- name: custom
- display_text: custom compute offer
- is_customized: yes
- storage_type: shared
- host_tags: eco
- storage_tags: eco
- delegate_to: localhost
-
-- name: Remove a compute service offering
- cs_service_offering:
- name: Tiny
- state: absent
- delegate_to: localhost
-
-- name: Create or update a system offering for the console proxy
- cs_service_offering:
- name: System Offering for Console Proxy 2GB
- display_text: System Offering for Console Proxy 2GB RAM
- is_system: yes
- system_vm_type: consoleproxy
- cpu_number: 1
- cpu_speed: 2198
- memory: 2048
- storage_type: shared
- storage_tags: perf
- delegate_to: localhost
-
-- name: Remove a system offering
- cs_service_offering:
- name: System Offering for Console Proxy 2GB
- is_system: yes
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the service offering
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-cpu_number:
- description: Number of CPUs in the service offering
- returned: success
- type: int
- sample: 4
-cpu_speed:
- description: Speed of CPUs in MHz in the service offering
- returned: success
- type: int
- sample: 2198
-disk_iops_max:
- description: Max iops of the disk offering
- returned: success
- type: int
- sample: 1000
-disk_iops_min:
- description: Min iops of the disk offering
- returned: success
- type: int
- sample: 500
-disk_bytes_read_rate:
- description: Bytes read rate of the service offering
- returned: success
- type: int
- sample: 1000
-disk_bytes_write_rate:
- description: Bytes write rate of the service offering
- returned: success
- type: int
- sample: 1000
-disk_iops_read_rate:
- description: IO requests per second read rate of the service offering
- returned: success
- type: int
- sample: 1000
-disk_iops_write_rate:
- description: IO requests per second write rate of the service offering
- returned: success
- type: int
- sample: 1000
-created:
- description: Date the offering was created
- returned: success
- type: str
- sample: 2017-11-19T10:48:59+0000
-display_text:
- description: Display text of the offering
- returned: success
- type: str
- sample: Micro 512mb 1cpu
-domain:
- description: Domain the offering is into
- returned: success
- type: str
- sample: ROOT
-host_tags:
- description: List of host tags
- returned: success
- type: list
- sample: [ 'eco' ]
-storage_tags:
- description: List of storage tags
- returned: success
- type: list
- sample: [ 'eco' ]
-is_system:
- description: Whether the offering is for system VMs or not
- returned: success
- type: bool
- sample: false
-is_iops_customized:
- description: Whether the offering uses custom IOPS or not
- returned: success
- type: bool
- sample: false
-is_volatile:
- description: Whether the offering is volatile or not
- returned: success
- type: bool
- sample: false
-limit_cpu_usage:
- description: Whether the CPU usage is restricted to committed service offering
- returned: success
- type: bool
- sample: false
-memory:
- description: Memory of the system offering
- returned: success
- type: int
- sample: 512
-name:
- description: Name of the system offering
- returned: success
- type: str
- sample: Micro
-offer_ha:
- description: Whether HA support is enabled in the offering or not
- returned: success
- type: bool
- sample: false
-provisioning_type:
- description: Provisioning type used to create volumes
- returned: success
- type: str
- sample: thin
-storage_type:
- description: Storage type used to create volumes
- returned: success
- type: str
- sample: shared
-system_vm_type:
- description: System VM type of this offering
- returned: success
- type: str
- sample: consoleproxy
-service_offering_details:
- description: Additioanl service offering details
- returned: success
- type: dict
- sample: "{'vgpuType': 'GRID K180Q','pciDevice':'Group of NVIDIA Corporation GK107GL [GRID K1] GPUs'}"
-network_rate:
- description: Data transfer rate in megabits per second allowed
- returned: success
- type: int
- sample: 1000
-is_customized:
- description: Whether the offering is customizable or not
- returned: success
- type: bool
- sample: false
- version_added: '2.8'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackServiceOffering(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackServiceOffering, self).__init__(module)
- self.returns = {
- 'cpunumber': 'cpu_number',
- 'cpuspeed': 'cpu_speed',
- 'deploymentplanner': 'deployment_planner',
- 'diskBytesReadRate': 'disk_bytes_read_rate',
- 'diskBytesWriteRate': 'disk_bytes_write_rate',
- 'diskIopsReadRate': 'disk_iops_read_rate',
- 'diskIopsWriteRate': 'disk_iops_write_rate',
- 'maxiops': 'disk_iops_max',
- 'miniops': 'disk_iops_min',
- 'hypervisorsnapshotreserve': 'hypervisor_snapshot_reserve',
- 'iscustomized': 'is_customized',
- 'iscustomizediops': 'is_iops_customized',
- 'issystem': 'is_system',
- 'isvolatile': 'is_volatile',
- 'limitcpuuse': 'limit_cpu_usage',
- 'memory': 'memory',
- 'networkrate': 'network_rate',
- 'offerha': 'offer_ha',
- 'provisioningtype': 'provisioning_type',
- 'serviceofferingdetails': 'service_offering_details',
- 'storagetype': 'storage_type',
- 'systemvmtype': 'system_vm_type',
- 'tags': 'storage_tags',
- }
-
- def get_service_offering(self):
- args = {
- 'name': self.module.params.get('name'),
- 'domainid': self.get_domain(key='id'),
- 'issystem': self.module.params.get('is_system'),
- 'systemvmtype': self.module.params.get('system_vm_type'),
- }
- service_offerings = self.query_api('listServiceOfferings', **args)
- if service_offerings:
- return service_offerings['serviceoffering'][0]
-
- def present_service_offering(self):
- service_offering = self.get_service_offering()
- if not service_offering:
- service_offering = self._create_offering(service_offering)
- else:
- service_offering = self._update_offering(service_offering)
-
- return service_offering
-
- def absent_service_offering(self):
- service_offering = self.get_service_offering()
- if service_offering:
- self.result['changed'] = True
- if not self.module.check_mode:
- args = {
- 'id': service_offering['id'],
- }
- self.query_api('deleteServiceOffering', **args)
- return service_offering
-
- def _create_offering(self, service_offering):
- self.result['changed'] = True
-
- system_vm_type = self.module.params.get('system_vm_type')
- is_system = self.module.params.get('is_system')
-
- required_params = []
- if is_system and not system_vm_type:
- required_params.append('system_vm_type')
- self.module.fail_on_missing_params(required_params=required_params)
-
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'bytesreadrate': self.module.params.get('disk_bytes_read_rate'),
- 'byteswriterate': self.module.params.get('disk_bytes_write_rate'),
- 'cpunumber': self.module.params.get('cpu_number'),
- 'cpuspeed': self.module.params.get('cpu_speed'),
- 'customizediops': self.module.params.get('is_iops_customized'),
- 'deploymentplanner': self.module.params.get('deployment_planner'),
- 'domainid': self.get_domain(key='id'),
- 'hosttags': self.module.params.get('host_tags'),
- 'hypervisorsnapshotreserve': self.module.params.get('hypervisor_snapshot_reserve'),
- 'iopsreadrate': self.module.params.get('disk_iops_read_rate'),
- 'iopswriterate': self.module.params.get('disk_iops_write_rate'),
- 'maxiops': self.module.params.get('disk_iops_max'),
- 'miniops': self.module.params.get('disk_iops_min'),
- 'issystem': is_system,
- 'isvolatile': self.module.params.get('is_volatile'),
- 'memory': self.module.params.get('memory'),
- 'networkrate': self.module.params.get('network_rate'),
- 'offerha': self.module.params.get('offer_ha'),
- 'provisioningtype': self.module.params.get('provisioning_type'),
- 'serviceofferingdetails': self.module.params.get('service_offering_details'),
- 'storagetype': self.module.params.get('storage_type'),
- 'systemvmtype': system_vm_type,
- 'tags': self.module.params.get('storage_tags'),
- 'limitcpuuse': self.module.params.get('limit_cpu_usage'),
- 'customized': self.module.params.get('is_customized')
- }
- if not self.module.check_mode:
- res = self.query_api('createServiceOffering', **args)
- service_offering = res['serviceoffering']
- return service_offering
-
- def _update_offering(self, service_offering):
- args = {
- 'id': service_offering['id'],
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- }
- if self.has_changed(args, service_offering):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateServiceOffering', **args)
- service_offering = res['serviceoffering']
- return service_offering
-
- def get_result(self, service_offering):
- super(AnsibleCloudStackServiceOffering, self).get_result(service_offering)
- if service_offering:
- if 'hosttags' in service_offering:
- self.result['host_tags'] = service_offering['hosttags'].split(',') or [service_offering['hosttags']]
-
- # Prevent confusion, the api returns a tags key for storage tags.
- if 'tags' in service_offering:
- self.result['storage_tags'] = service_offering['tags'].split(',') or [service_offering['tags']]
- if 'tags' in self.result:
- del self.result['tags']
-
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- cpu_number=dict(type='int'),
- cpu_speed=dict(type='int'),
- limit_cpu_usage=dict(type='bool'),
- deployment_planner=dict(),
- domain=dict(),
- host_tags=dict(type='list', aliases=['host_tag']),
- hypervisor_snapshot_reserve=dict(type='int'),
- disk_bytes_read_rate=dict(type='int', aliases=['bytes_read_rate']),
- disk_bytes_write_rate=dict(type='int', aliases=['bytes_write_rate']),
- disk_iops_read_rate=dict(type='int'),
- disk_iops_write_rate=dict(type='int'),
- disk_iops_max=dict(type='int'),
- disk_iops_min=dict(type='int'),
- is_system=dict(type='bool', default=False),
- is_volatile=dict(type='bool'),
- is_iops_customized=dict(type='bool', aliases=['disk_iops_customized']),
- memory=dict(type='int'),
- network_rate=dict(type='int'),
- offer_ha=dict(type='bool'),
- provisioning_type=dict(choices=['thin', 'sparse', 'fat']),
- service_offering_details=dict(type='list'),
- storage_type=dict(choices=['local', 'shared']),
- system_vm_type=dict(choices=['domainrouter', 'consoleproxy', 'secondarystoragevm']),
- storage_tags=dict(type='list', aliases=['storage_tag']),
- state=dict(choices=['present', 'absent'], default='present'),
- is_customized=dict(type='bool'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_so = AnsibleCloudStackServiceOffering(module)
-
- state = module.params.get('state')
- if state == "absent":
- service_offering = acs_so.absent_service_offering()
- else:
- service_offering = acs_so.present_service_offering()
-
- result = acs_so.get_result(service_offering)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_snapshot_policy.py b/lib/ansible/modules/cloud/cloudstack/cs_snapshot_policy.py
deleted file mode 100644
index b9e65be7c6..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_snapshot_policy.py
+++ /dev/null
@@ -1,361 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_snapshot_policy
-short_description: Manages volume snapshot policies on Apache CloudStack based clouds.
-description:
- - Create, update and delete volume snapshot policies.
-version_added: '2.2'
-author: René Moser (@resmo)
-options:
- volume:
- description:
- - Name of the volume.
- - Either I(volume) or I(vm) is required.
- type: str
- volume_type:
- description:
- - Type of the volume.
- type: str
- choices:
- - DATADISK
- - ROOT
- version_added: '2.3'
- vm:
- description:
- - Name of the instance to select the volume from.
- - Use I(volume_type) if VM has a DATADISK and ROOT volume.
- - In case of I(volume_type=DATADISK), additionally use I(device_id) if VM has more than one DATADISK volume.
- - Either I(volume) or I(vm) is required.
- type: str
- version_added: '2.3'
- device_id:
- description:
- - ID of the device on a VM the volume is attached to.
- - This will only be considered if VM has multiple DATADISK volumes.
- type: int
- version_added: '2.3'
- vpc:
- description:
- - Name of the vpc the instance is deployed in.
- type: str
- version_added: '2.3'
- interval_type:
- description:
- - Interval of the snapshot.
- type: str
- default: daily
- choices: [ hourly, daily, weekly, monthly ]
- aliases: [ interval ]
- max_snaps:
- description:
- - Max number of snapshots.
- type: int
- default: 8
- aliases: [ max ]
- schedule:
- description:
- - Time the snapshot is scheduled. Required if I(state=present).
- - 'Format for I(interval_type=HOURLY): C(MM)'
- - 'Format for I(interval_type=DAILY): C(MM:HH)'
- - 'Format for I(interval_type=WEEKLY): C(MM:HH:DD (1-7))'
- - 'Format for I(interval_type=MONTHLY): C(MM:HH:DD (1-28))'
- type: str
- time_zone:
- description:
- - Specifies a timezone for this command.
- type: str
- default: UTC
- aliases: [ timezone ]
- state:
- description:
- - State of the snapshot policy.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the volume is related to.
- type: str
- account:
- description:
- - Account the volume is related to.
- type: str
- project:
- description:
- - Name of the project the volume is related to.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: ensure a snapshot policy daily at 1h00 UTC
- cs_snapshot_policy:
- volume: ROOT-478
- schedule: '00:1'
- max_snaps: 3
- delegate_to: localhost
-
-- name: ensure a snapshot policy daily at 1h00 UTC on the second DATADISK of VM web-01
- cs_snapshot_policy:
- vm: web-01
- volume_type: DATADISK
- device_id: 2
- schedule: '00:1'
- max_snaps: 3
- delegate_to: localhost
-
-- name: ensure a snapshot policy hourly at minute 5 UTC
- cs_snapshot_policy:
- volume: ROOT-478
- schedule: '5'
- interval_type: hourly
- max_snaps: 1
- delegate_to: localhost
-
-- name: ensure a snapshot policy weekly on Sunday at 05h00, TZ Europe/Zurich
- cs_snapshot_policy:
- volume: ROOT-478
- schedule: '00:5:1'
- interval_type: weekly
- max_snaps: 1
- time_zone: 'Europe/Zurich'
- delegate_to: localhost
-
-- name: ensure a snapshot policy is absent
- cs_snapshot_policy:
- volume: ROOT-478
- interval_type: hourly
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the snapshot policy.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-interval_type:
- description: interval type of the snapshot policy.
- returned: success
- type: str
- sample: daily
-schedule:
- description: schedule of the snapshot policy.
- returned: success
- type: str
- sample:
-max_snaps:
- description: maximum number of snapshots retained.
- returned: success
- type: int
- sample: 10
-time_zone:
- description: the time zone of the snapshot policy.
- returned: success
- type: str
- sample: Etc/UTC
-volume:
- description: the volume of the snapshot policy.
- returned: success
- type: str
- sample: Etc/UTC
-zone:
- description: Name of zone the volume is related to.
- returned: success
- type: str
- sample: ch-gva-2
-project:
- description: Name of project the volume is related to.
- returned: success
- type: str
- sample: Production
-account:
- description: Account the volume is related to.
- returned: success
- type: str
- sample: example account
-domain:
- description: Domain the volume is related to.
- returned: success
- type: str
- sample: example domain
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackSnapshotPolicy(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackSnapshotPolicy, self).__init__(module)
- self.returns = {
- 'schedule': 'schedule',
- 'timezone': 'time_zone',
- 'maxsnaps': 'max_snaps',
- }
- self.interval_types = {
- 'hourly': 0,
- 'daily': 1,
- 'weekly': 2,
- 'monthly': 3,
- }
- self.volume = None
-
- def get_interval_type(self):
- interval_type = self.module.params.get('interval_type')
- return self.interval_types[interval_type]
-
- def get_volume(self, key=None):
- if self.volume:
- return self._get_by_key(key, self.volume)
-
- args = {
- 'name': self.module.params.get('volume'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'virtualmachineid': self.get_vm(key='id', filter_zone=False),
- 'type': self.module.params.get('volume_type'),
- }
- volumes = self.query_api('listVolumes', **args)
- if volumes:
- if volumes['count'] > 1:
- device_id = self.module.params.get('device_id')
- if not device_id:
- self.module.fail_json(msg="Found more then 1 volume: combine params 'vm', 'volume_type', 'device_id' and/or 'volume' to select the volume")
- else:
- for v in volumes['volume']:
- if v.get('deviceid') == device_id:
- self.volume = v
- return self._get_by_key(key, self.volume)
- self.module.fail_json(msg="No volume found with device id %s" % device_id)
- self.volume = volumes['volume'][0]
- return self._get_by_key(key, self.volume)
- return None
-
- def get_snapshot_policy(self):
- args = {
- 'volumeid': self.get_volume(key='id')
- }
- policies = self.query_api('listSnapshotPolicies', **args)
- if policies:
- for policy in policies['snapshotpolicy']:
- if policy['intervaltype'] == self.get_interval_type():
- return policy
- return None
-
- def present_snapshot_policy(self):
- required_params = [
- 'schedule',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- policy = self.get_snapshot_policy()
- args = {
- 'id': policy.get('id') if policy else None,
- 'intervaltype': self.module.params.get('interval_type'),
- 'schedule': self.module.params.get('schedule'),
- 'maxsnaps': self.module.params.get('max_snaps'),
- 'timezone': self.module.params.get('time_zone'),
- 'volumeid': self.get_volume(key='id')
- }
- if not policy or (policy and self.has_changed(policy, args, only_keys=['schedule', 'maxsnaps', 'timezone'])):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('createSnapshotPolicy', **args)
- policy = res['snapshotpolicy']
- return policy
-
- def absent_snapshot_policy(self):
- policy = self.get_snapshot_policy()
- if policy:
- self.result['changed'] = True
- args = {
- 'id': policy['id']
- }
- if not self.module.check_mode:
- self.query_api('deleteSnapshotPolicies', **args)
- return policy
-
- def get_result(self, policy):
- super(AnsibleCloudStackSnapshotPolicy, self).get_result(policy)
- if policy and 'intervaltype' in policy:
- for key, value in self.interval_types.items():
- if value == policy['intervaltype']:
- self.result['interval_type'] = key
- break
- volume = self.get_volume()
- if volume:
- volume_results = {
- 'volume': volume.get('name'),
- 'zone': volume.get('zonename'),
- 'project': volume.get('project'),
- 'account': volume.get('account'),
- 'domain': volume.get('domain'),
- }
- self.result.update(volume_results)
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- volume=dict(),
- volume_type=dict(choices=['DATADISK', 'ROOT']),
- vm=dict(),
- device_id=dict(type='int'),
- vpc=dict(),
- interval_type=dict(default='daily', choices=['hourly', 'daily', 'weekly', 'monthly'], aliases=['interval']),
- schedule=dict(),
- time_zone=dict(default='UTC', aliases=['timezone']),
- max_snaps=dict(type='int', default=8, aliases=['max']),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- required_one_of=(
- ['vm', 'volume'],
- ),
- supports_check_mode=True
- )
-
- acs_snapshot_policy = AnsibleCloudStackSnapshotPolicy(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- policy = acs_snapshot_policy.absent_snapshot_policy()
- else:
- policy = acs_snapshot_policy.present_snapshot_policy()
-
- result = acs_snapshot_policy.get_result(policy)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_sshkeypair.py b/lib/ansible/modules/cloud/cloudstack/cs_sshkeypair.py
deleted file mode 100644
index f36fedf576..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_sshkeypair.py
+++ /dev/null
@@ -1,266 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_sshkeypair
-short_description: Manages SSH keys on Apache CloudStack based clouds.
-description:
- - Create, register and remove SSH keys.
- - If no key was found and no public key was provided and a new SSH
- private/public key pair will be created and the private key will be returned.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of public key.
- type: str
- required: true
- domain:
- description:
- - Domain the public key is related to.
- type: str
- account:
- description:
- - Account the public key is related to.
- type: str
- project:
- description:
- - Name of the project the public key to be registered in.
- type: str
- state:
- description:
- - State of the public key.
- type: str
- default: present
- choices: [ present, absent ]
- public_key:
- description:
- - String of the public key.
- type: str
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a new private / public key pair
- cs_sshkeypair:
- name: linus@example.com
- delegate_to: localhost
- register: key
-- debug:
- msg: 'Private key is {{ key.private_key }}'
-
-- name: remove a public key by its name
- cs_sshkeypair:
- name: linus@example.com
- state: absent
- delegate_to: localhost
-
-- name: register your existing local public key
- cs_sshkeypair:
- name: linus@example.com
- public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the SSH public key.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: Name of the SSH public key.
- returned: success
- type: str
- sample: linus@example.com
-fingerprint:
- description: Fingerprint of the SSH public key.
- returned: success
- type: str
- sample: "86:5e:a3:e8:bd:95:7b:07:7c:c2:5c:f7:ad:8b:09:28"
-private_key:
- description: Private key of generated SSH keypair.
- returned: changed
- type: str
- sample: "-----BEGIN RSA PRIVATE KEY-----\nMII...8tO\n-----END RSA PRIVATE KEY-----\n"
-'''
-
-import traceback
-
-SSHPUBKEYS_IMP_ERR = None
-try:
- import sshpubkeys
- HAS_LIB_SSHPUBKEYS = True
-except ImportError:
- SSHPUBKEYS_IMP_ERR = traceback.format_exc()
- HAS_LIB_SSHPUBKEYS = False
-
-from ansible.module_utils.basic import AnsibleModule, missing_required_lib
-from ansible.module_utils._text import to_native
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_required_together,
- cs_argument_spec
-)
-
-
-class AnsibleCloudStackSshKey(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackSshKey, self).__init__(module)
- self.returns = {
- 'privatekey': 'private_key',
- 'fingerprint': 'fingerprint',
- }
- self.ssh_key = None
-
- def register_ssh_key(self, public_key):
- ssh_key = self.get_ssh_key()
- args = self._get_common_args()
- name = self.module.params.get('name')
-
- res = None
- if not ssh_key:
- self.result['changed'] = True
- args['publickey'] = public_key
- if not self.module.check_mode:
- args['name'] = name
- res = self.query_api('registerSSHKeyPair', **args)
- else:
- fingerprint = self._get_ssh_fingerprint(public_key)
- if ssh_key['fingerprint'] != fingerprint:
- self.result['changed'] = True
- if not self.module.check_mode:
- # delete the ssh key with matching name but wrong fingerprint
- args['name'] = name
- self.query_api('deleteSSHKeyPair', **args)
-
- elif ssh_key['name'].lower() != name.lower():
- self.result['changed'] = True
- if not self.module.check_mode:
- # delete the ssh key with matching fingerprint but wrong name
- args['name'] = ssh_key['name']
- self.query_api('deleteSSHKeyPair', **args)
- # First match for key retrievement will be the fingerprint.
- # We need to make another lookup if there is a key with identical name.
- self.ssh_key = None
- ssh_key = self.get_ssh_key()
- if ssh_key and ssh_key['fingerprint'] != fingerprint:
- args['name'] = name
- self.query_api('deleteSSHKeyPair', **args)
-
- if not self.module.check_mode and self.result['changed']:
- args['publickey'] = public_key
- args['name'] = name
- res = self.query_api('registerSSHKeyPair', **args)
-
- if res and 'keypair' in res:
- ssh_key = res['keypair']
-
- return ssh_key
-
- def create_ssh_key(self):
- ssh_key = self.get_ssh_key()
- if not ssh_key:
- self.result['changed'] = True
- args = self._get_common_args()
- args['name'] = self.module.params.get('name')
- if not self.module.check_mode:
- res = self.query_api('createSSHKeyPair', **args)
- ssh_key = res['keypair']
- return ssh_key
-
- def remove_ssh_key(self, name=None):
- ssh_key = self.get_ssh_key()
- if ssh_key:
- self.result['changed'] = True
- args = self._get_common_args()
- args['name'] = name or self.module.params.get('name')
- if not self.module.check_mode:
- self.query_api('deleteSSHKeyPair', **args)
- return ssh_key
-
- def _get_common_args(self):
- return {
- 'domainid': self.get_domain('id'),
- 'account': self.get_account('name'),
- 'projectid': self.get_project('id')
- }
-
- def get_ssh_key(self):
- if not self.ssh_key:
- public_key = self.module.params.get('public_key')
- if public_key:
- # Query by fingerprint of the public key
- args_fingerprint = self._get_common_args()
- args_fingerprint['fingerprint'] = self._get_ssh_fingerprint(public_key)
- ssh_keys = self.query_api('listSSHKeyPairs', **args_fingerprint)
- if ssh_keys and 'sshkeypair' in ssh_keys:
- self.ssh_key = ssh_keys['sshkeypair'][0]
- # When key has not been found by fingerprint, use the name
- if not self.ssh_key:
- args_name = self._get_common_args()
- args_name['name'] = self.module.params.get('name')
- ssh_keys = self.query_api('listSSHKeyPairs', **args_name)
- if ssh_keys and 'sshkeypair' in ssh_keys:
- self.ssh_key = ssh_keys['sshkeypair'][0]
- return self.ssh_key
-
- def _get_ssh_fingerprint(self, public_key):
- key = sshpubkeys.SSHKey(public_key)
- if hasattr(key, 'hash_md5'):
- return key.hash_md5().replace(to_native('MD5:'), to_native(''))
- return key.hash()
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- public_key=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- if not HAS_LIB_SSHPUBKEYS:
- module.fail_json(msg=missing_required_lib("sshpubkeys"), exception=SSHPUBKEYS_IMP_ERR)
-
- acs_sshkey = AnsibleCloudStackSshKey(module)
- state = module.params.get('state')
- if state in ['absent']:
- ssh_key = acs_sshkey.remove_ssh_key()
- else:
- public_key = module.params.get('public_key')
- if public_key:
- ssh_key = acs_sshkey.register_ssh_key(public_key)
- else:
- ssh_key = acs_sshkey.create_ssh_key()
-
- result = acs_sshkey.get_result(ssh_key)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_staticnat.py b/lib/ansible/modules/cloud/cloudstack/cs_staticnat.py
deleted file mode 100644
index 42fb603d58..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_staticnat.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_staticnat
-short_description: Manages static NATs on Apache CloudStack based clouds.
-description:
- - Create, update and remove static NATs.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- ip_address:
- description:
- - Public IP address the static NAT is assigned to.
- type: str
- required: true
- vm:
- description:
- - Name of virtual machine which we make the static NAT for.
- - Required if I(state=present).
- type: str
- vm_guest_ip:
- description:
- - VM guest NIC secondary IP address for the static NAT.
- type: str
- network:
- description:
- - Network the IP address is related to.
- type: str
- version_added: '2.2'
- vpc:
- description:
- - VPC the network related to.
- type: str
- version_added: '2.3'
- state:
- description:
- - State of the static NAT.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the static NAT is related to.
- type: str
- account:
- description:
- - Account the static NAT is related to.
- type: str
- project:
- description:
- - Name of the project the static NAT is related to.
- type: str
- zone:
- description:
- - Name of the zone in which the virtual machine is in.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a static NAT for IP 1.2.3.4 to web01
- cs_staticnat:
- ip_address: 1.2.3.4
- vm: web01
- delegate_to: localhost
-
-- name: Remove a static NAT
- cs_staticnat:
- ip_address: 1.2.3.4
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the ip_address.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-ip_address:
- description: Public IP address.
- returned: success
- type: str
- sample: 1.2.3.4
-vm_name:
- description: Name of the virtual machine.
- returned: success
- type: str
- sample: web-01
-vm_display_name:
- description: Display name of the virtual machine.
- returned: success
- type: str
- sample: web-01
-vm_guest_ip:
- description: IP of the virtual machine.
- returned: success
- type: str
- sample: 10.101.65.152
-zone:
- description: Name of zone the static NAT is related to.
- returned: success
- type: str
- sample: ch-gva-2
-project:
- description: Name of project the static NAT is related to.
- returned: success
- type: str
- sample: Production
-account:
- description: Account the static NAT is related to.
- returned: success
- type: str
- sample: example account
-domain:
- description: Domain the static NAT is related to.
- returned: success
- type: str
- sample: example domain
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackStaticNat(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackStaticNat, self).__init__(module)
- self.returns = {
- 'virtualmachinedisplayname': 'vm_display_name',
- 'virtualmachinename': 'vm_name',
- 'ipaddress': 'ip_address',
- 'vmipaddress': 'vm_guest_ip',
- }
-
- def create_static_nat(self, ip_address):
- self.result['changed'] = True
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'ipaddressid': ip_address['id'],
- 'vmguestip': self.get_vm_guest_ip(),
- 'networkid': self.get_network(key='id')
- }
- if not self.module.check_mode:
- self.query_api('enableStaticNat', **args)
-
- # reset ip address and query new values
- self.ip_address = None
- ip_address = self.get_ip_address()
- return ip_address
-
- def update_static_nat(self, ip_address):
- args = {
- 'virtualmachineid': self.get_vm(key='id'),
- 'ipaddressid': ip_address['id'],
- 'vmguestip': self.get_vm_guest_ip(),
- 'networkid': self.get_network(key='id')
- }
- # make an alias, so we can use has_changed()
- ip_address['vmguestip'] = ip_address['vmipaddress']
- if self.has_changed(args, ip_address, ['vmguestip', 'virtualmachineid']):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('disableStaticNat', ipaddressid=ip_address['id'])
- self.poll_job(res, 'staticnat')
-
- self.query_api('enableStaticNat', **args)
-
- # reset ip address and query new values
- self.ip_address = None
- ip_address = self.get_ip_address()
- return ip_address
-
- def present_static_nat(self):
- ip_address = self.get_ip_address()
- if not ip_address['isstaticnat']:
- ip_address = self.create_static_nat(ip_address)
- else:
- ip_address = self.update_static_nat(ip_address)
- return ip_address
-
- def absent_static_nat(self):
- ip_address = self.get_ip_address()
- if ip_address['isstaticnat']:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('disableStaticNat', ipaddressid=ip_address['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'staticnat')
- return ip_address
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- ip_address=dict(required=True),
- vm=dict(),
- vm_guest_ip=dict(),
- network=dict(),
- vpc=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_static_nat = AnsibleCloudStackStaticNat(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- ip_address = acs_static_nat.absent_static_nat()
- else:
- ip_address = acs_static_nat.present_static_nat()
-
- result = acs_static_nat.get_result(ip_address)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_storage_pool.py b/lib/ansible/modules/cloud/cloudstack/cs_storage_pool.py
deleted file mode 100644
index e7c310eaeb..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_storage_pool.py
+++ /dev/null
@@ -1,509 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Netservers Ltd. <support@netservers.co.uk>
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_storage_pool
-short_description: Manages Primary Storage Pools on Apache CloudStack based clouds.
-description:
- - Create, update, put into maintenance, disable, enable and remove storage pools.
-version_added: '2.4'
-author:
- - Netservers Ltd. (@netservers)
- - René Moser (@resmo)
-options:
- name:
- description:
- - Name of the storage pool.
- type: str
- required: true
- zone:
- description:
- - Name of the zone in which the host should be deployed.
- - If not set, default zone is used.
- type: str
- storage_url:
- description:
- - URL of the storage pool.
- - Required if I(state=present).
- type: str
- pod:
- description:
- - Name of the pod.
- type: str
- cluster:
- description:
- - Name of the cluster.
- type: str
- scope:
- description:
- - The scope of the storage pool.
- - Defaults to cluster when C(cluster) is provided, otherwise zone.
- type: str
- choices: [ cluster, zone ]
- managed:
- description:
- - Whether the storage pool should be managed by CloudStack.
- - Only considered on creation.
- type: bool
- hypervisor:
- description:
- - Required when creating a zone scoped pool.
- - Possible values are C(KVM), C(VMware), C(BareMetal), C(XenServer), C(LXC), C(HyperV), C(UCS), C(OVM), C(Simulator).
- type: str
- storage_tags:
- description:
- - Tags associated with this storage pool.
- type: list
- aliases: [ storage_tag ]
- provider:
- description:
- - Name of the storage provider e.g. SolidFire, SolidFireShared, DefaultPrimary, CloudByte.
- type: str
- default: DefaultPrimary
- capacity_bytes:
- description:
- - Bytes CloudStack can provision from this storage pool.
- type: int
- capacity_iops:
- description:
- - Bytes CloudStack can provision from this storage pool.
- type: int
- allocation_state:
- description:
- - Allocation state of the storage pool.
- type: str
- choices: [ enabled, disabled, maintenance ]
- state:
- description:
- - State of the storage pool.
- type: str
- default: present
- choices: [ present, absent ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: ensure a zone scoped storage_pool is present
- cs_storage_pool:
- zone: zone01
- storage_url: rbd://admin:SECRET@ceph-mons.domain/poolname
- provider: DefaultPrimary
- name: Ceph RBD
- scope: zone
- hypervisor: KVM
- delegate_to: localhost
-
-- name: ensure a cluster scoped storage_pool is disabled
- cs_storage_pool:
- name: Ceph RBD
- zone: zone01
- cluster: cluster01
- pod: pod01
- storage_url: rbd://admin:SECRET@ceph-the-mons.domain/poolname
- provider: DefaultPrimary
- scope: cluster
- allocation_state: disabled
- delegate_to: localhost
-
-- name: ensure a cluster scoped storage_pool is in maintenance
- cs_storage_pool:
- name: Ceph RBD
- zone: zone01
- cluster: cluster01
- pod: pod01
- storage_url: rbd://admin:SECRET@ceph-the-mons.domain/poolname
- provider: DefaultPrimary
- scope: cluster
- allocation_state: maintenance
- delegate_to: localhost
-
-- name: ensure a storage_pool is absent
- cs_storage_pool:
- name: Ceph RBD
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the pool.
- returned: success
- type: str
- sample: a3fca65a-7db1-4891-b97c-48806a978a96
-created:
- description: Date of the pool was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-capacity_iops:
- description: IOPS CloudStack can provision from this storage pool
- returned: when available
- type: int
- sample: 60000
-zone:
- description: The name of the zone.
- returned: success
- type: str
- sample: Zone01
-cluster:
- description: The name of the cluster.
- returned: when scope is cluster
- type: str
- sample: Cluster01
-pod:
- description: The name of the pod.
- returned: when scope is cluster
- type: str
- sample: Cluster01
-disk_size_allocated:
- description: The pool's currently allocated disk space.
- returned: success
- type: int
- sample: 2443517624320
-disk_size_total:
- description: The total size of the pool.
- returned: success
- type: int
- sample: 3915055693824
-disk_size_used:
- description: The pool's currently used disk size.
- returned: success
- type: int
- sample: 1040862622180
-scope:
- description: The scope of the storage pool.
- returned: success
- type: str
- sample: cluster
-hypervisor:
- description: Hypervisor related to this storage pool.
- returned: when available
- type: str
- sample: KVM
-state:
- description: The state of the storage pool as returned by the API.
- returned: success
- type: str
- sample: Up
-allocation_state:
- description: The state of the storage pool.
- returned: success
- type: str
- sample: enabled
-path:
- description: The storage pool path used in the storage_url.
- returned: success
- type: str
- sample: poolname
-overprovision_factor:
- description: The overprovision factor of the storage pool.
- returned: success
- type: str
- sample: 2.0
-suitable_for_migration:
- description: Whether the storage pool is suitable to migrate a volume or not.
- returned: success
- type: bool
- sample: false
-storage_capabilities:
- description: Capabilities of the storage pool.
- returned: success
- type: dict
- sample: {"VOLUME_SNAPSHOT_QUIESCEVM": "false"}
-storage_tags:
- description: the tags for the storage pool.
- returned: success
- type: list
- sample: ["perf", "ssd"]
-'''
-
-# import cloudstack common
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackStoragePool(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackStoragePool, self).__init__(module)
- self.returns = {
- 'capacityiops': 'capacity_iops',
- 'podname': 'pod',
- 'clustername': 'cluster',
- 'disksizeallocated': 'disk_size_allocated',
- 'disksizetotal': 'disk_size_total',
- 'disksizeused': 'disk_size_used',
- 'scope': 'scope',
- 'hypervisor': 'hypervisor',
- 'type': 'type',
- 'ip_address': 'ipaddress',
- 'path': 'path',
- 'overprovisionfactor': 'overprovision_factor',
- 'storagecapabilities': 'storage_capabilities',
- 'suitableformigration': 'suitable_for_migration',
- }
- self.allocation_states = {
- # Host state: param state
- 'Up': 'enabled',
- 'Disabled': 'disabled',
- 'Maintenance': 'maintenance',
- }
- self.storage_pool = None
-
- def _get_common_args(self):
- return {
- 'name': self.module.params.get('name'),
- 'url': self.module.params.get('storage_url'),
- 'zoneid': self.get_zone(key='id'),
- 'provider': self.get_storage_provider(),
- 'scope': self.module.params.get('scope'),
- 'hypervisor': self.module.params.get('hypervisor'),
- 'capacitybytes': self.module.params.get('capacity_bytes'),
- 'capacityiops': self.module.params.get('capacity_iops'),
- }
-
- def _allocation_state_enabled_disabled_changed(self, pool, allocation_state):
- if allocation_state in ['enabled', 'disabled']:
- for pool_state, param_state in self.allocation_states.items():
- if pool_state == pool['state'] and allocation_state != param_state:
- return True
- return False
-
- def _handle_allocation_state(self, pool, state=None):
- allocation_state = state or self.module.params.get('allocation_state')
- if not allocation_state:
- return pool
-
- if self.allocation_states.get(pool['state']) == allocation_state:
- return pool
-
- # Cancel maintenance if target state is enabled/disabled
- elif allocation_state in ['enabled', 'disabled']:
- pool = self._cancel_maintenance(pool)
- pool = self._update_storage_pool(pool=pool, allocation_state=allocation_state)
-
- # Only an enabled host can put in maintenance
- elif allocation_state == 'maintenance':
- pool = self._update_storage_pool(pool=pool, allocation_state='enabled')
- pool = self._enable_maintenance(pool=pool)
-
- return pool
-
- def _create_storage_pool(self):
- args = self._get_common_args()
- args.update({
- 'clusterid': self.get_cluster(key='id'),
- 'podid': self.get_pod(key='id'),
- 'managed': self.module.params.get('managed'),
- })
-
- scope = self.module.params.get('scope')
- if scope is None:
- args['scope'] = 'cluster' if args['clusterid'] else 'zone'
-
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('createStoragePool', **args)
- return res['storagepool']
-
- def _update_storage_pool(self, pool, allocation_state=None):
- args = {
- 'id': pool['id'],
- 'capacitybytes': self.module.params.get('capacity_bytes'),
- 'capacityiops': self.module.params.get('capacity_iops'),
- 'tags': self.get_storage_tags(),
- }
-
- if self.has_changed(args, pool) or self._allocation_state_enabled_disabled_changed(pool, allocation_state):
- self.result['changed'] = True
- args['enabled'] = allocation_state == 'enabled' if allocation_state in ['enabled', 'disabled'] else None
- if not self.module.check_mode:
- res = self.query_api('updateStoragePool', **args)
- pool = res['storagepool']
- return pool
-
- def _enable_maintenance(self, pool):
- if pool['state'].lower() != "maintenance":
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('enableStorageMaintenance', id=pool['id'])
- pool = self.poll_job(res, 'storagepool')
- return pool
-
- def _cancel_maintenance(self, pool):
- if pool['state'].lower() == "maintenance":
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('cancelStorageMaintenance', id=pool['id'])
- pool = self.poll_job(res, 'storagepool')
- return pool
-
- def get_storage_tags(self):
- storage_tags = self.module.params.get('storage_tags')
- if storage_tags is None:
- return None
- return ','.join(storage_tags)
-
- def get_storage_pool(self, key=None):
- if self.storage_pool is None:
- zoneid = self.get_zone(key='id')
- clusterid = self.get_cluster(key='id')
- podid = self.get_pod(key='id')
-
- args = {
- 'zoneid': zoneid,
- 'podid': podid,
- 'clusterid': clusterid,
- 'name': self.module.params.get('name'),
- }
-
- res = self.query_api('listStoragePools', **args)
- if 'storagepool' not in res:
- return None
-
- self.storage_pool = res['storagepool'][0]
-
- return self.storage_pool
-
- def present_storage_pool(self):
- pool = self.get_storage_pool()
- if pool:
- pool = self._update_storage_pool(pool=pool)
- else:
- pool = self._create_storage_pool()
-
- if pool:
- pool = self._handle_allocation_state(pool=pool)
-
- return pool
-
- def absent_storage_pool(self):
- pool = self.get_storage_pool()
- if pool:
- self.result['changed'] = True
-
- args = {
- 'id': pool['id'],
- }
- if not self.module.check_mode:
- # Only a pool in maintenance can be deleted
- self._handle_allocation_state(pool=pool, state='maintenance')
- self.query_api('deleteStoragePool', **args)
- return pool
-
- def get_storage_provider(self, type="primary"):
- args = {
- 'type': type,
- }
- provider = self.module.params.get('provider')
- storage_providers = self.query_api('listStorageProviders', **args)
- for sp in storage_providers.get('dataStoreProvider') or []:
- if sp['name'].lower() == provider.lower():
- return provider
- self.fail_json(msg="Storage provider %s not found" % provider)
-
- def get_pod(self, key=None):
- pod = self.module.params.get('pod')
- if not pod:
- return None
- args = {
- 'name': pod,
- 'zoneid': self.get_zone(key='id'),
- }
- pods = self.query_api('listPods', **args)
- if pods:
- return self._get_by_key(key, pods['pod'][0])
-
- self.fail_json(msg="Pod %s not found" % self.module.params.get('pod'))
-
- def get_cluster(self, key=None):
- cluster = self.module.params.get('cluster')
- if not cluster:
- return None
-
- args = {
- 'name': cluster,
- 'zoneid': self.get_zone(key='id'),
- }
-
- clusters = self.query_api('listClusters', **args)
- if clusters:
- return self._get_by_key(key, clusters['cluster'][0])
-
- self.fail_json(msg="Cluster %s not found" % cluster)
-
- def get_result(self, pool):
- super(AnsibleCloudStackStoragePool, self).get_result(pool)
- if pool:
- self.result['storage_url'] = "%s://%s/%s" % (pool['type'], pool['ipaddress'], pool['path'])
- self.result['scope'] = pool['scope'].lower()
- self.result['storage_tags'] = pool['tags'].split(',') if pool.get('tags') else []
- self.result['allocation_state'] = self.allocation_states.get(pool['state'])
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- storage_url=dict(),
- zone=dict(),
- pod=dict(),
- cluster=dict(),
- scope=dict(choices=['zone', 'cluster']),
- hypervisor=dict(),
- provider=dict(default='DefaultPrimary'),
- capacity_bytes=dict(type='int'),
- capacity_iops=dict(type='int'),
- managed=dict(type='bool'),
- storage_tags=dict(type='list', aliases=['storage_tag']),
- allocation_state=dict(choices=['enabled', 'disabled', 'maintenance']),
- state=dict(choices=['present', 'absent'], default='present'),
- ))
-
- required_together = cs_required_together()
- required_together.extend([
- ['pod', 'cluster'],
- ])
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=required_together,
- required_if=[
- ('state', 'present', ['storage_url']),
- ],
- supports_check_mode=True
- )
-
- acs_storage_pool = AnsibleCloudStackStoragePool(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- pool = acs_storage_pool.absent_storage_pool()
- else:
- pool = acs_storage_pool.present_storage_pool()
-
- result = acs_storage_pool.get_result(pool)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_template.py b/lib/ansible/modules/cloud/cloudstack/cs_template.py
deleted file mode 100644
index d75b6307de..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_template.py
+++ /dev/null
@@ -1,745 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_template
-short_description: Manages templates on Apache CloudStack based clouds.
-description:
- - Register templates from an URL.
- - Create templates from a ROOT volume of a stopped VM or its snapshot.
- - Update (since version 2.7), extract and delete templates.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the template.
- type: str
- required: true
- url:
- description:
- - URL of where the template is hosted on I(state=present).
- - URL to which the template would be extracted on I(state=extracted).
- - Mutually exclusive with I(vm).
- type: str
- vm:
- description:
- - VM name the template will be created from its volume or alternatively from a snapshot.
- - VM must be in stopped state if created from its volume.
- - Mutually exclusive with I(url).
- type: str
- snapshot:
- description:
- - Name of the snapshot, created from the VM ROOT volume, the template will be created from.
- - I(vm) is required together with this argument.
- type: str
- os_type:
- description:
- - OS type that best represents the OS of this template.
- type: str
- checksum:
- description:
- - The MD5 checksum value of this template.
- - If set, we search by checksum instead of name.
- type: str
- is_ready:
- description:
- - "Note: this flag was not implemented and therefore marked as deprecated."
- - Deprecated, will be removed in version 2.11.
- type: bool
- is_public:
- description:
- - Register the template to be publicly available to all users.
- - Only used if I(state) is C(present).
- type: bool
- is_featured:
- description:
- - Register the template to be featured.
- - Only used if I(state) is C(present).
- type: bool
- is_dynamically_scalable:
- description:
- - Register the template having XS/VMware tools installed in order to support dynamic scaling of VM CPU/memory.
- - Only used if I(state) is C(present).
- type: bool
- cross_zones:
- description:
- - Whether the template should be synced or removed across zones.
- - Only used if I(state) is C(present) or C(absent).
- default: no
- type: bool
- mode:
- description:
- - Mode for the template extraction.
- - Only used if I(state=extracted).
- type: str
- default: http_download
- choices: [ http_download, ftp_upload ]
- domain:
- description:
- - Domain the template, snapshot or VM is related to.
- type: str
- account:
- description:
- - Account the template, snapshot or VM is related to.
- type: str
- project:
- description:
- - Name of the project the template to be registered in.
- type: str
- zone:
- description:
- - Name of the zone you wish the template to be registered or deleted from.
- - If not specified, first found zone will be used.
- type: str
- template_filter:
- description:
- - Name of the filter used to search for the template.
- - The filter C(all) was added in 2.7.
- type: str
- default: self
- choices: [ all, featured, self, selfexecutable, sharedexecutable, executable, community ]
- template_find_options:
- description:
- - Options to find a template uniquely.
- - More than one allowed.
- type: list
- choices: [ display_text, checksum, cross_zones ]
- version_added: '2.7'
- aliases: [ template_find_option ]
- default: []
- hypervisor:
- description:
- - Name the hypervisor to be used for creating the new template.
- - Relevant when using I(state=present).
- - Possible values are C(KVM), C(VMware), C(BareMetal), C(XenServer), C(LXC), C(HyperV), C(UCS), C(OVM), C(Simulator).
- type: str
- requires_hvm:
- description:
- - Whether the template requires HVM or not.
- - Only considered while creating the template.
- type: bool
- password_enabled:
- description:
- - Enable template password reset support.
- type: bool
- template_tag:
- description:
- - The tag for this template.
- type: str
- sshkey_enabled:
- description:
- - True if the template supports the sshkey upload feature.
- - Only considered if I(url) is used (API limitation).
- type: bool
- is_routing:
- description:
- - Sets the template type to routing, i.e. if template is used to deploy routers.
- - Only considered if I(url) is used.
- type: bool
- format:
- description:
- - The format for the template.
- - Only considered if I(state=present).
- type: str
- choices: [ QCOW2, RAW, VHD, OVA ]
- is_extractable:
- description:
- - Allows the template or its derivatives to be extractable.
- type: bool
- details:
- description:
- - Template details in key/value pairs.
- type: str
- bits:
- description:
- - 32 or 64 bits support.
- type: int
- default: 64
- choices: [ 32, 64 ]
- display_text:
- description:
- - Display text of the template.
- type: str
- state:
- description:
- - State of the template.
- type: str
- default: present
- choices: [ present, absent, extracted ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: register a systemvm template
- cs_template:
- name: systemvm-vmware-4.5
- url: "http://packages.shapeblue.com/systemvmtemplate/4.5/systemvm64template-4.5-vmware.ova"
- hypervisor: VMware
- format: OVA
- cross_zones: yes
- os_type: Debian GNU/Linux 7(64-bit)
- delegate_to: localhost
-
-- name: Create a template from a stopped virtual machine's volume
- cs_template:
- name: Debian 9 (64-bit) 20GB ({{ ansible_date_time.date }})
- vm: debian-9-base-vm
- os_type: Debian GNU/Linux 9 (64-bit)
- zone: tokio-ix
- password_enabled: yes
- is_public: yes
- delegate_to: localhost
-
-# Note: Use template_find_option(s) when a template name is not unique
-- name: Create a template from a stopped virtual machine's volume
- cs_template:
- name: Debian 9 (64-bit)
- display_text: Debian 9 (64-bit) 20GB ({{ ansible_date_time.date }})
- template_find_option: display_text
- vm: debian-9-base-vm
- os_type: Debian GNU/Linux 9 (64-bit)
- zone: tokio-ix
- password_enabled: yes
- is_public: yes
- delegate_to: localhost
-
-- name: create a template from a virtual machine's root volume snapshot
- cs_template:
- name: Debian 9 (64-bit) Snapshot ROOT-233_2015061509114
- snapshot: ROOT-233_2015061509114
- os_type: Debian GNU/Linux 9 (64-bit)
- zone: tokio-ix
- password_enabled: yes
- is_public: yes
- delegate_to: localhost
-
-- name: Remove a template
- cs_template:
- name: systemvm-4.2
- cross_zones: yes
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the template or extracted object.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: Name of the template or extracted object.
- returned: success
- type: str
- sample: Debian 7 64-bit
-display_text:
- description: Display text of the template.
- returned: if available
- type: str
- sample: Debian 7.7 64-bit minimal 2015-03-19
-checksum:
- description: MD5 checksum of the template.
- returned: if available
- type: str
- sample: 0b31bccccb048d20b551f70830bb7ad0
-status:
- description: Status of the template or extracted object.
- returned: success
- type: str
- sample: Download Complete
-is_ready:
- description: True if the template is ready to be deployed from.
- returned: if available
- type: bool
- sample: true
-is_public:
- description: True if the template is public.
- returned: if available
- type: bool
- sample: true
-is_featured:
- description: True if the template is featured.
- returned: if available
- type: bool
- sample: true
-is_extractable:
- description: True if the template is extractable.
- returned: if available
- type: bool
- sample: true
-format:
- description: Format of the template.
- returned: if available
- type: str
- sample: OVA
-os_type:
- description: Type of the OS.
- returned: if available
- type: str
- sample: CentOS 6.5 (64-bit)
-password_enabled:
- description: True if the reset password feature is enabled, false otherwise.
- returned: if available
- type: bool
- sample: false
-sshkey_enabled:
- description: true if template is sshkey enabled, false otherwise.
- returned: if available
- type: bool
- sample: false
-cross_zones:
- description: true if the template is managed across all zones, false otherwise.
- returned: if available
- type: bool
- sample: false
-template_type:
- description: Type of the template.
- returned: if available
- type: str
- sample: USER
-created:
- description: Date of registering.
- returned: success
- type: str
- sample: 2015-03-29T14:57:06+0200
-template_tag:
- description: Template tag related to this template.
- returned: if available
- type: str
- sample: special
-hypervisor:
- description: Hypervisor related to this template.
- returned: if available
- type: str
- sample: VMware
-mode:
- description: Mode of extraction
- returned: on state=extracted
- type: str
- sample: http_download
-state:
- description: State of the extracted template
- returned: on state=extracted
- type: str
- sample: DOWNLOAD_URL_CREATED
-url:
- description: Url to which the template is extracted to
- returned: on state=extracted
- type: str
- sample: "http://1.2.3.4/userdata/eb307f13-4aca-45e8-b157-a414a14e6b04.ova"
-tags:
- description: List of resource tags associated with the template.
- returned: if available
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-zone:
- description: Name of zone the template is registered in.
- returned: success
- type: str
- sample: zuerich
-domain:
- description: Domain the template is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the template is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the template is related to.
- returned: success
- type: str
- sample: Production
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackTemplate(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackTemplate, self).__init__(module)
- self.returns = {
- 'checksum': 'checksum',
- 'status': 'status',
- 'isready': 'is_ready',
- 'templatetag': 'template_tag',
- 'sshkeyenabled': 'sshkey_enabled',
- 'passwordenabled': 'password_enabled',
- 'templatetype': 'template_type',
- 'ostypename': 'os_type',
- 'crossZones': 'cross_zones',
- 'format': 'format',
- 'hypervisor': 'hypervisor',
- 'url': 'url',
- 'extractMode': 'mode',
- 'state': 'state',
- }
-
- def _get_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'bits': self.module.params.get('bits'),
- 'isdynamicallyscalable': self.module.params.get('is_dynamically_scalable'),
- 'isextractable': self.module.params.get('is_extractable'),
- 'isfeatured': self.module.params.get('is_featured'),
- 'ispublic': self.module.params.get('is_public'),
- 'passwordenabled': self.module.params.get('password_enabled'),
- 'requireshvm': self.module.params.get('requires_hvm'),
- 'templatetag': self.module.params.get('template_tag'),
- 'ostypeid': self.get_os_type(key='id'),
- }
-
- if not args['ostypeid']:
- self.module.fail_json(msg="Missing required arguments: os_type")
-
- return args
-
- def get_root_volume(self, key=None):
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'virtualmachineid': self.get_vm(key='id'),
- 'type': "ROOT"
- }
- volumes = self.query_api('listVolumes', **args)
- if volumes:
- return self._get_by_key(key, volumes['volume'][0])
- self.module.fail_json(msg="Root volume for '%s' not found" % self.get_vm('name'))
-
- def get_snapshot(self, key=None):
- snapshot = self.module.params.get('snapshot')
- if not snapshot:
- return None
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'volumeid': self.get_root_volume('id'),
- 'fetch_list': True,
- }
- snapshots = self.query_api('listSnapshots', **args)
- if snapshots:
- for s in snapshots:
- if snapshot in [s['name'], s['id']]:
- return self._get_by_key(key, s)
- self.module.fail_json(msg="Snapshot '%s' not found" % snapshot)
-
- def present_template(self):
- template = self.get_template()
- if template:
- template = self.update_template(template)
- elif self.module.params.get('url'):
- template = self.register_template()
- elif self.module.params.get('vm'):
- template = self.create_template()
- else:
- self.fail_json(msg="one of the following is required on state=present: url, vm")
- return template
-
- def create_template(self):
- template = None
- self.result['changed'] = True
-
- args = self._get_args()
- snapshot_id = self.get_snapshot(key='id')
- if snapshot_id:
- args['snapshotid'] = snapshot_id
- else:
- args['volumeid'] = self.get_root_volume('id')
-
- if not self.module.check_mode:
- template = self.query_api('createTemplate', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- template = self.poll_job(template, 'template')
-
- if template:
- template = self.ensure_tags(resource=template, resource_type='Template')
-
- return template
-
- def register_template(self):
- required_params = [
- 'format',
- 'url',
- 'hypervisor',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
- template = None
- self.result['changed'] = True
- args = self._get_args()
- args.update({
- 'url': self.module.params.get('url'),
- 'format': self.module.params.get('format'),
- 'checksum': self.module.params.get('checksum'),
- 'isextractable': self.module.params.get('is_extractable'),
- 'isrouting': self.module.params.get('is_routing'),
- 'sshkeyenabled': self.module.params.get('sshkey_enabled'),
- 'hypervisor': self.get_hypervisor(),
- 'domainid': self.get_domain(key='id'),
- 'account': self.get_account(key='name'),
- 'projectid': self.get_project(key='id'),
- })
-
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
- else:
- args['zoneid'] = -1
-
- if not self.module.check_mode:
- self.query_api('registerTemplate', **args)
- template = self.get_template()
- return template
-
- def update_template(self, template):
- args = {
- 'id': template['id'],
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'format': self.module.params.get('format'),
- 'isdynamicallyscalable': self.module.params.get('is_dynamically_scalable'),
- 'isrouting': self.module.params.get('is_routing'),
- 'ostypeid': self.get_os_type(key='id'),
- 'passwordenabled': self.module.params.get('password_enabled'),
- }
- if self.has_changed(args, template):
- self.result['changed'] = True
- if not self.module.check_mode:
- self.query_api('updateTemplate', **args)
- template = self.get_template()
-
- args = {
- 'id': template['id'],
- 'isextractable': self.module.params.get('is_extractable'),
- 'isfeatured': self.module.params.get('is_featured'),
- 'ispublic': self.module.params.get('is_public'),
- }
- if self.has_changed(args, template):
- self.result['changed'] = True
- if not self.module.check_mode:
- self.query_api('updateTemplatePermissions', **args)
- # Refresh
- template = self.get_template()
-
- if template:
- template = self.ensure_tags(resource=template, resource_type='Template')
-
- return template
-
- def _is_find_option(self, param_name):
- return param_name in self.module.params.get('template_find_options')
-
- def _find_option_match(self, template, param_name, internal_name=None):
- if not internal_name:
- internal_name = param_name
-
- if param_name in self.module.params.get('template_find_options'):
- param_value = self.module.params.get(param_name)
-
- if not param_value:
- self.fail_json(msg="The param template_find_options has %s but param was not provided." % param_name)
-
- if template[internal_name] == param_value:
- return True
- return False
-
- def get_template(self):
- args = {
- 'name': self.module.params.get('name'),
- 'templatefilter': self.module.params.get('template_filter'),
- 'domainid': self.get_domain(key='id'),
- 'account': self.get_account(key='name'),
- 'projectid': self.get_project(key='id')
- }
-
- cross_zones = self.module.params.get('cross_zones')
- if not cross_zones:
- args['zoneid'] = self.get_zone(key='id')
-
- template_found = None
-
- templates = self.query_api('listTemplates', **args)
- if templates:
- for tmpl in templates['template']:
-
- if self._is_find_option('cross_zones') and not self._find_option_match(
- template=tmpl,
- param_name='cross_zones',
- internal_name='crossZones'):
- continue
-
- if self._is_find_option('checksum') and not self._find_option_match(
- template=tmpl,
- param_name='checksum'):
- continue
-
- if self._is_find_option('display_text') and not self._find_option_match(
- template=tmpl,
- param_name='display_text',
- internal_name='displaytext'):
- continue
-
- if not template_found:
- template_found = tmpl
- # A cross zones template has one entry per zone but the same id
- elif tmpl['id'] == template_found['id']:
- continue
- else:
- self.fail_json(msg="Multiple templates found matching provided params. Please use template_find_options.")
-
- return template_found
-
- def extract_template(self):
- template = self.get_template()
- if not template:
- self.module.fail_json(msg="Failed: template not found")
-
- args = {
- 'id': template['id'],
- 'url': self.module.params.get('url'),
- 'mode': self.module.params.get('mode'),
- 'zoneid': self.get_zone(key='id')
- }
- self.result['changed'] = True
-
- if not self.module.check_mode:
- template = self.query_api('extractTemplate', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- template = self.poll_job(template, 'template')
- return template
-
- def remove_template(self):
- template = self.get_template()
- if template:
- self.result['changed'] = True
-
- args = {
- 'id': template['id']
- }
- if not self.module.params.get('cross_zones'):
- args['zoneid'] = self.get_zone(key='id')
-
- if not self.module.check_mode:
- res = self.query_api('deleteTemplate', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- res = self.poll_job(res, 'template')
- return template
-
- def get_result(self, template):
- super(AnsibleCloudStackTemplate, self).get_result(template)
- if template:
- if 'isextractable' in template:
- self.result['is_extractable'] = True if template['isextractable'] else False
- if 'isfeatured' in template:
- self.result['is_featured'] = True if template['isfeatured'] else False
- if 'ispublic' in template:
- self.result['is_public'] = True if template['ispublic'] else False
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- url=dict(),
- vm=dict(),
- snapshot=dict(),
- os_type=dict(),
- is_ready=dict(type='bool', removed_in_version='2.11'),
- is_public=dict(type='bool'),
- is_featured=dict(type='bool'),
- is_dynamically_scalable=dict(type='bool'),
- is_extractable=dict(type='bool'),
- is_routing=dict(type='bool'),
- checksum=dict(),
- template_filter=dict(default='self', choices=['all', 'featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community']),
- template_find_options=dict(type='list', choices=['display_text', 'checksum', 'cross_zones'], aliases=['template_find_option'], default=[]),
- hypervisor=dict(),
- requires_hvm=dict(type='bool'),
- password_enabled=dict(type='bool'),
- template_tag=dict(),
- sshkey_enabled=dict(type='bool'),
- format=dict(choices=['QCOW2', 'RAW', 'VHD', 'OVA']),
- details=dict(),
- bits=dict(type='int', choices=[32, 64], default=64),
- state=dict(choices=['present', 'absent', 'extracted'], default='present'),
- cross_zones=dict(type='bool', default=False),
- mode=dict(choices=['http_download', 'ftp_upload'], default='http_download'),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['url', 'vm'],
- ['zone', 'cross_zones'],
- ),
- supports_check_mode=True
- )
-
- acs_tpl = AnsibleCloudStackTemplate(module)
-
- state = module.params.get('state')
- if state == 'absent':
- tpl = acs_tpl.remove_template()
-
- elif state == 'extracted':
- tpl = acs_tpl.extract_template()
- else:
- tpl = acs_tpl.present_template()
-
- result = acs_tpl.get_result(tpl)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_traffic_type.py b/lib/ansible/modules/cloud/cloudstack/cs_traffic_type.py
deleted file mode 100644
index 87c2e199f3..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_traffic_type.py
+++ /dev/null
@@ -1,326 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2019, Patryk D. Cichy <patryk.d.cichy@gmail.com>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_traffic_type
-short_description: Manages traffic types on CloudStack Physical Networks
-description:
- - Add, remove, update Traffic Types associated with CloudStack Physical Networks.
-extends_documentation_fragment: cloudstack
-version_added: "2.8"
-author:
- - Patryk Cichy (@PatTheSilent)
-options:
- physical_network:
- description:
- - the name of the Physical Network
- required: true
- type: str
- zone:
- description:
- - Name of the zone with the physical network.
- - Default zone will be used if this is empty.
- type: str
- traffic_type:
- description:
- - the trafficType to be added to the physical network.
- required: true
- choices: [Management, Guest, Public, Storage]
- type: str
- state:
- description:
- - State of the traffic type
- choices: [present, absent]
- default: present
- type: str
- hyperv_networklabel:
- description:
- - The network name label of the physical device dedicated to this traffic on a HyperV host.
- type: str
- isolation_method:
- description:
- - Use if the physical network has multiple isolation types and traffic type is public.
- choices: [vlan, vxlan]
- type: str
- kvm_networklabel:
- description:
- - The network name label of the physical device dedicated to this traffic on a KVM host.
- type: str
- ovm3_networklabel:
- description:
- - The network name of the physical device dedicated to this traffic on an OVM3 host.
- type: str
- vlan:
- description:
- - The VLAN id to be used for Management traffic by VMware host.
- type: str
- vmware_networklabel:
- description:
- - The network name label of the physical device dedicated to this traffic on a VMware host.
- type: str
- xen_networklabel:
- description:
- - The network name label of the physical device dedicated to this traffic on a XenServer host.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-'''
-
-EXAMPLES = '''
-- name: add a traffic type
- cs_traffic_type:
- physical_network: public-network
- traffic_type: Guest
- zone: test-zone
- delegate_to: localhost
-
-- name: update traffic type
- cs_traffic_type:
- physical_network: public-network
- traffic_type: Guest
- kvm_networklabel: cloudbr0
- zone: test-zone
- delegate_to: localhost
-
-- name: remove traffic type
- cs_traffic_type:
- physical_network: public-network
- traffic_type: Public
- state: absent
- zone: test-zone
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: ID of the network provider
- returned: success
- type: str
- sample: 659c1840-9374-440d-a412-55ca360c9d3c
-traffic_type:
- description: the trafficType that was added to the physical network
- returned: success
- type: str
- sample: Public
-hyperv_networklabel:
- description: The network name label of the physical device dedicated to this traffic on a HyperV host
- returned: success
- type: str
- sample: HyperV Internal Switch
-kvm_networklabel:
- description: The network name label of the physical device dedicated to this traffic on a KVM host
- returned: success
- type: str
- sample: cloudbr0
-ovm3_networklabel:
- description: The network name of the physical device dedicated to this traffic on an OVM3 host
- returned: success
- type: str
- sample: cloudbr0
-physical_network:
- description: the physical network this belongs to
- returned: success
- type: str
- sample: 28ed70b7-9a1f-41bf-94c3-53a9f22da8b6
-vmware_networklabel:
- description: The network name label of the physical device dedicated to this traffic on a VMware host
- returned: success
- type: str
- sample: Management Network
-xen_networklabel:
- description: The network name label of the physical device dedicated to this traffic on a XenServer host
- returned: success
- type: str
- sample: xenbr0
-zone:
- description: Name of zone the physical network is in.
- returned: success
- type: str
- sample: ch-gva-2
-'''
-
-from ansible.module_utils.cloudstack import AnsibleCloudStack, cs_argument_spec, cs_required_together
-from ansible.module_utils.basic import AnsibleModule
-
-
-class AnsibleCloudStackTrafficType(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackTrafficType, self).__init__(module)
- self.returns = {
- 'traffictype': 'traffic_type',
- 'hypervnetworklabel': 'hyperv_networklabel',
- 'kvmnetworklabel': 'kvm_networklabel',
- 'ovm3networklabel': 'ovm3_networklabel',
- 'physicalnetworkid': 'physical_network',
- 'vmwarenetworklabel': 'vmware_networklabel',
- 'xennetworklabel': 'xen_networklabel'
- }
-
- self.traffic_type = None
-
- def _get_label_args(self):
- label_args = dict()
- if self.module.params.get('hyperv_networklabel'):
- label_args.update(dict(hypervnetworklabel=self.module.params.get('hyperv_networklabel')))
- if self.module.params.get('kvm_networklabel'):
- label_args.update(dict(kvmnetworklabel=self.module.params.get('kvm_networklabel')))
- if self.module.params.get('ovm3_networklabel'):
- label_args.update(dict(ovm3networklabel=self.module.params.get('ovm3_networklabel')))
- if self.module.params.get('vmware_networklabel'):
- label_args.update(dict(vmwarenetworklabel=self.module.params.get('vmware_networklabel')))
- return label_args
-
- def _get_additional_args(self):
- additional_args = dict()
-
- if self.module.params.get('isolation_method'):
- additional_args.update(dict(isolationmethod=self.module.params.get('isolation_method')))
-
- if self.module.params.get('vlan'):
- additional_args.update(dict(vlan=self.module.params.get('vlan')))
-
- additional_args.update(self._get_label_args())
-
- return additional_args
-
- def get_traffic_types(self):
- args = {
- 'physicalnetworkid': self.get_physical_network(key='id')
- }
- traffic_types = self.query_api('listTrafficTypes', **args)
- return traffic_types
-
- def get_traffic_type(self):
- if self.traffic_type:
- return self.traffic_type
-
- traffic_type = self.module.params.get('traffic_type')
-
- traffic_types = self.get_traffic_types()
-
- if traffic_types:
- for t_type in traffic_types['traffictype']:
- if traffic_type.lower() in [t_type['traffictype'].lower(), t_type['id']]:
- self.traffic_type = t_type
- break
- return self.traffic_type
-
- def present_traffic_type(self):
- traffic_type = self.get_traffic_type()
- if traffic_type:
- self.traffic_type = self.update_traffic_type()
- else:
- self.result['changed'] = True
- self.traffic_type = self.add_traffic_type()
-
- return self.traffic_type
-
- def add_traffic_type(self):
- traffic_type = self.module.params.get('traffic_type')
- args = {
- 'physicalnetworkid': self.get_physical_network(key='id'),
- 'traffictype': traffic_type
- }
- args.update(self._get_additional_args())
- if not self.module.check_mode:
- resource = self.query_api('addTrafficType', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.traffic_type = self.poll_job(resource, 'traffictype')
- return self.traffic_type
-
- def absent_traffic_type(self):
- traffic_type = self.get_traffic_type()
- if traffic_type:
-
- args = {
- 'id': traffic_type['id']
- }
- self.result['changed'] = True
- if not self.module.check_mode:
- resource = self.query_api('deleteTrafficType', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(resource, 'traffictype')
-
- return traffic_type
-
- def update_traffic_type(self):
-
- traffic_type = self.get_traffic_type()
- args = {
- 'id': traffic_type['id']
- }
- args.update(self._get_label_args())
- if self.has_changed(args, traffic_type):
- self.result['changed'] = True
- if not self.module.check_mode:
- resource = self.query_api('updateTrafficType', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.traffic_type = self.poll_job(resource, 'traffictype')
-
- return self.traffic_type
-
-
-def setup_module_object():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- physical_network=dict(required=True),
- zone=dict(),
- state=dict(choices=['present', 'absent'], default='present'),
- traffic_type=dict(required=True, choices=['Management', 'Guest', 'Public', 'Storage']),
- hyperv_networklabel=dict(),
- isolation_method=dict(choices=['vlan', 'vxlan']),
- kvm_networklabel=dict(),
- ovm3_networklabel=dict(),
- vlan=dict(),
- vmware_networklabel=dict(),
- xen_networklabel=dict(),
- poll_async=dict(type='bool', default=True)
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
- return module
-
-
-def execute_module(module):
- actt = AnsibleCloudStackTrafficType(module)
- state = module.params.get('state')
-
- if state in ['present']:
- result = actt.present_traffic_type()
- else:
- result = actt.absent_traffic_type()
-
- return actt.get_result(result)
-
-
-def main():
- module = setup_module_object()
- result = execute_module(module)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_user.py b/lib/ansible/modules/cloud/cloudstack/cs_user.py
deleted file mode 100644
index 79342c7223..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_user.py
+++ /dev/null
@@ -1,445 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_user
-short_description: Manages users on Apache CloudStack based clouds.
-description:
- - Create, update, disable, lock, enable and remove users.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- username:
- description:
- - Username of the user.
- type: str
- required: true
- account:
- description:
- - Account the user will be created under.
- - Required on I(state=present).
- type: str
- password:
- description:
- - Password of the user to be created.
- - Required on I(state=present).
- - Only considered on creation and will not be updated if user exists.
- type: str
- first_name:
- description:
- - First name of the user.
- - Required on I(state=present).
- type: str
- last_name:
- description:
- - Last name of the user.
- - Required on I(state=present).
- type: str
- email:
- description:
- - Email of the user.
- - Required on I(state=present).
- type: str
- timezone:
- description:
- - Timezone of the user.
- type: str
- keys_registered:
- description:
- - If API keys of the user should be generated.
- - "Note: Keys can not be removed by the API again."
- version_added: '2.4'
- type: bool
- default: no
- domain:
- description:
- - Domain the user is related to.
- type: str
- default: ROOT
- state:
- description:
- - State of the user.
- - C(unlocked) is an alias for C(enabled).
- type: str
- default: present
- choices: [ present, absent, enabled, disabled, locked, unlocked ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create an user in domain 'CUSTOMERS'
- cs_user:
- account: developers
- username: johndoe
- password: S3Cur3
- last_name: Doe
- first_name: John
- email: john.doe@example.com
- domain: CUSTOMERS
- delegate_to: localhost
-
-- name: Lock an existing user in domain 'CUSTOMERS'
- cs_user:
- username: johndoe
- domain: CUSTOMERS
- state: locked
- delegate_to: localhost
-
-- name: Disable an existing user in domain 'CUSTOMERS'
- cs_user:
- username: johndoe
- domain: CUSTOMERS
- state: disabled
- delegate_to: localhost
-
-- name: Enable/unlock an existing user in domain 'CUSTOMERS'
- cs_user:
- username: johndoe
- domain: CUSTOMERS
- state: enabled
- delegate_to: localhost
-
-- name: Remove an user in domain 'CUSTOMERS'
- cs_user:
- name: customer_xy
- domain: CUSTOMERS
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the user.
- returned: success
- type: str
- sample: 87b1e0ce-4e01-11e4-bb66-0050569e64b8
-username:
- description: Username of the user.
- returned: success
- type: str
- sample: johndoe
-fist_name:
- description: First name of the user.
- returned: success
- type: str
- sample: John
-last_name:
- description: Last name of the user.
- returned: success
- type: str
- sample: Doe
-email:
- description: Emailof the user.
- returned: success
- type: str
- sample: john.doe@example.com
-user_api_key:
- description: API key of the user.
- returned: success
- type: str
- sample: JLhcg8VWi8DoFqL2sSLZMXmGojcLnFrOBTipvBHJjySODcV4mCOo29W2duzPv5cALaZnXj5QxDx3xQfaQt3DKg
-user_api_secret:
- description: API secret of the user.
- returned: success
- type: str
- sample: FUELo3LB9fa1UopjTLPdqLv_6OXQMJZv9g9N4B_Ao3HFz8d6IGFCV9MbPFNM8mwz00wbMevja1DoUNDvI8C9-g
-account:
- description: Account name of the user.
- returned: success
- type: str
- sample: developers
-account_type:
- description: Type of the account.
- returned: success
- type: str
- sample: user
-timezone:
- description: Timezone of the user.
- returned: success
- type: str
- sample: enabled
-created:
- description: Date the user was created.
- returned: success
- type: str
- sample: Doe
-state:
- description: State of the user.
- returned: success
- type: str
- sample: enabled
-domain:
- description: Domain the user is related.
- returned: success
- type: str
- sample: ROOT
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackUser(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackUser, self).__init__(module)
- self.returns = {
- 'username': 'username',
- 'firstname': 'first_name',
- 'lastname': 'last_name',
- 'email': 'email',
- 'secretkey': 'user_api_secret',
- 'apikey': 'user_api_key',
- 'timezone': 'timezone',
- }
- self.account_types = {
- 'user': 0,
- 'root_admin': 1,
- 'domain_admin': 2,
- }
- self.user = None
-
- def get_account_type(self):
- account_type = self.module.params.get('account_type')
- return self.account_types[account_type]
-
- def get_user(self):
- if not self.user:
- args = {
- 'domainid': self.get_domain('id'),
- 'fetch_list': True,
- }
-
- users = self.query_api('listUsers', **args)
-
- if users:
- user_name = self.module.params.get('username')
- for u in users:
- if user_name.lower() == u['username'].lower():
- self.user = u
- break
- return self.user
-
- def enable_user(self):
- user = self.get_user()
- if not user:
- user = self.present_user()
-
- if user['state'].lower() != 'enabled':
- self.result['changed'] = True
- args = {
- 'id': user['id'],
- }
- if not self.module.check_mode:
- res = self.query_api('enableUser', **args)
- user = res['user']
- return user
-
- def lock_user(self):
- user = self.get_user()
- if not user:
- user = self.present_user()
-
- # we need to enable the user to lock it.
- if user['state'].lower() == 'disabled':
- user = self.enable_user()
-
- if user['state'].lower() != 'locked':
- self.result['changed'] = True
-
- args = {
- 'id': user['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('lockUser', **args)
- user = res['user']
-
- return user
-
- def disable_user(self):
- user = self.get_user()
- if not user:
- user = self.present_user()
-
- if user['state'].lower() != 'disabled':
- self.result['changed'] = True
- args = {
- 'id': user['id'],
- }
- if not self.module.check_mode:
- user = self.query_api('disableUser', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- user = self.poll_job(user, 'user')
- return user
-
- def present_user(self):
- required_params = [
- 'account',
- 'email',
- 'password',
- 'first_name',
- 'last_name',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- user = self.get_user()
- if user:
- user = self._update_user(user)
- else:
- user = self._create_user(user)
- return user
-
- def _get_common_args(self):
- return {
- 'firstname': self.module.params.get('first_name'),
- 'lastname': self.module.params.get('last_name'),
- 'email': self.module.params.get('email'),
- 'timezone': self.module.params.get('timezone'),
- }
-
- def _create_user(self, user):
- self.result['changed'] = True
-
- args = self._get_common_args()
- args.update({
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain('id'),
- 'username': self.module.params.get('username'),
- 'password': self.module.params.get('password'),
- })
-
- if not self.module.check_mode:
- res = self.query_api('createUser', **args)
- user = res['user']
-
- # register user api keys
- if self.module.params.get('keys_registered'):
- res = self.query_api('registerUserKeys', id=user['id'])
- user.update(res['userkeys'])
-
- return user
-
- def _update_user(self, user):
- args = self._get_common_args()
- args.update({
- 'id': user['id'],
- })
-
- if self.has_changed(args, user):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateUser', **args)
-
- user = res['user']
-
- # register user api keys
- if 'apikey' not in user and self.module.params.get('keys_registered'):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('registerUserKeys', id=user['id'])
- user.update(res['userkeys'])
- return user
-
- def absent_user(self):
- user = self.get_user()
- if user:
- self.result['changed'] = True
-
- if not self.module.check_mode:
- self.query_api('deleteUser', id=user['id'])
-
- return user
-
- def get_result(self, user):
- super(AnsibleCloudStackUser, self).get_result(user)
- if user:
- if 'accounttype' in user:
- for key, value in self.account_types.items():
- if value == user['accounttype']:
- self.result['account_type'] = key
- break
-
- # secretkey has been removed since CloudStack 4.10 from listUsers API
- if self.module.params.get('keys_registered') and 'apikey' in user and 'secretkey' not in user:
- user_keys = self.query_api('getUserKeys', id=user['id'])
- if user_keys:
- self.result['user_api_secret'] = user_keys['userkeys'].get('secretkey')
-
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- username=dict(required=True),
- account=dict(),
- state=dict(choices=['present', 'absent', 'enabled', 'disabled', 'locked', 'unlocked'], default='present'),
- domain=dict(default='ROOT'),
- email=dict(),
- first_name=dict(),
- last_name=dict(),
- password=dict(no_log=True),
- timezone=dict(),
- keys_registered=dict(type='bool', default=False),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_acc = AnsibleCloudStackUser(module)
-
- state = module.params.get('state')
-
- if state == 'absent':
- user = acs_acc.absent_user()
-
- elif state in ['enabled', 'unlocked']:
- user = acs_acc.enable_user()
-
- elif state == 'disabled':
- user = acs_acc.disable_user()
-
- elif state == 'locked':
- user = acs_acc.lock_user()
-
- else:
- user = acs_acc.present_user()
-
- result = acs_acc.get_result(user)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vlan_ip_range.py b/lib/ansible/modules/cloud/cloudstack/cs_vlan_ip_range.py
deleted file mode 100644
index b83a45d7b3..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vlan_ip_range.py
+++ /dev/null
@@ -1,387 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2018, David Passante <@dpassante>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_vlan_ip_range
-short_description: Manages VLAN IP ranges on Apache CloudStack based clouds.
-description:
- - Create and delete VLAN IP range.
-version_added: '2.8'
-author: David Passante (@dpassante)
-options:
- network:
- description:
- - The network name or id.
- - Required if I(for_virtual_network) and I(physical_network) are not set.
- type: str
- physical_network:
- description:
- - The physical network name or id.
- type: str
- start_ip:
- description:
- - The beginning IPv4 address in the VLAN IP range.
- - Only considered on create.
- type: str
- required: true
- end_ip:
- description:
- - The ending IPv4 address in the VLAN IP range.
- - If not specified, value of I(start_ip) is used.
- - Only considered on create.
- type: str
- gateway:
- description:
- - The gateway of the VLAN IP range.
- - Required if I(state=present).
- type: str
- netmask:
- description:
- - The netmask of the VLAN IP range.
- - Required if I(state=present).
- type: str
- start_ipv6:
- description:
- - The beginning IPv6 address in the IPv6 network range.
- - Only considered on create.
- type: str
- end_ipv6:
- description:
- - The ending IPv6 address in the IPv6 network range.
- - If not specified, value of I(start_ipv6) is used.
- - Only considered on create.
- type: str
- gateway_ipv6:
- description:
- - The gateway of the IPv6 network.
- - Only considered on create.
- type: str
- cidr_ipv6:
- description:
- - The CIDR of IPv6 network, must be at least /64.
- type: str
- vlan:
- description:
- - The ID or VID of the network.
- - If not specified, will be defaulted to the vlan of the network.
- type: str
- state:
- description:
- - State of the network ip range.
- type: str
- default: present
- choices: [ present, absent ]
- zone:
- description:
- - The Zone ID of the VLAN IP range.
- - If not set, default zone is used.
- type: str
- domain:
- description:
- - Domain of the account owning the VLAN.
- type: str
- account:
- description:
- - Account who owns the VLAN.
- - Mutually exclusive with I(project).
- type: str
- project:
- description:
- - Project who owns the VLAN.
- - Mutually exclusive with I(account).
- type: str
- for_virtual_network:
- description:
- - C(yes) if VLAN is of Virtual type, C(no) if Direct.
- - If set to C(yes) but neither I(physical_network) or I(network) is set CloudStack will try to add the
- VLAN range to the Physical Network with a Public traffic type.
- type: bool
- default: no
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create a VLAN IP range for network test
- cs_vlan_ip_range:
- network: test
- vlan: 98
- start_ip: 10.2.4.10
- end_ip: 10.2.4.100
- gateway: 10.2.4.1
- netmask: 255.255.255.0
- zone: zone-02
- delegate_to: localhost
-
-- name: remove a VLAN IP range for network test
- cs_vlan_ip_range:
- state: absent
- network: test
- start_ip: 10.2.4.10
- end_ip: 10.2.4.100
- zone: zone-02
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the VLAN IP range.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-network:
- description: The network of vlan range
- returned: if available
- type: str
- sample: test
-vlan:
- description: The ID or VID of the VLAN.
- returned: success
- type: str
- sample: vlan://98
-gateway:
- description: IPv4 gateway.
- returned: success
- type: str
- sample: 10.2.4.1
-netmask:
- description: IPv4 netmask.
- returned: success
- type: str
- sample: 255.255.255.0
-gateway_ipv6:
- description: IPv6 gateway.
- returned: if available
- type: str
- sample: 2001:db8::1
-cidr_ipv6:
- description: The CIDR of IPv6 network.
- returned: if available
- type: str
- sample: 2001:db8::/64
-zone:
- description: Name of zone.
- returned: success
- type: str
- sample: zone-02
-domain:
- description: Domain name of the VLAN IP range.
- returned: success
- type: str
- sample: ROOT
-account:
- description: Account who owns the network.
- returned: if available
- type: str
- sample: example account
-project:
- description: Project who owns the network.
- returned: if available
- type: str
- sample: example project
-for_systemvms:
- description: Whether VLAN IP range is dedicated to system vms or not.
- returned: success
- type: bool
- sample: false
-for_virtual_network:
- description: Whether VLAN IP range is of Virtual type or not.
- returned: success
- type: bool
- sample: false
-physical_network:
- description: The physical network VLAN IP range belongs to.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-start_ip:
- description: The start ip of the VLAN IP range.
- returned: success
- type: str
- sample: 10.2.4.10
-end_ip:
- description: The end ip of the VLAN IP range.
- returned: success
- type: str
- sample: 10.2.4.100
-start_ipv6:
- description: The start ipv6 of the VLAN IP range.
- returned: if available
- type: str
- sample: 2001:db8::10
-end_ipv6:
- description: The end ipv6 of the VLAN IP range.
- returned: if available
- type: str
- sample: 2001:db8::50
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackVlanIpRange(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVlanIpRange, self).__init__(module)
- self.returns = {
- 'startip': 'start_ip',
- 'endip': 'end_ip',
- 'physicalnetworkid': 'physical_network',
- 'vlan': 'vlan',
- 'forsystemvms': 'for_systemvms',
- 'forvirtualnetwork': 'for_virtual_network',
- 'gateway': 'gateway',
- 'netmask': 'netmask',
- 'ip6gateway': 'gateway_ipv6',
- 'ip6cidr': 'cidr_ipv6',
- 'startipv6': 'start_ipv6',
- 'endipv6': 'end_ipv6',
- }
- self.ip_range = None
-
- def get_vlan_ip_range(self):
- if not self.ip_range:
- args = {
- 'zoneid': self.get_zone(key='id'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'networkid': self.get_network(key='id'),
- }
-
- res = self.query_api('listVlanIpRanges', **args)
- if res:
- ip_range_list = res['vlaniprange']
-
- params = {
- 'startip': self.module.params.get('start_ip'),
- 'endip': self.get_or_fallback('end_ip', 'start_ip'),
- }
-
- for ipr in ip_range_list:
- if params['startip'] == ipr['startip'] and params['endip'] == ipr['endip']:
- self.ip_range = ipr
- break
-
- return self.ip_range
-
- def present_vlan_ip_range(self):
- ip_range = self.get_vlan_ip_range()
-
- if not ip_range:
- ip_range = self.create_vlan_ip_range()
-
- return ip_range
-
- def create_vlan_ip_range(self):
- self.result['changed'] = True
-
- vlan = self.module.params.get('vlan')
-
- args = {
- 'zoneid': self.get_zone(key='id'),
- 'projectid': self.get_project(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'startip': self.module.params.get('start_ip'),
- 'endip': self.get_or_fallback('end_ip', 'start_ip'),
- 'netmask': self.module.params.get('netmask'),
- 'gateway': self.module.params.get('gateway'),
- 'startipv6': self.module.params.get('start_ipv6'),
- 'endipv6': self.get_or_fallback('end_ipv6', 'start_ipv6'),
- 'ip6gateway': self.module.params.get('gateway_ipv6'),
- 'ip6cidr': self.module.params.get('cidr_ipv6'),
- 'vlan': self.get_network(key='vlan') if not vlan else vlan,
- 'networkid': self.get_network(key='id'),
- 'forvirtualnetwork': self.module.params.get('for_virtual_network'),
- }
- if self.module.params.get('physical_network'):
- args['physicalnetworkid'] = self.get_physical_network(key='id')
-
- if not self.module.check_mode:
- res = self.query_api('createVlanIpRange', **args)
-
- self.ip_range = res['vlan']
-
- return self.ip_range
-
- def absent_vlan_ip_range(self):
- ip_range = self.get_vlan_ip_range()
-
- if ip_range:
- self.result['changed'] = True
-
- args = {
- 'id': ip_range['id'],
- }
-
- if not self.module.check_mode:
- self.query_api('deleteVlanIpRange', **args)
-
- return ip_range
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- network=dict(type='str'),
- physical_network=dict(type='str'),
- zone=dict(type='str'),
- start_ip=dict(type='str', required=True),
- end_ip=dict(type='str'),
- gateway=dict(type='str'),
- netmask=dict(type='str'),
- start_ipv6=dict(type='str'),
- end_ipv6=dict(type='str'),
- gateway_ipv6=dict(type='str'),
- cidr_ipv6=dict(type='str'),
- vlan=dict(type='str'),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(type='str'),
- account=dict(type='str'),
- project=dict(type='str'),
- for_virtual_network=dict(type='bool', default=False),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['account', 'project'],
- ),
- required_if=(("state", "present", ("gateway", "netmask")),),
- supports_check_mode=True,
- )
-
- acs_vlan_ip_range = AnsibleCloudStackVlanIpRange(module)
-
- state = module.params.get('state')
- if state == 'absent':
- ipr = acs_vlan_ip_range.absent_vlan_ip_range()
-
- else:
- ipr = acs_vlan_ip_range.present_vlan_ip_range()
-
- result = acs_vlan_ip_range.get_result(ipr)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vmsnapshot.py b/lib/ansible/modules/cloud/cloudstack/cs_vmsnapshot.py
deleted file mode 100644
index 47eed8fcd7..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vmsnapshot.py
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_vmsnapshot
-short_description: Manages VM snapshots on Apache CloudStack based clouds.
-description:
- - Create, remove and revert VM from snapshots.
-version_added: '2.0'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Unique Name of the snapshot. In CloudStack terms display name.
- type: str
- required: true
- aliases: [ display_name ]
- vm:
- description:
- - Name of the virtual machine.
- type: str
- required: true
- description:
- description:
- - Description of the snapshot.
- type: str
- snapshot_memory:
- description:
- - Snapshot memory if set to true.
- default: no
- type: bool
- zone:
- description:
- - Name of the zone in which the VM is in. If not set, default zone is used.
- type: str
- project:
- description:
- - Name of the project the VM is assigned to.
- type: str
- state:
- description:
- - State of the snapshot.
- type: str
- default: present
- choices: [ present, absent, revert ]
- domain:
- description:
- - Domain the VM snapshot is related to.
- type: str
- account:
- description:
- - Account the VM snapshot is related to.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a VM snapshot of disk and memory before an upgrade
- cs_vmsnapshot:
- name: Snapshot before upgrade
- vm: web-01
- snapshot_memory: yes
- delegate_to: localhost
-
-- name: Revert a VM to a snapshot after a failed upgrade
- cs_vmsnapshot:
- name: Snapshot before upgrade
- vm: web-01
- state: revert
- delegate_to: localhost
-
-- name: Remove a VM snapshot after successful upgrade
- cs_vmsnapshot:
- name: Snapshot before upgrade
- vm: web-01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the snapshot.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: Name of the snapshot.
- returned: success
- type: str
- sample: snapshot before update
-display_name:
- description: Display name of the snapshot.
- returned: success
- type: str
- sample: snapshot before update
-created:
- description: date of the snapshot.
- returned: success
- type: str
- sample: 2015-03-29T14:57:06+0200
-current:
- description: true if the snapshot is current
- returned: success
- type: bool
- sample: True
-state:
- description: state of the vm snapshot
- returned: success
- type: str
- sample: Allocated
-type:
- description: type of vm snapshot
- returned: success
- type: str
- sample: DiskAndMemory
-description:
- description: description of vm snapshot
- returned: success
- type: str
- sample: snapshot brought to you by Ansible
-domain:
- description: Domain the vm snapshot is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the vm snapshot is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the vm snapshot is related to.
- returned: success
- type: str
- sample: Production
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackVmSnapshot(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVmSnapshot, self).__init__(module)
- self.returns = {
- 'type': 'type',
- 'current': 'current',
- }
-
- def get_snapshot(self):
- args = {
- 'virtualmachineid': self.get_vm('id'),
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id'),
- 'projectid': self.get_project('id'),
- 'name': self.module.params.get('name'),
- }
- snapshots = self.query_api('listVMSnapshot', **args)
- if snapshots:
- return snapshots['vmSnapshot'][0]
- return None
-
- def create_snapshot(self):
- snapshot = self.get_snapshot()
- if not snapshot:
- self.result['changed'] = True
-
- args = {
- 'virtualmachineid': self.get_vm('id'),
- 'name': self.module.params.get('name'),
- 'description': self.module.params.get('description'),
- 'snapshotmemory': self.module.params.get('snapshot_memory'),
- }
- if not self.module.check_mode:
- res = self.query_api('createVMSnapshot', **args)
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- snapshot = self.poll_job(res, 'vmsnapshot')
-
- if snapshot:
- snapshot = self.ensure_tags(resource=snapshot, resource_type='Snapshot')
-
- return snapshot
-
- def remove_snapshot(self):
- snapshot = self.get_snapshot()
- if snapshot:
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('deleteVMSnapshot', vmsnapshotid=snapshot['id'])
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- res = self.poll_job(res, 'vmsnapshot')
- return snapshot
-
- def revert_vm_to_snapshot(self):
- snapshot = self.get_snapshot()
- if snapshot:
- self.result['changed'] = True
-
- if snapshot['state'] != "Ready":
- self.module.fail_json(msg="snapshot state is '%s', not ready, could not revert VM" % snapshot['state'])
-
- if not self.module.check_mode:
- res = self.query_api('revertToVMSnapshot', vmsnapshotid=snapshot['id'])
-
- poll_async = self.module.params.get('poll_async')
- if res and poll_async:
- res = self.poll_job(res, 'vmsnapshot')
- return snapshot
-
- self.module.fail_json(msg="snapshot not found, could not revert VM")
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True, aliases=['display_name']),
- vm=dict(required=True),
- description=dict(),
- zone=dict(),
- snapshot_memory=dict(type='bool', default=False),
- state=dict(choices=['present', 'absent', 'revert'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_vmsnapshot = AnsibleCloudStackVmSnapshot(module)
-
- state = module.params.get('state')
- if state in ['revert']:
- snapshot = acs_vmsnapshot.revert_vm_to_snapshot()
- elif state in ['absent']:
- snapshot = acs_vmsnapshot.remove_snapshot()
- else:
- snapshot = acs_vmsnapshot.create_snapshot()
-
- result = acs_vmsnapshot.get_result(snapshot)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_volume.py b/lib/ansible/modules/cloud/cloudstack/cs_volume.py
deleted file mode 100644
index 3d4a0d1691..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_volume.py
+++ /dev/null
@@ -1,576 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2015, Jefferson Girão <jefferson@girao.net>
-# (c) 2015, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_volume
-short_description: Manages volumes on Apache CloudStack based clouds.
-description:
- - Create, destroy, attach, detach, extract or upload volumes.
-version_added: '2.1'
-author:
- - Jefferson Girão (@jeffersongirao)
- - René Moser (@resmo)
-options:
- name:
- description:
- - Name of the volume.
- - I(name) can only contain ASCII letters.
- type: str
- required: true
- account:
- description:
- - Account the volume is related to.
- type: str
- device_id:
- description:
- - ID of the device on a VM the volume is attached to.
- - Only considered if I(state) is C(attached).
- type: int
- custom_id:
- description:
- - Custom id to the resource.
- - Allowed to Root Admins only.
- type: str
- disk_offering:
- description:
- - Name of the disk offering to be used.
- - Required one of I(disk_offering), I(snapshot) if volume is not already I(state=present).
- type: str
- display_volume:
- description:
- - Whether to display the volume to the end user or not.
- - Allowed to Root Admins only.
- type: bool
- domain:
- description:
- - Name of the domain the volume to be deployed in.
- type: str
- max_iops:
- description:
- - Max iops
- type: int
- min_iops:
- description:
- - Min iops
- type: int
- project:
- description:
- - Name of the project the volume to be deployed in.
- type: str
- size:
- description:
- - Size of disk in GB
- type: int
- snapshot:
- description:
- - The snapshot name for the disk volume.
- - Required one of I(disk_offering), I(snapshot) if volume is not already I(state=present).
- type: str
- force:
- description:
- - Force removal of volume even it is attached to a VM.
- - Considered on I(state=absent) only.
- default: no
- type: bool
- shrink_ok:
- description:
- - Whether to allow to shrink the volume.
- default: no
- type: bool
- vm:
- description:
- - Name of the virtual machine to attach the volume to.
- type: str
- zone:
- description:
- - Name of the zone in which the volume should be deployed.
- - If not set, default zone is used.
- type: str
- state:
- description:
- - State of the volume.
- - The choices C(extracted) and C(uploaded) were added in version 2.8.
- type: str
- default: present
- choices: [ present, absent, attached, detached, extracted, uploaded ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "To delete all tags, set a empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- version_added: '2.4'
- url:
- description:
- - URL to which the volume would be extracted on I(state=extracted)
- - or the URL where to download the volume on I(state=uploaded).
- - Only considered if I(state) is C(extracted) or C(uploaded).
- type: str
- version_added: '2.8'
- mode:
- description:
- - Mode for the volume extraction.
- - Only considered if I(state=extracted).
- type: str
- choices: [ http_download, ftp_upload ]
- default: http_download
- version_added: '2.8'
- format:
- description:
- - The format for the volume.
- - Only considered if I(state=uploaded).
- type: str
- choices: [ QCOW2, RAW, VHD, VHDX, OVA ]
- version_added: '2.8'
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: create volume within project and zone with specified storage options
- cs_volume:
- name: web-vm-1-volume
- project: Integration
- zone: ch-zrh-ix-01
- disk_offering: PerfPlus Storage
- size: 20
- delegate_to: localhost
-
-- name: create/attach volume to instance
- cs_volume:
- name: web-vm-1-volume
- disk_offering: PerfPlus Storage
- size: 20
- vm: web-vm-1
- state: attached
- delegate_to: localhost
-
-- name: detach volume
- cs_volume:
- name: web-vm-1-volume
- state: detached
- delegate_to: localhost
-
-- name: remove volume
- cs_volume:
- name: web-vm-1-volume
- state: absent
- delegate_to: localhost
-
-# New in version 2.8
-- name: Extract DATA volume to make it downloadable
- cs_volume:
- state: extracted
- name: web-vm-1-volume
- register: data_vol_out
- delegate_to: localhost
-
-- name: Create new volume by downloading source volume
- cs_volume:
- state: uploaded
- name: web-vm-1-volume-2
- format: VHD
- url: "{{ data_vol_out.url }}"
- delegate_to: localhost
-'''
-
-RETURN = '''
-id:
- description: ID of the volume.
- returned: success
- type: str
- sample:
-name:
- description: Name of the volume.
- returned: success
- type: str
- sample: web-volume-01
-display_name:
- description: Display name of the volume.
- returned: success
- type: str
- sample: web-volume-01
-group:
- description: Group the volume belongs to
- returned: success
- type: str
- sample: web
-domain:
- description: Domain the volume belongs to
- returned: success
- type: str
- sample: example domain
-project:
- description: Project the volume belongs to
- returned: success
- type: str
- sample: Production
-zone:
- description: Name of zone the volume is in.
- returned: success
- type: str
- sample: ch-gva-2
-created:
- description: Date of the volume was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-attached:
- description: Date of the volume was attached.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-type:
- description: Disk volume type.
- returned: success
- type: str
- sample: DATADISK
-size:
- description: Size of disk volume.
- returned: success
- type: int
- sample: 20
-vm:
- description: Name of the vm the volume is attached to (not returned when detached)
- returned: success
- type: str
- sample: web-01
-state:
- description: State of the volume
- returned: success
- type: str
- sample: Attached
-device_id:
- description: Id of the device on user vm the volume is attached to (not returned when detached)
- returned: success
- type: int
- sample: 1
-url:
- description: The url of the uploaded volume or the download url depending extraction mode.
- returned: success when I(state=extracted)
- type: str
- sample: http://1.12.3.4/userdata/387e2c7c-7c42-4ecc-b4ed-84e8367a1965.vhd
- version_added: '2.8'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_required_together,
- cs_argument_spec
-)
-
-
-class AnsibleCloudStackVolume(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVolume, self).__init__(module)
- self.returns = {
- 'group': 'group',
- 'attached': 'attached',
- 'vmname': 'vm',
- 'deviceid': 'device_id',
- 'type': 'type',
- 'size': 'size',
- 'url': 'url',
- }
- self.volume = None
-
- def get_volume(self):
- if not self.volume:
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'displayvolume': self.module.params.get('display_volume'),
- 'type': 'DATADISK',
- 'fetch_list': True,
- }
- # Do not filter on DATADISK when state=extracted
- if self.module.params.get('state') == 'extracted':
- del args['type']
-
- volumes = self.query_api('listVolumes', **args)
- if volumes:
- volume_name = self.module.params.get('name')
- for v in volumes:
- if volume_name.lower() == v['name'].lower():
- self.volume = v
- break
- return self.volume
-
- def get_snapshot(self, key=None):
- snapshot = self.module.params.get('snapshot')
- if not snapshot:
- return None
-
- args = {
- 'name': snapshot,
- 'account': self.get_account('name'),
- 'domainid': self.get_domain('id'),
- 'projectid': self.get_project('id'),
- }
- snapshots = self.query_api('listSnapshots', **args)
- if snapshots:
- return self._get_by_key(key, snapshots['snapshot'][0])
- self.module.fail_json(msg="Snapshot with name %s not found" % snapshot)
-
- def present_volume(self):
- volume = self.get_volume()
- if volume:
- volume = self.update_volume(volume)
- else:
- disk_offering_id = self.get_disk_offering(key='id')
- snapshot_id = self.get_snapshot(key='id')
-
- if not disk_offering_id and not snapshot_id:
- self.module.fail_json(msg="Required one of: disk_offering,snapshot")
-
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'diskofferingid': disk_offering_id,
- 'displayvolume': self.module.params.get('display_volume'),
- 'maxiops': self.module.params.get('max_iops'),
- 'miniops': self.module.params.get('min_iops'),
- 'projectid': self.get_project(key='id'),
- 'size': self.module.params.get('size'),
- 'snapshotid': snapshot_id,
- 'zoneid': self.get_zone(key='id')
- }
- if not self.module.check_mode:
- res = self.query_api('createVolume', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- if volume:
- volume = self.ensure_tags(resource=volume, resource_type='Volume')
- self.volume = volume
-
- return volume
-
- def attached_volume(self):
- volume = self.present_volume()
-
- if volume:
- if volume.get('virtualmachineid') != self.get_vm(key='id'):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- volume = self.detached_volume()
-
- if 'attached' not in volume:
- self.result['changed'] = True
-
- args = {
- 'id': volume['id'],
- 'virtualmachineid': self.get_vm(key='id'),
- 'deviceid': self.module.params.get('device_id'),
- }
- if not self.module.check_mode:
- res = self.query_api('attachVolume', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- return volume
-
- def detached_volume(self):
- volume = self.present_volume()
-
- if volume:
- if 'attached' not in volume:
- return volume
-
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('detachVolume', id=volume['id'])
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- return volume
-
- def absent_volume(self):
- volume = self.get_volume()
-
- if volume:
- if 'attached' in volume and not self.module.params.get('force'):
- self.module.fail_json(msg="Volume '%s' is attached, use force=true for detaching and removing the volume." % volume.get('name'))
-
- self.result['changed'] = True
- if not self.module.check_mode:
- volume = self.detached_volume()
- res = self.query_api('deleteVolume', id=volume['id'])
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'volume')
-
- return volume
-
- def update_volume(self, volume):
- args_resize = {
- 'id': volume['id'],
- 'diskofferingid': self.get_disk_offering(key='id'),
- 'maxiops': self.module.params.get('max_iops'),
- 'miniops': self.module.params.get('min_iops'),
- 'size': self.module.params.get('size')
- }
- # change unit from bytes to giga bytes to compare with args
- volume_copy = volume.copy()
- volume_copy['size'] = volume_copy['size'] / (2**30)
-
- if self.has_changed(args_resize, volume_copy):
-
- self.result['changed'] = True
- if not self.module.check_mode:
- args_resize['shrinkok'] = self.module.params.get('shrink_ok')
- res = self.query_api('resizeVolume', **args_resize)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- self.volume = volume
-
- return volume
-
- def extract_volume(self):
- volume = self.get_volume()
- if not volume:
- self.module.fail_json(msg="Failed: volume not found")
-
- args = {
- 'id': volume['id'],
- 'url': self.module.params.get('url'),
- 'mode': self.module.params.get('mode').upper(),
- 'zoneid': self.get_zone(key='id')
- }
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('extractVolume', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- self.volume = volume
-
- return volume
-
- def upload_volume(self):
- volume = self.get_volume()
- if not volume:
- disk_offering_id = self.get_disk_offering(key='id')
-
- self.result['changed'] = True
-
- args = {
- 'name': self.module.params.get('name'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'format': self.module.params.get('format'),
- 'url': self.module.params.get('url'),
- 'diskofferingid': disk_offering_id,
- }
- if not self.module.check_mode:
- res = self.query_api('uploadVolume', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- volume = self.poll_job(res, 'volume')
- if volume:
- volume = self.ensure_tags(resource=volume, resource_type='Volume')
- self.volume = volume
-
- return volume
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- disk_offering=dict(),
- display_volume=dict(type='bool'),
- max_iops=dict(type='int'),
- min_iops=dict(type='int'),
- size=dict(type='int'),
- snapshot=dict(),
- vm=dict(),
- device_id=dict(type='int'),
- custom_id=dict(),
- force=dict(type='bool', default=False),
- shrink_ok=dict(type='bool', default=False),
- state=dict(default='present', choices=[
- 'present',
- 'absent',
- 'attached',
- 'detached',
- 'extracted',
- 'uploaded',
- ]),
- zone=dict(),
- domain=dict(),
- account=dict(),
- project=dict(),
- poll_async=dict(type='bool', default=True),
- tags=dict(type='list', aliases=['tag']),
- url=dict(),
- mode=dict(choices=['http_download', 'ftp_upload'], default='http_download'),
- format=dict(choices=['QCOW2', 'RAW', 'VHD', 'VHDX', 'OVA']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- mutually_exclusive=(
- ['snapshot', 'disk_offering'],
- ),
- required_if=[
- ('state', 'uploaded', ['url', 'format']),
- ],
- supports_check_mode=True
- )
-
- acs_vol = AnsibleCloudStackVolume(module)
-
- state = module.params.get('state')
-
- if state in ['absent']:
- volume = acs_vol.absent_volume()
- elif state in ['attached']:
- volume = acs_vol.attached_volume()
- elif state in ['detached']:
- volume = acs_vol.detached_volume()
- elif state == 'extracted':
- volume = acs_vol.extract_volume()
- elif state == 'uploaded':
- volume = acs_vol.upload_volume()
- else:
- volume = acs_vol.present_volume()
-
- result = acs_vol.get_result(volume)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vpc.py b/lib/ansible/modules/cloud/cloudstack/cs_vpc.py
deleted file mode 100644
index b36575efca..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vpc.py
+++ /dev/null
@@ -1,398 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_vpc
-short_description: "Manages VPCs on Apache CloudStack based clouds."
-description:
- - Create, update and delete VPCs.
-version_added: '2.3'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the VPC.
- type: str
- required: true
- display_text:
- description:
- - Display text of the VPC.
- - If not set, I(name) will be used for creating.
- type: str
- cidr:
- description:
- - CIDR of the VPC, e.g. 10.1.0.0/16
- - All VPC guest networks' CIDRs must be within this CIDR.
- - Required on I(state=present).
- type: str
- network_domain:
- description:
- - Network domain for the VPC.
- - All networks inside the VPC will belong to this domain.
- - Only considered while creating the VPC, can not be changed.
- type: str
- vpc_offering:
- description:
- - Name of the VPC offering.
- - If not set, default VPC offering is used.
- type: str
- clean_up:
- description:
- - Whether to redeploy a VPC router or not when I(state=restarted)
- version_added: '2.5'
- type: bool
- state:
- description:
- - State of the VPC.
- - The state C(present) creates a started VPC.
- - The state C(stopped) is only considered while creating the VPC, added in version 2.6.
- type: str
- default: present
- choices:
- - present
- - absent
- - stopped
- - restarted
- domain:
- description:
- - Domain the VPC is related to.
- type: str
- account:
- description:
- - Account the VPC is related to.
- type: str
- project:
- description:
- - Name of the project the VPC is related to.
- type: str
- zone:
- description:
- - Name of the zone.
- - If not set, default zone is used.
- type: str
- tags:
- description:
- - List of tags. Tags are a list of dictionaries having keys I(key) and I(value).
- - "For deleting all tags, set an empty list e.g. I(tags: [])."
- type: list
- aliases: [ tag ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a VPC is present but not started after creating
- cs_vpc:
- name: my_vpc
- display_text: My example VPC
- cidr: 10.10.0.0/16
- state: stopped
- delegate_to: localhost
-
-- name: Ensure a VPC is present and started after creating
- cs_vpc:
- name: my_vpc
- display_text: My example VPC
- cidr: 10.10.0.0/16
- delegate_to: localhost
-
-- name: Ensure a VPC is absent
- cs_vpc:
- name: my_vpc
- state: absent
- delegate_to: localhost
-
-- name: Ensure a VPC is restarted with clean up
- cs_vpc:
- name: my_vpc
- clean_up: yes
- state: restarted
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: "UUID of the VPC."
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: "Name of the VPC."
- returned: success
- type: str
- sample: my_vpc
-display_text:
- description: "Display text of the VPC."
- returned: success
- type: str
- sample: My example VPC
-cidr:
- description: "CIDR of the VPC."
- returned: success
- type: str
- sample: 10.10.0.0/16
-network_domain:
- description: "Network domain of the VPC."
- returned: success
- type: str
- sample: example.com
-region_level_vpc:
- description: "Whether the VPC is region level or not."
- returned: success
- type: bool
- sample: true
-restart_required:
- description: "Whether the VPC router needs a restart or not."
- returned: success
- type: bool
- sample: true
-distributed_vpc_router:
- description: "Whether the VPC uses distributed router or not."
- returned: success
- type: bool
- sample: true
-redundant_vpc_router:
- description: "Whether the VPC has redundant routers or not."
- returned: success
- type: bool
- sample: true
-domain:
- description: "Domain the VPC is related to."
- returned: success
- type: str
- sample: example domain
-account:
- description: "Account the VPC is related to."
- returned: success
- type: str
- sample: example account
-project:
- description: "Name of project the VPC is related to."
- returned: success
- type: str
- sample: Production
-zone:
- description: "Name of zone the VPC is in."
- returned: success
- type: str
- sample: ch-gva-2
-state:
- description: "State of the VPC."
- returned: success
- type: str
- sample: Enabled
-tags:
- description: "List of resource tags associated with the VPC."
- returned: success
- type: list
- sample: '[ { "key": "foo", "value": "bar" } ]'
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackVpc(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVpc, self).__init__(module)
- self.returns = {
- 'cidr': 'cidr',
- 'networkdomain': 'network_domain',
- 'redundantvpcrouter': 'redundant_vpc_router',
- 'distributedvpcrouter': 'distributed_vpc_router',
- 'regionlevelvpc': 'region_level_vpc',
- 'restartrequired': 'restart_required',
- }
- self.vpc = None
-
- def get_vpc_offering(self, key=None):
- vpc_offering = self.module.params.get('vpc_offering')
- args = {
- 'state': 'Enabled',
- }
- if vpc_offering:
- args['name'] = vpc_offering
- fail_msg = "VPC offering not found or not enabled: %s" % vpc_offering
- else:
- args['isdefault'] = True
- fail_msg = "No enabled default VPC offering found"
-
- vpc_offerings = self.query_api('listVPCOfferings', **args)
- if vpc_offerings:
- # The API name argument filter also matches substrings, we have to
- # iterate over the results to get an exact match
- for vo in vpc_offerings['vpcoffering']:
- if 'name' in args:
- if args['name'] == vo['name']:
- return self._get_by_key(key, vo)
- # Return the first offering found, if not queried for the name
- else:
- return self._get_by_key(key, vo)
- self.module.fail_json(msg=fail_msg)
-
- def get_vpc(self):
- if self.vpc:
- return self.vpc
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'fetch_list': True,
- }
- vpcs = self.query_api('listVPCs', **args)
- if vpcs:
- vpc_name = self.module.params.get('name')
- for v in vpcs:
- if vpc_name in [v['name'], v['displaytext'], v['id']]:
- # Fail if the identifier matches more than one VPC
- if self.vpc:
- self.module.fail_json(msg="More than one VPC found with the provided identifyer: %s" % vpc_name)
- else:
- self.vpc = v
- return self.vpc
-
- def restart_vpc(self):
- self.result['changed'] = True
- vpc = self.get_vpc()
- if vpc and not self.module.check_mode:
- args = {
- 'id': vpc['id'],
- 'cleanup': self.module.params.get('clean_up'),
- }
- res = self.query_api('restartVPC', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'vpc')
- return vpc
-
- def present_vpc(self):
- vpc = self.get_vpc()
- if not vpc:
- vpc = self._create_vpc(vpc)
- else:
- vpc = self._update_vpc(vpc)
-
- if vpc:
- vpc = self.ensure_tags(resource=vpc, resource_type='Vpc')
- return vpc
-
- def _create_vpc(self, vpc):
- self.result['changed'] = True
- args = {
- 'name': self.module.params.get('name'),
- 'displaytext': self.get_or_fallback('display_text', 'name'),
- 'networkdomain': self.module.params.get('network_domain'),
- 'vpcofferingid': self.get_vpc_offering(key='id'),
- 'cidr': self.module.params.get('cidr'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'zoneid': self.get_zone(key='id'),
- 'start': self.module.params.get('state') != 'stopped'
- }
- self.result['diff']['after'] = args
- if not self.module.check_mode:
- res = self.query_api('createVPC', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpc = self.poll_job(res, 'vpc')
- return vpc
-
- def _update_vpc(self, vpc):
- args = {
- 'id': vpc['id'],
- 'displaytext': self.module.params.get('display_text'),
- }
- if self.has_changed(args, vpc):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateVPC', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpc = self.poll_job(res, 'vpc')
- return vpc
-
- def absent_vpc(self):
- vpc = self.get_vpc()
- if vpc:
- self.result['changed'] = True
- self.result['diff']['before'] = vpc
- if not self.module.check_mode:
- res = self.query_api('deleteVPC', id=vpc['id'])
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'vpc')
- return vpc
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- cidr=dict(),
- display_text=dict(),
- vpc_offering=dict(),
- network_domain=dict(),
- clean_up=dict(type='bool'),
- state=dict(choices=['present', 'absent', 'stopped', 'restarted'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- tags=dict(type='list', aliases=['tag']),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- required_if=[
- ('state', 'present', ['cidr']),
- ],
- supports_check_mode=True,
- )
-
- acs_vpc = AnsibleCloudStackVpc(module)
-
- state = module.params.get('state')
- if state == 'absent':
- vpc = acs_vpc.absent_vpc()
- elif state == 'restarted':
- vpc = acs_vpc.restart_vpc()
- else:
- vpc = acs_vpc.present_vpc()
-
- result = acs_vpc.get_result(vpc)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vpc_offering.py b/lib/ansible/modules/cloud/cloudstack/cs_vpc_offering.py
deleted file mode 100644
index e0dabdef72..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vpc_offering.py
+++ /dev/null
@@ -1,322 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, David Passante (@dpassante)
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = '''
----
-module: cs_vpc_offering
-short_description: Manages vpc offerings on Apache CloudStack based clouds.
-description:
- - Create, update, enable, disable and remove CloudStack VPC offerings.
-version_added: '2.5'
-author: David Passante (@dpassante)
-options:
- name:
- description:
- - The name of the vpc offering
- type: str
- required: true
- state:
- description:
- - State of the vpc offering.
- type: str
- choices: [ enabled, present, disabled, absent ]
- default: present
- display_text:
- description:
- - Display text of the vpc offerings
- type: str
- service_capabilities:
- description:
- - Desired service capabilities as part of vpc offering.
- type: list
- aliases: [ service_capability ]
- service_offering:
- description:
- - The name or ID of the service offering for the VPC router appliance.
- type: str
- supported_services:
- description:
- - Services supported by the vpc offering
- type: list
- aliases: [ supported_service ]
- service_providers:
- description:
- - provider to service mapping. If not specified, the provider for the service will be mapped to the default provider on the physical network
- type: list
- aliases: [ service_provider ]
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Create a vpc offering and enable it
- cs_vpc_offering:
- name: my_vpc_offering
- display_text: vpc offering description
- state: enabled
- supported_services: [ Dns, Dhcp ]
- service_providers:
- - {service: 'dns', provider: 'VpcVirtualRouter'}
- - {service: 'dhcp', provider: 'VpcVirtualRouter'}
- delegate_to: localhost
-
-- name: Create a vpc offering with redundant router
- cs_vpc_offering:
- name: my_vpc_offering
- display_text: vpc offering description
- supported_services: [ Dns, Dhcp, SourceNat ]
- service_providers:
- - {service: 'dns', provider: 'VpcVirtualRouter'}
- - {service: 'dhcp', provider: 'VpcVirtualRouter'}
- - {service: 'SourceNat', provider: 'VpcVirtualRouter'}
- service_capabilities:
- - {service: 'SourceNat', capabilitytype: 'RedundantRouter', capabilityvalue: true}
- delegate_to: localhost
-
-- name: Create a region level vpc offering with distributed router
- cs_vpc_offering:
- name: my_vpc_offering
- display_text: vpc offering description
- state: present
- supported_services: [ Dns, Dhcp, SourceNat ]
- service_providers:
- - {service: 'dns', provider: 'VpcVirtualRouter'}
- - {service: 'dhcp', provider: 'VpcVirtualRouter'}
- - {service: 'SourceNat', provider: 'VpcVirtualRouter'}
- service_capabilities:
- - {service: 'Connectivity', capabilitytype: 'DistributedRouter', capabilityvalue: true}
- - {service: 'Connectivity', capabilitytype: 'RegionLevelVPC', capabilityvalue: true}
- delegate_to: localhost
-
-- name: Remove a vpc offering
- cs_vpc_offering:
- name: my_vpc_offering
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the vpc offering.
- returned: success
- type: str
- sample: a6f7a5fc-43f8-11e5-a151-feff819cdc9f
-name:
- description: The name of the vpc offering
- returned: success
- type: str
- sample: MyCustomVPCOffering
-display_text:
- description: The display text of the vpc offering
- returned: success
- type: str
- sample: My vpc offering
-state:
- description: The state of the vpc offering
- returned: success
- type: str
- sample: Enabled
-service_offering_id:
- description: The service offering ID.
- returned: success
- type: str
- sample: c5f7a5fc-43f8-11e5-a151-feff819cdc9f
-is_default:
- description: Whether VPC offering is the default offering or not.
- returned: success
- type: bool
- sample: false
-region_level:
- description: Indicated if the offering can support region level vpc.
- returned: success
- type: bool
- sample: false
-distributed:
- description: Indicates if the vpc offering supports distributed router for one-hop forwarding.
- returned: success
- type: bool
- sample: false
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackVPCOffering(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVPCOffering, self).__init__(module)
- self.returns = {
- 'serviceofferingid': 'service_offering_id',
- 'isdefault': 'is_default',
- 'distributedvpcrouter': 'distributed',
- 'supportsregionLevelvpc': 'region_level',
- }
- self.vpc_offering = None
-
- def get_vpc_offering(self):
- if self.vpc_offering:
- return self.vpc_offering
-
- args = {
- 'name': self.module.params.get('name'),
- }
- vo = self.query_api('listVPCOfferings', **args)
-
- if vo:
- for vpc_offer in vo['vpcoffering']:
- if args['name'] == vpc_offer['name']:
- self.vpc_offering = vpc_offer
-
- return self.vpc_offering
-
- def get_service_offering_id(self):
- service_offering = self.module.params.get('service_offering')
- if not service_offering:
- return None
-
- args = {
- 'issystem': True
- }
-
- service_offerings = self.query_api('listServiceOfferings', **args)
- if service_offerings:
- for s in service_offerings['serviceoffering']:
- if service_offering in [s['name'], s['id']]:
- return s['id']
- self.fail_json(msg="Service offering '%s' not found" % service_offering)
-
- def create_or_update(self):
- vpc_offering = self.get_vpc_offering()
-
- if not vpc_offering:
- vpc_offering = self.create_vpc_offering()
-
- return self.update_vpc_offering(vpc_offering)
-
- def create_vpc_offering(self):
- vpc_offering = None
- self.result['changed'] = True
- args = {
- 'name': self.module.params.get('name'),
- 'state': self.module.params.get('state'),
- 'displaytext': self.module.params.get('display_text'),
- 'supportedservices': self.module.params.get('supported_services'),
- 'serviceproviderlist': self.module.params.get('service_providers'),
- 'serviceofferingid': self.get_service_offering_id(),
- 'servicecapabilitylist': self.module.params.get('service_capabilities'),
- }
-
- required_params = [
- 'display_text',
- 'supported_services',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- if not self.module.check_mode:
- res = self.query_api('createVPCOffering', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpc_offering = self.poll_job(res, 'vpcoffering')
-
- return vpc_offering
-
- def delete_vpc_offering(self):
- vpc_offering = self.get_vpc_offering()
-
- if vpc_offering:
- self.result['changed'] = True
-
- args = {
- 'id': vpc_offering['id'],
- }
-
- if not self.module.check_mode:
- res = self.query_api('deleteVPCOffering', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpc_offering = self.poll_job(res, 'vpcoffering')
-
- return vpc_offering
-
- def update_vpc_offering(self, vpc_offering):
- if not vpc_offering:
- return vpc_offering
-
- args = {
- 'id': vpc_offering['id'],
- 'state': self.module.params.get('state'),
- 'name': self.module.params.get('name'),
- 'displaytext': self.module.params.get('display_text'),
- }
-
- if args['state'] in ['enabled', 'disabled']:
- args['state'] = args['state'].title()
- else:
- del args['state']
-
- if self.has_changed(args, vpc_offering):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateVPCOffering', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpc_offering = self.poll_job(res, 'vpcoffering')
-
- return vpc_offering
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- display_text=dict(),
- state=dict(choices=['enabled', 'present', 'disabled', 'absent'], default='present'),
- service_capabilities=dict(type='list', aliases=['service_capability']),
- service_offering=dict(),
- supported_services=dict(type='list', aliases=['supported_service']),
- service_providers=dict(type='list', aliases=['service_provider']),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_vpc_offering = AnsibleCloudStackVPCOffering(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- vpc_offering = acs_vpc_offering.delete_vpc_offering()
- else:
- vpc_offering = acs_vpc_offering.create_or_update()
-
- result = acs_vpc_offering.get_result(vpc_offering)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vpn_connection.py b/lib/ansible/modules/cloud/cloudstack/cs_vpn_connection.py
deleted file mode 100644
index cdcc249118..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vpn_connection.py
+++ /dev/null
@@ -1,354 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = r'''
----
-module: cs_vpn_connection
-short_description: Manages site-to-site VPN connections on Apache CloudStack based clouds.
-description:
- - Create and remove VPN connections.
-version_added: '2.5'
-author: René Moser (@resmo)
-options:
- vpc:
- description:
- - Name of the VPC the VPN connection is related to.
- type: str
- required: true
- vpn_customer_gateway:
- description:
- - Name of the VPN customer gateway.
- type: str
- required: true
- passive:
- description:
- - State of the VPN connection.
- - Only considered when I(state=present).
- default: no
- type: bool
- force:
- description:
- - Activate the VPN gateway if not already activated on I(state=present).
- - Also see M(cs_vpn_gateway).
- default: no
- type: bool
- state:
- description:
- - State of the VPN connection.
- type: str
- default: present
- choices: [ present, absent ]
- zone:
- description:
- - Name of the zone the VPC is related to.
- - If not set, default zone is used.
- type: str
- domain:
- description:
- - Domain the VPN connection is related to.
- type: str
- account:
- description:
- - Account the VPN connection is related to.
- type: str
- project:
- description:
- - Name of the project the VPN connection is related to.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = r'''
-- name: Create a VPN connection with activated VPN gateway
- cs_vpn_connection:
- vpn_customer_gateway: my vpn connection
- vpc: my vpc
- delegate_to: localhost
-
-- name: Create a VPN connection and force VPN gateway activation
- cs_vpn_connection:
- vpn_customer_gateway: my vpn connection
- vpc: my vpc
- force: yes
- delegate_to: localhost
-
-- name: Remove a vpn connection
- cs_vpn_connection:
- vpn_customer_gateway: my vpn connection
- vpc: my vpc
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = r'''
----
-id:
- description: UUID of the VPN connection.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-vpn_gateway_id:
- description: UUID of the VPN gateway.
- returned: success
- type: str
- sample: 04589590-ac63-93f5-4ffc-b698b8ac38b6
-domain:
- description: Domain the VPN connection is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the VPN connection is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the VPN connection is related to.
- returned: success
- type: str
- sample: Production
-created:
- description: Date the connection was created.
- returned: success
- type: str
- sample: 2014-12-01T14:57:57+0100
-dpd:
- description: Whether dead pear detection is enabled or not.
- returned: success
- type: bool
- sample: true
-esp_lifetime:
- description: Lifetime in seconds of phase 2 VPN connection.
- returned: success
- type: int
- sample: 86400
-esp_policy:
- description: IKE policy of the VPN connection.
- returned: success
- type: str
- sample: aes256-sha1;modp1536
-force_encap:
- description: Whether encapsulation for NAT traversal is enforced or not.
- returned: success
- type: bool
- sample: true
-ike_lifetime:
- description: Lifetime in seconds of phase 1 VPN connection.
- returned: success
- type: int
- sample: 86400
-ike_policy:
- description: ESP policy of the VPN connection.
- returned: success
- type: str
- sample: aes256-sha1;modp1536
-cidrs:
- description: List of CIDRs of the customer gateway.
- returned: success
- type: list
- sample: [ 10.10.10.0/24 ]
-passive:
- description: Whether the connection is passive or not.
- returned: success
- type: bool
- sample: false
-public_ip:
- description: IP address of the VPN gateway.
- returned: success
- type: str
- sample: 10.100.212.10
-gateway:
- description: IP address of the VPN customer gateway.
- returned: success
- type: str
- sample: 10.101.214.10
-state:
- description: State of the VPN connection.
- returned: success
- type: str
- sample: Connected
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackVpnConnection(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVpnConnection, self).__init__(module)
- self.returns = {
- 'dpd': 'dpd',
- 'esplifetime': 'esp_lifetime',
- 'esppolicy': 'esp_policy',
- 'gateway': 'gateway',
- 'ikepolicy': 'ike_policy',
- 'ikelifetime': 'ike_lifetime',
- 'publicip': 'public_ip',
- 'passive': 'passive',
- 's2svpngatewayid': 'vpn_gateway_id',
- }
- self.vpn_customer_gateway = None
-
- def get_vpn_customer_gateway(self, key=None, identifier=None, refresh=False):
- if not refresh and self.vpn_customer_gateway:
- return self._get_by_key(key, self.vpn_customer_gateway)
-
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'fetch_list': True,
- }
-
- vpn_customer_gateway = identifier or self.module.params.get('vpn_customer_gateway')
- vcgws = self.query_api('listVpnCustomerGateways', **args)
- if vcgws:
- for vcgw in vcgws:
- if vpn_customer_gateway.lower() in [vcgw['id'], vcgw['name'].lower()]:
- self.vpn_customer_gateway = vcgw
- return self._get_by_key(key, self.vpn_customer_gateway)
- self.fail_json(msg="VPN customer gateway not found: %s" % vpn_customer_gateway)
-
- def get_vpn_gateway(self, key=None):
- args = {
- 'vpcid': self.get_vpc(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- }
- vpn_gateways = self.query_api('listVpnGateways', **args)
- if vpn_gateways:
- return self._get_by_key(key, vpn_gateways['vpngateway'][0])
-
- elif self.module.params.get('force'):
- if self.module.check_mode:
- return {}
- res = self.query_api('createVpnGateway', **args)
- vpn_gateway = self.poll_job(res, 'vpngateway')
- return self._get_by_key(key, vpn_gateway)
-
- self.fail_json(msg="VPN gateway not found and not forced to create one")
-
- def get_vpn_connection(self):
- args = {
- 'vpcid': self.get_vpc(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- }
-
- vpn_conns = self.query_api('listVpnConnections', **args)
- if vpn_conns:
- for vpn_conn in vpn_conns['vpnconnection']:
- if self.get_vpn_customer_gateway(key='id') == vpn_conn['s2scustomergatewayid']:
- return vpn_conn
-
- def present_vpn_connection(self):
- vpn_conn = self.get_vpn_connection()
-
- args = {
- 's2scustomergatewayid': self.get_vpn_customer_gateway(key='id'),
- 's2svpngatewayid': self.get_vpn_gateway(key='id'),
- 'passive': self.module.params.get('passive'),
- }
-
- if not vpn_conn:
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('createVpnConnection', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpn_conn = self.poll_job(res, 'vpnconnection')
-
- return vpn_conn
-
- def absent_vpn_connection(self):
- vpn_conn = self.get_vpn_connection()
-
- if vpn_conn:
- self.result['changed'] = True
-
- args = {
- 'id': vpn_conn['id']
- }
-
- if not self.module.check_mode:
- res = self.query_api('deleteVpnConnection', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'vpnconnection')
-
- return vpn_conn
-
- def get_result(self, vpn_conn):
- super(AnsibleCloudStackVpnConnection, self).get_result(vpn_conn)
- if vpn_conn:
- if 'cidrlist' in vpn_conn:
- self.result['cidrs'] = vpn_conn['cidrlist'].split(',') or [vpn_conn['cidrlist']]
- # Ensure we return a bool
- self.result['force_encap'] = True if vpn_conn.get('forceencap') else False
- args = {
- 'key': 'name',
- 'identifier': vpn_conn['s2scustomergatewayid'],
- 'refresh': True,
- }
- self.result['vpn_customer_gateway'] = self.get_vpn_customer_gateway(**args)
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- vpn_customer_gateway=dict(required=True),
- vpc=dict(required=True),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- passive=dict(type='bool', default=False),
- force=dict(type='bool', default=False),
- state=dict(choices=['present', 'absent'], default='present'),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_vpn_conn = AnsibleCloudStackVpnConnection(module)
-
- state = module.params.get('state')
- if state == "absent":
- vpn_conn = acs_vpn_conn.absent_vpn_connection()
- else:
- vpn_conn = acs_vpn_conn.present_vpn_connection()
-
- result = acs_vpn_conn.get_result(vpn_conn)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vpn_customer_gateway.py b/lib/ansible/modules/cloud/cloudstack/cs_vpn_customer_gateway.py
deleted file mode 100644
index 2c14a9fcea..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vpn_customer_gateway.py
+++ /dev/null
@@ -1,347 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-DOCUMENTATION = r'''
----
-module: cs_vpn_customer_gateway
-short_description: Manages site-to-site VPN customer gateway configurations on Apache CloudStack based clouds.
-description:
- - Create, update and remove VPN customer gateways.
-version_added: '2.5'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the gateway.
- type: str
- required: true
- cidrs:
- description:
- - List of guest CIDRs behind the gateway.
- - Required if I(state=present).
- type: list
- aliases: [ cidr ]
- gateway:
- description:
- - Public IP address of the gateway.
- - Required if I(state=present).
- type: str
- esp_policy:
- description:
- - ESP policy in the format e.g. C(aes256-sha1;modp1536).
- - Required if I(state=present).
- type: str
- ike_policy:
- description:
- - IKE policy in the format e.g. C(aes256-sha1;modp1536).
- - Required if I(state=present).
- type: str
- ipsec_psk:
- description:
- - IPsec Preshared-Key.
- - Cannot contain newline or double quotes.
- - Required if I(state=present).
- type: str
- ike_lifetime:
- description:
- - Lifetime in seconds of phase 1 VPN connection.
- - Defaulted to 86400 by the API on creation if not set.
- type: int
- esp_lifetime:
- description:
- - Lifetime in seconds of phase 2 VPN connection.
- - Defaulted to 3600 by the API on creation if not set.
- type: int
- dpd:
- description:
- - Enable Dead Peer Detection.
- - Disabled per default by the API on creation if not set.
- type: bool
- force_encap:
- description:
- - Force encapsulation for NAT traversal.
- - Disabled per default by the API on creation if not set.
- type: bool
- state:
- description:
- - State of the VPN customer gateway.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the VPN customer gateway is related to.
- type: str
- account:
- description:
- - Account the VPN customer gateway is related to.
- type: str
- project:
- description:
- - Name of the project the VPN gateway is related to.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- default: yes
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = r'''
-- name: Create a vpn customer gateway
- cs_vpn_customer_gateway:
- name: my vpn customer gateway
- cidrs:
- - 192.168.123.0/24
- - 192.168.124.0/24
- esp_policy: aes256-sha1;modp1536
- gateway: 10.10.1.1
- ike_policy: aes256-sha1;modp1536
- ipsec_psk: "S3cr3Tk3Y"
- delegate_to: localhost
-
-- name: Remove a vpn customer gateway
- cs_vpn_customer_gateway:
- name: my vpn customer gateway
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = r'''
----
-id:
- description: UUID of the VPN customer gateway.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-gateway:
- description: IP address of the VPN customer gateway.
- returned: success
- type: str
- sample: 10.100.212.10
-domain:
- description: Domain the VPN customer gateway is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the VPN customer gateway is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the VPN customer gateway is related to.
- returned: success
- type: str
- sample: Production
-dpd:
- description: Whether dead pear detection is enabled or not.
- returned: success
- type: bool
- sample: true
-esp_lifetime:
- description: Lifetime in seconds of phase 2 VPN connection.
- returned: success
- type: int
- sample: 86400
-esp_policy:
- description: IKE policy of the VPN customer gateway.
- returned: success
- type: str
- sample: aes256-sha1;modp1536
-force_encap:
- description: Whether encapsulation for NAT traversal is enforced or not.
- returned: success
- type: bool
- sample: true
-ike_lifetime:
- description: Lifetime in seconds of phase 1 VPN connection.
- returned: success
- type: int
- sample: 86400
-ike_policy:
- description: ESP policy of the VPN customer gateway.
- returned: success
- type: str
- sample: aes256-sha1;modp1536
-name:
- description: Name of this customer gateway.
- returned: success
- type: str
- sample: my vpn customer gateway
-cidrs:
- description: List of CIDRs of this customer gateway.
- returned: success
- type: list
- sample: [ 10.10.10.0/24 ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackVpnCustomerGateway(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVpnCustomerGateway, self).__init__(module)
- self.returns = {
- 'dpd': 'dpd',
- 'esplifetime': 'esp_lifetime',
- 'esppolicy': 'esp_policy',
- 'gateway': 'gateway',
- 'ikepolicy': 'ike_policy',
- 'ikelifetime': 'ike_lifetime',
- 'ipaddress': 'ip_address',
- }
-
- def _common_args(self):
- return {
- 'name': self.module.params.get('name'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'cidrlist': ','.join(self.module.params.get('cidrs')) if self.module.params.get('cidrs') is not None else None,
- 'esppolicy': self.module.params.get('esp_policy'),
- 'esplifetime': self.module.params.get('esp_lifetime'),
- 'ikepolicy': self.module.params.get('ike_policy'),
- 'ikelifetime': self.module.params.get('ike_lifetime'),
- 'ipsecpsk': self.module.params.get('ipsec_psk'),
- 'dpd': self.module.params.get('dpd'),
- 'forceencap': self.module.params.get('force_encap'),
- 'gateway': self.module.params.get('gateway'),
- }
-
- def get_vpn_customer_gateway(self):
- args = {
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id'),
- 'fetch_list': True,
- }
- vpn_customer_gateway = self.module.params.get('name')
- vpn_customer_gateways = self.query_api('listVpnCustomerGateways', **args)
- if vpn_customer_gateways:
- for vgw in vpn_customer_gateways:
- if vpn_customer_gateway.lower() in [vgw['id'], vgw['name'].lower()]:
- return vgw
-
- def present_vpn_customer_gateway(self):
- vpn_customer_gateway = self.get_vpn_customer_gateway()
- required_params = [
- 'cidrs',
- 'esp_policy',
- 'gateway',
- 'ike_policy',
- 'ipsec_psk',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- if not vpn_customer_gateway:
- vpn_customer_gateway = self._create_vpn_customer_gateway(vpn_customer_gateway)
- else:
- vpn_customer_gateway = self._update_vpn_customer_gateway(vpn_customer_gateway)
-
- return vpn_customer_gateway
-
- def _create_vpn_customer_gateway(self, vpn_customer_gateway):
- self.result['changed'] = True
- args = self._common_args()
- if not self.module.check_mode:
- res = self.query_api('createVpnCustomerGateway', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpn_customer_gateway = self.poll_job(res, 'vpncustomergateway')
- return vpn_customer_gateway
-
- def _update_vpn_customer_gateway(self, vpn_customer_gateway):
- args = self._common_args()
- args.update({'id': vpn_customer_gateway['id']})
- if self.has_changed(args, vpn_customer_gateway, skip_diff_for_keys=['ipsecpsk']):
- self.result['changed'] = True
- if not self.module.check_mode:
- res = self.query_api('updateVpnCustomerGateway', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpn_customer_gateway = self.poll_job(res, 'vpncustomergateway')
- return vpn_customer_gateway
-
- def absent_vpn_customer_gateway(self):
- vpn_customer_gateway = self.get_vpn_customer_gateway()
- if vpn_customer_gateway:
- self.result['changed'] = True
- args = {
- 'id': vpn_customer_gateway['id']
- }
- if not self.module.check_mode:
- res = self.query_api('deleteVpnCustomerGateway', **args)
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'vpncustomergateway')
-
- return vpn_customer_gateway
-
- def get_result(self, vpn_customer_gateway):
- super(AnsibleCloudStackVpnCustomerGateway, self).get_result(vpn_customer_gateway)
- if vpn_customer_gateway:
- if 'cidrlist' in vpn_customer_gateway:
- self.result['cidrs'] = vpn_customer_gateway['cidrlist'].split(',') or [vpn_customer_gateway['cidrlist']]
- # Ensure we return a bool
- self.result['force_encap'] = True if vpn_customer_gateway.get('forceencap') else False
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- name=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- cidrs=dict(type='list', aliases=['cidr']),
- esp_policy=dict(),
- esp_lifetime=dict(type='int'),
- gateway=dict(),
- ike_policy=dict(),
- ike_lifetime=dict(type='int'),
- ipsec_psk=dict(no_log=True),
- dpd=dict(type='bool'),
- force_encap=dict(type='bool'),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_vpn_cgw = AnsibleCloudStackVpnCustomerGateway(module)
-
- state = module.params.get('state')
- if state == "absent":
- vpn_customer_gateway = acs_vpn_cgw.absent_vpn_customer_gateway()
- else:
- vpn_customer_gateway = acs_vpn_cgw.present_vpn_customer_gateway()
-
- result = acs_vpn_cgw.get_result(vpn_customer_gateway)
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_vpn_gateway.py b/lib/ansible/modules/cloud/cloudstack/cs_vpn_gateway.py
deleted file mode 100644
index 72bac2beba..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_vpn_gateway.py
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['preview'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_vpn_gateway
-short_description: Manages site-to-site VPN gateways on Apache CloudStack based clouds.
-description:
- - Creates and removes VPN site-to-site gateways.
-version_added: '2.4'
-author: René Moser (@resmo)
-options:
- vpc:
- description:
- - Name of the VPC.
- type: str
- required: true
- state:
- description:
- - State of the VPN gateway.
- type: str
- default: present
- choices: [ present, absent ]
- domain:
- description:
- - Domain the VPN gateway is related to.
- type: str
- account:
- description:
- - Account the VPN gateway is related to.
- type: str
- project:
- description:
- - Name of the project the VPN gateway is related to.
- type: str
- zone:
- description:
- - Name of the zone the VPC is related to.
- - If not set, default zone is used.
- type: str
- poll_async:
- description:
- - Poll async jobs until job has finished.
- type: bool
- default: yes
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a vpn gateway is present
- cs_vpn_gateway:
- vpc: my VPC
- delegate_to: localhost
-
-- name: Ensure a vpn gateway is absent
- cs_vpn_gateway:
- vpc: my VPC
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the VPN site-to-site gateway.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-public_ip:
- description: IP address of the VPN site-to-site gateway.
- returned: success
- type: str
- sample: 10.100.212.10
-vpc:
- description: Name of the VPC.
- returned: success
- type: str
- sample: My VPC
-domain:
- description: Domain the VPN site-to-site gateway is related to.
- returned: success
- type: str
- sample: example domain
-account:
- description: Account the VPN site-to-site gateway is related to.
- returned: success
- type: str
- sample: example account
-project:
- description: Name of project the VPN site-to-site gateway is related to.
- returned: success
- type: str
- sample: Production
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together
-)
-
-
-class AnsibleCloudStackVpnGateway(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackVpnGateway, self).__init__(module)
- self.returns = {
- 'publicip': 'public_ip'
- }
-
- def get_vpn_gateway(self):
- args = {
- 'vpcid': self.get_vpc(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id')
- }
- vpn_gateways = self.query_api('listVpnGateways', **args)
- if vpn_gateways:
- return vpn_gateways['vpngateway'][0]
- return None
-
- def present_vpn_gateway(self):
- vpn_gateway = self.get_vpn_gateway()
- if not vpn_gateway:
- self.result['changed'] = True
- args = {
- 'vpcid': self.get_vpc(key='id'),
- 'account': self.get_account(key='name'),
- 'domainid': self.get_domain(key='id'),
- 'projectid': self.get_project(key='id')
- }
- if not self.module.check_mode:
- res = self.query_api('createVpnGateway', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- vpn_gateway = self.poll_job(res, 'vpngateway')
-
- return vpn_gateway
-
- def absent_vpn_gateway(self):
- vpn_gateway = self.get_vpn_gateway()
- if vpn_gateway:
- self.result['changed'] = True
- args = {
- 'id': vpn_gateway['id']
- }
- if not self.module.check_mode:
- res = self.query_api('deleteVpnGateway', **args)
-
- poll_async = self.module.params.get('poll_async')
- if poll_async:
- self.poll_job(res, 'vpngateway')
-
- return vpn_gateway
-
- def get_result(self, vpn_gateway):
- super(AnsibleCloudStackVpnGateway, self).get_result(vpn_gateway)
- if vpn_gateway:
- self.result['vpc'] = self.get_vpc(key='name')
- return self.result
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- vpc=dict(required=True),
- state=dict(choices=['present', 'absent'], default='present'),
- domain=dict(),
- account=dict(),
- project=dict(),
- zone=dict(),
- poll_async=dict(type='bool', default=True),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_vpn_gw = AnsibleCloudStackVpnGateway(module)
-
- state = module.params.get('state')
- if state == "absent":
- vpn_gateway = acs_vpn_gw.absent_vpn_gateway()
- else:
- vpn_gateway = acs_vpn_gw.present_vpn_gateway()
-
- result = acs_vpn_gw.get_result(vpn_gateway)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_zone.py b/lib/ansible/modules/cloud/cloudstack/cs_zone.py
deleted file mode 100644
index 4aa933c78a..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_zone.py
+++ /dev/null
@@ -1,384 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_zone
-short_description: Manages zones on Apache CloudStack based clouds.
-description:
- - Create, update and remove zones.
-version_added: '2.1'
-author: René Moser (@resmo)
-options:
- name:
- description:
- - Name of the zone.
- type: str
- required: true
- id:
- description:
- - uuid of the existing zone.
- type: str
- state:
- description:
- - State of the zone.
- type: str
- default: present
- choices: [ present, enabled, disabled, absent ]
- domain:
- description:
- - Domain the zone is related to.
- - Zone is a public zone if not set.
- type: str
- network_domain:
- description:
- - Network domain for the zone.
- type: str
- network_type:
- description:
- - Network type of the zone.
- type: str
- default: Basic
- choices: [ Basic, Advanced ]
- dns1:
- description:
- - First DNS for the zone.
- - Required if I(state=present)
- type: str
- dns2:
- description:
- - Second DNS for the zone.
- type: str
- internal_dns1:
- description:
- - First internal DNS for the zone.
- - If not set I(dns1) will be used on I(state=present).
- type: str
- internal_dns2:
- description:
- - Second internal DNS for the zone.
- type: str
- dns1_ipv6:
- description:
- - First DNS for IPv6 for the zone.
- type: str
- dns2_ipv6:
- description:
- - Second DNS for IPv6 for the zone.
- type: str
- guest_cidr_address:
- description:
- - Guest CIDR address for the zone.
- type: str
- dhcp_provider:
- description:
- - DHCP provider for the Zone.
- type: str
- local_storage_enabled:
- description:
- - Whether to enable local storage for the zone or not..
- type: bool
- securitygroups_enabled:
- description:
- - Whether the zone is security group enabled or not.
- type: bool
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Ensure a zone is present
- cs_zone:
- name: ch-zrh-ix-01
- dns1: 8.8.8.8
- dns2: 8.8.4.4
- network_type: basic
- delegate_to: localhost
-
-- name: Ensure a zone is disabled
- cs_zone:
- name: ch-zrh-ix-01
- state: disabled
- delegate_to: localhost
-
-- name: Ensure a zone is enabled
- cs_zone:
- name: ch-zrh-ix-01
- state: enabled
- delegate_to: localhost
-
-- name: Ensure a zone is absent
- cs_zone:
- name: ch-zrh-ix-01
- state: absent
- delegate_to: localhost
-'''
-
-RETURN = '''
----
-id:
- description: UUID of the zone.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
-name:
- description: Name of the zone.
- returned: success
- type: str
- sample: zone01
-dns1:
- description: First DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
-dns2:
- description: Second DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
-internal_dns1:
- description: First internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
-internal_dns2:
- description: Second internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
-dns1_ipv6:
- description: First IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8888"
-dns2_ipv6:
- description: Second IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8844"
-allocation_state:
- description: State of the zone.
- returned: success
- type: str
- sample: Enabled
-domain:
- description: Domain the zone is related to.
- returned: success
- type: str
- sample: ROOT
-network_domain:
- description: Network domain for the zone.
- returned: success
- type: str
- sample: example.com
-network_type:
- description: Network type for the zone.
- returned: success
- type: str
- sample: basic
-local_storage_enabled:
- description: Local storage offering enabled.
- returned: success
- type: bool
- sample: false
-securitygroups_enabled:
- description: Security groups support is enabled.
- returned: success
- type: bool
- sample: false
-guest_cidr_address:
- description: Guest CIDR address for the zone
- returned: success
- type: str
- sample: 10.1.1.0/24
-dhcp_provider:
- description: DHCP provider for the zone
- returned: success
- type: str
- sample: VirtualRouter
-zone_token:
- description: Zone token
- returned: success
- type: str
- sample: ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7
-tags:
- description: List of resource tags associated with the zone.
- returned: success
- type: dict
- sample: [ { "key": "foo", "value": "bar" } ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
- cs_required_together,
-)
-
-
-class AnsibleCloudStackZone(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackZone, self).__init__(module)
- self.returns = {
- 'dns1': 'dns1',
- 'dns2': 'dns2',
- 'internaldns1': 'internal_dns1',
- 'internaldns2': 'internal_dns2',
- 'ipv6dns1': 'dns1_ipv6',
- 'ipv6dns2': 'dns2_ipv6',
- 'domain': 'network_domain',
- 'networktype': 'network_type',
- 'securitygroupsenabled': 'securitygroups_enabled',
- 'localstorageenabled': 'local_storage_enabled',
- 'guestcidraddress': 'guest_cidr_address',
- 'dhcpprovider': 'dhcp_provider',
- 'allocationstate': 'allocation_state',
- 'zonetoken': 'zone_token',
- }
- self.zone = None
-
- def _get_common_zone_args(self):
- args = {
- 'name': self.module.params.get('name'),
- 'dns1': self.module.params.get('dns1'),
- 'dns2': self.module.params.get('dns2'),
- 'internaldns1': self.get_or_fallback('internal_dns1', 'dns1'),
- 'internaldns2': self.get_or_fallback('internal_dns2', 'dns2'),
- 'ipv6dns1': self.module.params.get('dns1_ipv6'),
- 'ipv6dns2': self.module.params.get('dns2_ipv6'),
- 'networktype': self.module.params.get('network_type'),
- 'domain': self.module.params.get('network_domain'),
- 'localstorageenabled': self.module.params.get('local_storage_enabled'),
- 'guestcidraddress': self.module.params.get('guest_cidr_address'),
- 'dhcpprovider': self.module.params.get('dhcp_provider'),
- }
- state = self.module.params.get('state')
- if state in ['enabled', 'disabled']:
- args['allocationstate'] = state.capitalize()
- return args
-
- def get_zone(self):
- if not self.zone:
- args = {}
-
- uuid = self.module.params.get('id')
- if uuid:
- args['id'] = uuid
- zones = self.query_api('listZones', **args)
- if zones:
- self.zone = zones['zone'][0]
- return self.zone
-
- args['name'] = self.module.params.get('name')
- zones = self.query_api('listZones', **args)
- if zones:
- self.zone = zones['zone'][0]
- return self.zone
-
- def present_zone(self):
- zone = self.get_zone()
- if zone:
- zone = self._update_zone()
- else:
- zone = self._create_zone()
- return zone
-
- def _create_zone(self):
- required_params = [
- 'dns1',
- ]
- self.module.fail_on_missing_params(required_params=required_params)
-
- self.result['changed'] = True
-
- args = self._get_common_zone_args()
- args['domainid'] = self.get_domain(key='id')
- args['securitygroupenabled'] = self.module.params.get('securitygroups_enabled')
-
- zone = None
- if not self.module.check_mode:
- res = self.query_api('createZone', **args)
- zone = res['zone']
- return zone
-
- def _update_zone(self):
- zone = self.get_zone()
-
- args = self._get_common_zone_args()
- args['id'] = zone['id']
-
- if self.has_changed(args, zone):
- self.result['changed'] = True
-
- if not self.module.check_mode:
- res = self.query_api('updateZone', **args)
- zone = res['zone']
- return zone
-
- def absent_zone(self):
- zone = self.get_zone()
- if zone:
- self.result['changed'] = True
-
- args = {
- 'id': zone['id']
- }
- if not self.module.check_mode:
- self.query_api('deleteZone', **args)
-
- return zone
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- id=dict(),
- name=dict(required=True),
- dns1=dict(),
- dns2=dict(),
- internal_dns1=dict(),
- internal_dns2=dict(),
- dns1_ipv6=dict(),
- dns2_ipv6=dict(),
- network_type=dict(default='Basic', choices=['Basic', 'Advanced']),
- network_domain=dict(),
- guest_cidr_address=dict(),
- dhcp_provider=dict(),
- local_storage_enabled=dict(type='bool'),
- securitygroups_enabled=dict(type='bool'),
- state=dict(choices=['present', 'enabled', 'disabled', 'absent'], default='present'),
- domain=dict(),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- required_together=cs_required_together(),
- supports_check_mode=True
- )
-
- acs_zone = AnsibleCloudStackZone(module)
-
- state = module.params.get('state')
- if state in ['absent']:
- zone = acs_zone.absent_zone()
- else:
- zone = acs_zone.present_zone()
-
- result = acs_zone.get_result(zone)
-
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/ansible/modules/cloud/cloudstack/cs_zone_info.py b/lib/ansible/modules/cloud/cloudstack/cs_zone_info.py
deleted file mode 100644
index cf8a0eddd2..0000000000
--- a/lib/ansible/modules/cloud/cloudstack/cs_zone_info.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2016, René Moser <mail@renemoser.net>
-# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
-
-from __future__ import absolute_import, division, print_function
-__metaclass__ = type
-
-ANSIBLE_METADATA = {'metadata_version': '1.1',
- 'status': ['stableinterface'],
- 'supported_by': 'community'}
-
-
-DOCUMENTATION = '''
----
-module: cs_zone_info
-short_description: Gathering information about zones from Apache CloudStack based clouds.
-description:
- - Gathering information from the API of a zone.
-version_added: '2.9'
-author: René Moser (@resmo)
-options:
- zone:
- description:
- - Name of the zone.
- - If not specified, all zones are returned
- type: str
- aliases: [ name ]
-extends_documentation_fragment: cloudstack
-'''
-
-EXAMPLES = '''
-- name: Gather information from a zone
- cs_zone_info:
- zone: ch-gva-1
- register: zone
- delegate_to: localhost
-
-- name: Show the returned results of the registered variable
- debug:
- msg: "{{ zone }}"
-
-- name: Gather information from all zones
- cs_zone_info:
- register: zones
- delegate_to: localhost
-
-- name: Show information on all zones
- debug:
- msg: "{{ zones }}"
-'''
-
-RETURN = '''
----
-zones:
- description: A list of matching zones.
- type: list
- returned: success
- contains:
- id:
- description: UUID of the zone.
- returned: success
- type: str
- sample: 04589590-ac63-4ffc-93f5-b698b8ac38b6
- name:
- description: Name of the zone.
- returned: success
- type: str
- sample: zone01
- dns1:
- description: First DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
- dns2:
- description: Second DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
- internal_dns1:
- description: First internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.8.8
- internal_dns2:
- description: Second internal DNS for the zone.
- returned: success
- type: str
- sample: 8.8.4.4
- dns1_ipv6:
- description: First IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8888"
- dns2_ipv6:
- description: Second IPv6 DNS for the zone.
- returned: success
- type: str
- sample: "2001:4860:4860::8844"
- allocation_state:
- description: State of the zone.
- returned: success
- type: str
- sample: Enabled
- domain:
- description: Domain the zone is related to.
- returned: success
- type: str
- sample: ROOT
- network_domain:
- description: Network domain for the zone.
- returned: success
- type: str
- sample: example.com
- network_type:
- description: Network type for the zone.
- returned: success
- type: str
- sample: basic
- local_storage_enabled:
- description: Local storage offering enabled.
- returned: success
- type: bool
- sample: false
- securitygroups_enabled:
- description: Security groups support is enabled.
- returned: success
- type: bool
- sample: false
- guest_cidr_address:
- description: Guest CIDR address for the zone
- returned: success
- type: str
- sample: 10.1.1.0/24
- dhcp_provider:
- description: DHCP provider for the zone
- returned: success
- type: str
- sample: VirtualRouter
- zone_token:
- description: Zone token
- returned: success
- type: str
- sample: ccb0a60c-79c8-3230-ab8b-8bdbe8c45bb7
- tags:
- description: List of resource tags associated with the zone.
- returned: success
- type: dict
- sample: [ { "key": "foo", "value": "bar" } ]
-'''
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.cloudstack import (
- AnsibleCloudStack,
- cs_argument_spec,
-)
-
-
-class AnsibleCloudStackZoneInfo(AnsibleCloudStack):
-
- def __init__(self, module):
- super(AnsibleCloudStackZoneInfo, self).__init__(module)
- self.returns = {
- 'dns1': 'dns1',
- 'dns2': 'dns2',
- 'internaldns1': 'internal_dns1',
- 'internaldns2': 'internal_dns2',
- 'ipv6dns1': 'dns1_ipv6',
- 'ipv6dns2': 'dns2_ipv6',
- 'domain': 'network_domain',
- 'networktype': 'network_type',
- 'securitygroupsenabled': 'securitygroups_enabled',
- 'localstorageenabled': 'local_storage_enabled',
- 'guestcidraddress': 'guest_cidr_address',
- 'dhcpprovider': 'dhcp_provider',
- 'allocationstate': 'allocation_state',
- 'zonetoken': 'zone_token',
- }
-
- def get_zone(self):
- if self.module.params['zone']:
- zones = [super(AnsibleCloudStackZoneInfo, self).get_zone()]
- else:
- zones = self.query_api('listZones')
- if zones:
- zones = zones['zone']
- else:
- zones = []
- return {
- 'zones': [self.update_result(resource) for resource in zones]
- }
-
-
-def main():
- argument_spec = cs_argument_spec()
- argument_spec.update(dict(
- zone=dict(type='str', aliases=['name']),
- ))
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- acs_zone_info = AnsibleCloudStackZoneInfo(module=module)
- result = acs_zone_info.get_zone()
- module.exit_json(**result)
-
-
-if __name__ == '__main__':
- main()