cs_instance: remove CloudStackException dep (#31724)
- fixes dep - fix docs
This commit is contained in:
parent
614a53734c
commit
8b8d5aaca7
2 changed files with 169 additions and 284 deletions
|
@ -27,192 +27,134 @@ options:
|
|||
- 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.
|
||||
required: false
|
||||
default: null
|
||||
display_name:
|
||||
description:
|
||||
- Custom display name of the instances.
|
||||
- Display name will be set to C(name) if not specified.
|
||||
- Either C(name) or C(display_name) is required.
|
||||
required: false
|
||||
default: null
|
||||
group:
|
||||
description:
|
||||
- Group in where the new instance should be in.
|
||||
required: false
|
||||
default: null
|
||||
state:
|
||||
description:
|
||||
- State of the instance.
|
||||
required: false
|
||||
default: 'present'
|
||||
choices: [ 'deployed', 'started', 'stopped', 'restarted', 'restored', 'destroyed', 'expunged', 'present', 'absent' ]
|
||||
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.
|
||||
required: false
|
||||
default: null
|
||||
cpu:
|
||||
description:
|
||||
- The number of CPUs to allocate to the instance, used with custom service offerings
|
||||
required: false
|
||||
default: null
|
||||
cpu_speed:
|
||||
description:
|
||||
- The clock speed/shares allocated to the instance, used with custom service offerings
|
||||
required: false
|
||||
default: null
|
||||
memory:
|
||||
description:
|
||||
- The memory allocated to the instance, used with custom service offerings
|
||||
required: false
|
||||
default: null
|
||||
template:
|
||||
description:
|
||||
- Name or id of the template to be used for creating the new instance.
|
||||
- Required when using C(state=present).
|
||||
- Mutually exclusive with C(ISO) option.
|
||||
required: false
|
||||
default: null
|
||||
iso:
|
||||
description:
|
||||
- Name or id of the ISO to be used for creating the new instance.
|
||||
- Required when using C(state=present).
|
||||
- Mutually exclusive with C(template) option.
|
||||
required: false
|
||||
default: null
|
||||
template_filter:
|
||||
description:
|
||||
- Name of the filter used to search for the template or iso.
|
||||
- Used for params C(iso) or C(template) on C(state=present).
|
||||
required: false
|
||||
default: 'executable'
|
||||
choices: [ 'featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable', 'community' ]
|
||||
aliases: [ 'iso_filter' ]
|
||||
default: executable
|
||||
choices: [ 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 C(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.
|
||||
required: false
|
||||
default: null
|
||||
choices: [ 'KVM', 'VMware', 'BareMetal', 'XenServer', 'LXC', 'HyperV', 'UCS', 'OVM' ]
|
||||
choices: [ KVM, VMware, BareMetal, XenServer, LXC, HyperV, UCS, OVM, Simulator ]
|
||||
keyboard:
|
||||
description:
|
||||
- Keyboard device type for the instance.
|
||||
required: false
|
||||
default: null
|
||||
choices: [ 'de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us' ]
|
||||
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.
|
||||
required: false
|
||||
default: []
|
||||
aliases: [ 'network' ]
|
||||
aliases: [ network ]
|
||||
ip_address:
|
||||
description:
|
||||
- IPv4 address for default instance's network during creation.
|
||||
required: false
|
||||
default: null
|
||||
ip6_address:
|
||||
description:
|
||||
- IPv6 address for default instance's network.
|
||||
required: false
|
||||
default: null
|
||||
ip_to_networks:
|
||||
description:
|
||||
- "List of mappings in the form {'network': NetworkName, 'ip': 1.2.3.4}"
|
||||
- Mutually exclusive with C(networks) option.
|
||||
required: false
|
||||
default: null
|
||||
aliases: [ 'ip_to_network' ]
|
||||
aliases: [ ip_to_network ]
|
||||
disk_offering:
|
||||
description:
|
||||
- Name of the disk offering to be used.
|
||||
required: false
|
||||
default: null
|
||||
disk_size:
|
||||
description:
|
||||
- Disk size in GByte required if deploying instance from ISO.
|
||||
required: false
|
||||
default: null
|
||||
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)
|
||||
required: false
|
||||
default: null
|
||||
security_groups:
|
||||
description:
|
||||
- List of security groups the instance to be applied to.
|
||||
required: false
|
||||
default: null
|
||||
aliases: [ 'security_group' ]
|
||||
aliases: [ security_group ]
|
||||
domain:
|
||||
description:
|
||||
- Domain the instance is related to.
|
||||
required: false
|
||||
default: null
|
||||
account:
|
||||
description:
|
||||
- Account the instance is related to.
|
||||
required: false
|
||||
default: null
|
||||
project:
|
||||
description:
|
||||
- Name of the project the instance to be deployed in.
|
||||
required: false
|
||||
default: null
|
||||
zone:
|
||||
description:
|
||||
- Name of the zone in which the instance should be deployed.
|
||||
- If not set, default zone is used.
|
||||
required: false
|
||||
default: null
|
||||
ssh_key:
|
||||
description:
|
||||
- Name of the SSH key to be deployed on the new instance.
|
||||
required: false
|
||||
default: null
|
||||
affinity_groups:
|
||||
description:
|
||||
- Affinity groups names to be applied to the new instance.
|
||||
required: false
|
||||
default: []
|
||||
aliases: [ 'affinity_group' ]
|
||||
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 C(CLOUDSTACK_METHOD=post) to increase the HTTP_GET size limit of 2KB to 32 KB.
|
||||
required: false
|
||||
default: null
|
||||
force:
|
||||
description:
|
||||
- Force stop/start the instance if required to apply changes, otherwise a running instance will not be changed.
|
||||
required: false
|
||||
default: false
|
||||
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. C(tags: [])."
|
||||
required: false
|
||||
default: null
|
||||
aliases: [ 'tag' ]
|
||||
aliases: [ tag ]
|
||||
poll_async:
|
||||
description:
|
||||
- Poll async jobs until job has finished.
|
||||
required: false
|
||||
default: true
|
||||
extends_documentation_fragment: cloudstack
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Create a instance from an ISO
|
||||
# NOTE: Names of offerings and ISOs depending on the CloudStack configuration.
|
||||
- cs_instance:
|
||||
- name: create a instance from an ISO
|
||||
cs_instance:
|
||||
name: web-vm-1
|
||||
iso: Linux Debian 7 64-bit
|
||||
hypervisor: VMware
|
||||
|
@ -227,7 +169,7 @@ EXAMPLES = '''
|
|||
- Storage Integration
|
||||
delegate_to: localhost
|
||||
|
||||
# For changing a running instance, use the 'force' parameter
|
||||
- name: for changing a running instance, use the 'force' parameter
|
||||
- cs_instance:
|
||||
name: web-vm-1
|
||||
display_name: web-vm-01.example.com
|
||||
|
@ -236,9 +178,9 @@ EXAMPLES = '''
|
|||
force: yes
|
||||
delegate_to: localhost
|
||||
|
||||
# Create or update a instance on Exoscale's public cloud using display_name.
|
||||
# Note: user_data can be used to kickstart the instance using cloud-init yaml config.
|
||||
- cs_instance:
|
||||
# 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
|
||||
|
@ -254,8 +196,8 @@ EXAMPLES = '''
|
|||
- nginx
|
||||
delegate_to: localhost
|
||||
|
||||
# Create an instance with multiple interfaces specifying the IP addresses
|
||||
- cs_instance:
|
||||
- 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
|
||||
|
@ -266,19 +208,19 @@ EXAMPLES = '''
|
|||
ip: 192.0.2.1
|
||||
delegate_to: localhost
|
||||
|
||||
# Ensure an instance is stopped
|
||||
- cs_instance:
|
||||
- name: ensure an instance is stopped
|
||||
cs_instance:
|
||||
name: web-vm-1
|
||||
state: stopped
|
||||
delegate_to: localhost
|
||||
|
||||
# Ensure an instance is running
|
||||
- cs_instance:
|
||||
- name: ensure an instance is running
|
||||
cs_instance:
|
||||
name: web-vm-1
|
||||
state: started
|
||||
delegate_to: localhost
|
||||
|
||||
# Remove an instance
|
||||
- name: remove an instance
|
||||
- cs_instance:
|
||||
name: web-vm-1
|
||||
state: absent
|
||||
|
@ -405,12 +347,6 @@ instance_name:
|
|||
'''
|
||||
|
||||
import base64
|
||||
|
||||
try:
|
||||
from cs import CloudStackException
|
||||
except ImportError:
|
||||
pass # Handled in AnsibleCloudStack.__init__
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.cloudstack import (AnsibleCloudStack, CS_HYPERVISORS, cs_argument_spec,
|
||||
cs_required_together)
|
||||
|
@ -421,35 +357,33 @@ 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',
|
||||
'keypair': 'ssh_key',
|
||||
'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',
|
||||
}
|
||||
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.cs.listServiceOfferings()
|
||||
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'] ]:
|
||||
if service_offering in [s['name'], s['id']]:
|
||||
return s['id']
|
||||
self.module.fail_json(msg="Service offering '%s' not found" % service_offering)
|
||||
|
||||
self.fail_json(msg="Service offering '%s' not found" % service_offering)
|
||||
|
||||
def get_template_or_iso(self, key=None):
|
||||
template = self.module.params.get('template')
|
||||
|
@ -458,12 +392,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
if not template and not iso:
|
||||
return None
|
||||
|
||||
args = {}
|
||||
args['account'] = self.get_account(key='name')
|
||||
args['domainid'] = self.get_domain(key='id')
|
||||
args['projectid'] = self.get_project(key='id')
|
||||
args['zoneid'] = self.get_zone(key='id')
|
||||
args['isrecursive'] = True
|
||||
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,
|
||||
}
|
||||
|
||||
if template:
|
||||
if self.template:
|
||||
|
@ -471,29 +406,34 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
rootdisksize = self.module.params.get('root_disk_size')
|
||||
args['templatefilter'] = self.module.params.get('template_filter')
|
||||
templates = self.cs.listTemplates(**args)
|
||||
templates = self.query_api('listTemplates', **args)
|
||||
if templates:
|
||||
for t in templates['template']:
|
||||
if template in [ t['displaytext'], t['name'], t['id'] ]:
|
||||
if rootdisksize and t['size'] > rootdisksize*1024**3:
|
||||
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)
|
||||
more_info = ""
|
||||
|
||||
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')
|
||||
isos = self.cs.listIsos(**args)
|
||||
isos = self.query_api('listIsos', **args)
|
||||
if isos:
|
||||
for i in isos['iso']:
|
||||
if iso in [ i['displaytext'], i['name'], i['id'] ]:
|
||||
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):
|
||||
|
@ -506,7 +446,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
'projectid': self.get_project(key='id'),
|
||||
}
|
||||
# Do not pass zoneid, as the instance name must be unique across zones.
|
||||
instances = self.cs.listVirtualMachines(**args)
|
||||
instances = self.query_api('listVirtualMachines', **args)
|
||||
if instances:
|
||||
for v in instances['virtualmachine']:
|
||||
if instance_name.lower() in [v['name'].lower(), v['displayname'].lower(), v['id']]:
|
||||
|
@ -514,7 +454,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
break
|
||||
return self.instance
|
||||
|
||||
|
||||
def _get_instance_user_data(self, instance):
|
||||
# Query the user data if we need to
|
||||
if 'userdata' in instance:
|
||||
|
@ -522,11 +461,10 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
user_data = ""
|
||||
if self.get_user_data() is not None:
|
||||
res = self.cs.getVirtualMachineUserData(virtualmachineid=instance['id'])
|
||||
user_data = res['virtualmachineuserdata'].get('userdata',"")
|
||||
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:
|
||||
|
@ -553,11 +491,8 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
'projectid': self.get_project('id'),
|
||||
'name': ssh_key_name,
|
||||
}
|
||||
ssh_key_pairs = self.cs.listSSHKeyPairs(**args)
|
||||
if 'errortext' in ssh_key_pairs:
|
||||
self.module.fail_json(msg="Failed: '%s'" % ssh_key_pairs['errortext'])
|
||||
|
||||
elif 'sshkeypair' in ssh_key_pairs:
|
||||
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:
|
||||
|
@ -592,7 +527,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
return False
|
||||
|
||||
security_groups = [s.lower() for s in security_groups]
|
||||
instance_security_groups = self.instance.get('securitygroup',[])
|
||||
instance_security_groups = self.instance.get('securitygroup') or []
|
||||
|
||||
instance_security_group_names = []
|
||||
for instance_security_group in instance_security_groups:
|
||||
|
@ -606,7 +541,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_network_ids(self, network_names=None):
|
||||
if network_names is None:
|
||||
network_names = self.module.params.get('networks')
|
||||
|
@ -620,7 +554,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
'projectid': self.get_project(key='id'),
|
||||
'zoneid': self.get_zone(key='id'),
|
||||
}
|
||||
networks = self.cs.listNetworks(**args)
|
||||
networks = self.query_api('listNetworks', **args)
|
||||
if not networks:
|
||||
self.module.fail_json(msg="No networks available")
|
||||
|
||||
|
@ -628,7 +562,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
network_displaytexts = []
|
||||
for network_name in network_names:
|
||||
for n in networks['network']:
|
||||
if network_name in [ n['displaytext'], n['name'], n['id'] ]:
|
||||
if network_name in [n['displaytext'], n['name'], n['id']]:
|
||||
network_ids.append(n['id'])
|
||||
network_displaytexts.append(n['name'])
|
||||
break
|
||||
|
@ -638,7 +572,6 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
return network_ids
|
||||
|
||||
|
||||
def present_instance(self, start_vm=True):
|
||||
instance = self.get_instance()
|
||||
|
||||
|
@ -656,14 +589,12 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
return instance
|
||||
|
||||
|
||||
def get_user_data(self):
|
||||
user_data = self.module.params.get('user_data')
|
||||
if user_data is not None:
|
||||
user_data = base64.b64encode(str(user_data))
|
||||
return user_data
|
||||
|
||||
|
||||
def get_details(self):
|
||||
res = None
|
||||
cpu = self.module.params.get('cpu')
|
||||
|
@ -677,43 +608,39 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
}]
|
||||
return res
|
||||
|
||||
|
||||
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')
|
||||
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'] = ','.join(self.module.params.get('affinity_groups'))
|
||||
args['details'] = self.get_details()
|
||||
|
||||
security_groups = self.module.params.get('security_groups')
|
||||
if security_groups is not None:
|
||||
args['securitygroupnames'] = ','.join(security_groups)
|
||||
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')
|
||||
|
||||
template_iso = self.get_template_or_iso()
|
||||
if 'hypervisor' not in template_iso:
|
||||
|
@ -721,29 +648,27 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
instance = None
|
||||
if not self.module.check_mode:
|
||||
instance = self.cs.deployVirtualMachine(**args)
|
||||
|
||||
if 'errortext' in instance:
|
||||
self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
|
||||
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 = {}
|
||||
args_service_offering['id'] = instance['id']
|
||||
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 = {}
|
||||
args_instance_update['id'] = instance['id']
|
||||
args_instance_update['userdata'] = self.get_user_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'):
|
||||
|
@ -777,9 +702,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
|
||||
# Change service offering
|
||||
if service_offering_changed:
|
||||
res = self.cs.changeServiceForVirtualMachine(**args_service_offering)
|
||||
if 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
res = self.query_api('changeServiceForVirtualMachine', **args_service_offering)
|
||||
instance = res['virtualmachine']
|
||||
self.instance = instance
|
||||
|
||||
|
@ -787,9 +710,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
if instance_changed or security_groups_changed:
|
||||
if security_groups_changed:
|
||||
args_instance_update['securitygroupnames'] = ','.join(self.module.params.get('security_groups'))
|
||||
res = self.cs.updateVirtualMachine(**args_instance_update)
|
||||
if 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
res = self.query_api('updateVirtualMachine', **args_instance_update)
|
||||
instance = res['virtualmachine']
|
||||
self.instance = instance
|
||||
|
||||
|
@ -800,10 +721,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
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.cs.resetSSHKeyForVirtualMachine(**args_ssh_key)
|
||||
if 'errortext' in instance:
|
||||
self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
|
||||
|
||||
instance = self.query_api('resetSSHKeyForVirtualMachine', **args_ssh_key)
|
||||
instance = self.poll_job(instance, 'virtualmachine')
|
||||
self.instance = instance
|
||||
|
||||
|
@ -815,58 +733,46 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
"Use force=true to allow the instance %s to be stopped/started." % instance['name'])
|
||||
return instance
|
||||
|
||||
|
||||
def recover_instance(self, instance):
|
||||
if instance['state'].lower() in [ 'destroying', 'destroyed' ]:
|
||||
if instance['state'].lower() in ['destroying', 'destroyed']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
res = self.cs.recoverVirtualMachine(id=instance['id'])
|
||||
if 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
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.cs.destroyVirtualMachine(id=instance['id'])
|
||||
|
||||
if 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
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' ]:
|
||||
if instance['state'].lower() in ['destroying', 'destroyed']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
res = self.cs.destroyVirtualMachine(id=instance['id'], expunge=True)
|
||||
res = self.query_api('destroyVirtualMachine', id=instance['id'], expunge=True)
|
||||
|
||||
elif instance['state'].lower() not in [ 'expunging' ]:
|
||||
elif instance['state'].lower() not in ['expunging']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
res = self.cs.destroyVirtualMachine(id=instance['id'], expunge=True)
|
||||
|
||||
if res and 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
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 instanciated
|
||||
|
@ -877,17 +783,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
if instance['state'].lower() in ['starting', 'running']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
instance = self.cs.stopVirtualMachine(id=instance['id'])
|
||||
|
||||
if 'errortext' in instance:
|
||||
self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
|
||||
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 instanciated
|
||||
|
@ -898,38 +800,30 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
if instance['state'].lower() in ['stopped', 'stopping']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
instance = self.cs.startVirtualMachine(id=instance['id'])
|
||||
|
||||
if 'errortext' in instance:
|
||||
self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
|
||||
instance = self.query_api('startVirtualMachine', id=instance['id'])
|
||||
|
||||
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 instanciated
|
||||
if instance:
|
||||
if instance['state'].lower() in [ 'running', 'starting' ]:
|
||||
if instance['state'].lower() in ['running', 'starting']:
|
||||
self.result['changed'] = True
|
||||
if not self.module.check_mode:
|
||||
instance = self.cs.rebootVirtualMachine(id=instance['id'])
|
||||
|
||||
if 'errortext' in instance:
|
||||
self.module.fail_json(msg="Failed: '%s'" % instance['errortext'])
|
||||
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' ]:
|
||||
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
|
||||
|
@ -938,16 +832,13 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
args = {}
|
||||
args['templateid'] = self.get_template_or_iso(key='id')
|
||||
args['virtualmachineid'] = instance['id']
|
||||
res = self.cs.restoreVirtualMachine(**args)
|
||||
if 'errortext' in res:
|
||||
self.module.fail_json(msg="Failed: '%s'" % res['errortext'])
|
||||
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:
|
||||
|
@ -972,38 +863,38 @@ class AnsibleCloudStackInstance(AnsibleCloudStack):
|
|||
def main():
|
||||
argument_spec = cs_argument_spec()
|
||||
argument_spec.update(dict(
|
||||
name = dict(default=None),
|
||||
display_name = dict(default=None),
|
||||
group = dict(default=None),
|
||||
state = dict(choices=['present', 'deployed', 'started', 'stopped', 'restarted', 'restored', 'absent', 'destroyed', 'expunged'], default='present'),
|
||||
service_offering = dict(default=None),
|
||||
cpu = dict(default=None, type='int'),
|
||||
cpu_speed = dict(default=None, type='int'),
|
||||
memory = dict(default=None, type='int'),
|
||||
template = dict(default=None),
|
||||
iso = dict(default=None),
|
||||
template_filter = dict(default="executable", aliases=['iso_filter'], choices=['featured', 'self', 'selfexecutable', 'sharedexecutable', 'executable',
|
||||
'community']),
|
||||
networks = dict(type='list', aliases=[ 'network' ], default=None),
|
||||
ip_to_networks = dict(type='list', aliases=['ip_to_network'], default=None),
|
||||
ip_address = dict(defaul=None),
|
||||
ip6_address = dict(defaul=None),
|
||||
disk_offering = dict(default=None),
|
||||
disk_size = dict(type='int', default=None),
|
||||
root_disk_size = dict(type='int', default=None),
|
||||
keyboard = dict(choices=['de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us'], default=None),
|
||||
hypervisor = dict(choices=CS_HYPERVISORS, default=None),
|
||||
security_groups = dict(type='list', aliases=[ 'security_group' ], default=None),
|
||||
affinity_groups = dict(type='list', aliases=[ 'affinity_group' ], default=[]),
|
||||
domain = dict(default=None),
|
||||
account = dict(default=None),
|
||||
project = dict(default=None),
|
||||
user_data = dict(default=None),
|
||||
zone = dict(default=None),
|
||||
ssh_key = dict(default=None),
|
||||
force = dict(type='bool', default=False),
|
||||
tags = dict(type='list', aliases=[ 'tag' ], default=None),
|
||||
poll_async = dict(type='bool', default=True),
|
||||
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=['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(defaul=None),
|
||||
ip6_address=dict(defaul=None),
|
||||
disk_offering=dict(),
|
||||
disk_size=dict(type='int'),
|
||||
root_disk_size=dict(type='int'),
|
||||
keyboard=dict(choices=['de', 'de-ch', 'es', 'fi', 'fr', 'fr-be', 'fr-ch', 'is', 'it', 'jp', 'nl-be', 'no', 'pt', 'uk', 'us']),
|
||||
hypervisor=dict(choices=CS_HYPERVISORS),
|
||||
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']),
|
||||
poll_async=dict(type='bool', default=True),
|
||||
))
|
||||
|
||||
required_together = cs_required_together()
|
||||
|
@ -1014,53 +905,48 @@ def main():
|
|||
module = AnsibleModule(
|
||||
argument_spec=argument_spec,
|
||||
required_together=required_together,
|
||||
required_one_of = (
|
||||
required_one_of=(
|
||||
['display_name', 'name'],
|
||||
),
|
||||
mutually_exclusive = (
|
||||
mutually_exclusive=(
|
||||
['template', 'iso'],
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
try:
|
||||
acs_instance = AnsibleCloudStackInstance(module)
|
||||
acs_instance = AnsibleCloudStackInstance(module)
|
||||
|
||||
state = module.params.get('state')
|
||||
state = module.params.get('state')
|
||||
|
||||
if state in ['absent', 'destroyed']:
|
||||
instance = acs_instance.absent_instance()
|
||||
if state in ['absent', 'destroyed']:
|
||||
instance = acs_instance.absent_instance()
|
||||
|
||||
elif state in ['expunged']:
|
||||
instance = acs_instance.expunge_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 ['restored']:
|
||||
acs_instance.present_instance()
|
||||
instance = acs_instance.restore_instance()
|
||||
|
||||
elif state in ['present', 'deployed']:
|
||||
instance = acs_instance.present_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 ['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 ['started']:
|
||||
acs_instance.present_instance()
|
||||
instance = acs_instance.start_instance()
|
||||
|
||||
elif state in ['restarted']:
|
||||
acs_instance.present_instance()
|
||||
instance = acs_instance.restart_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)
|
||||
|
||||
except CloudStackException as e:
|
||||
module.fail_json(msg='CloudStackException: %s' % str(e))
|
||||
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)
|
||||
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ lib/ansible/modules/cloud/azure/azure_rm_virtualmachine.py
|
|||
lib/ansible/modules/cloud/azure/azure_rm_virtualnetwork.py
|
||||
lib/ansible/modules/cloud/azure/azure_rm_virtualnetwork_facts.py
|
||||
lib/ansible/modules/cloud/centurylink/clc_loadbalancer.py
|
||||
lib/ansible/modules/cloud/cloudstack/cs_instance.py
|
||||
lib/ansible/modules/cloud/cloudstack/_cs_nic.py
|
||||
lib/ansible/modules/cloud/docker/_docker.py
|
||||
lib/ansible/modules/cloud/docker/docker_container.py
|
||||
|
|
Loading…
Reference in a new issue