summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené Moser <mail@renemoser.net>2016-11-20 23:51:50 +0100
committerGitHub <noreply@github.com>2016-11-20 23:51:50 +0100
commit72f75fd9e08cd7e1412bbb94390e255ed3059d3e (patch)
tree4d5c76866e918c2368af507987eb4f97ce5e3e3d
parent493fb4b665225397259e9e6480c6d3e951726989 (diff)
downloadansible-72f75fd9e08cd7e1412bbb94390e255ed3059d3e.tar.gz
cloudstack: add helpers to distinguish VMs not in VPC (#18560)
VMs in VPC and not in VPC can have an identical name. As a result VMs in a VPC must be sorted out if no VPC is given. Due the API limitation, the only way is to check if the network of the VM is in a VPC.
-rw-r--r--lib/ansible/module_utils/cloudstack.py37
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/ansible/module_utils/cloudstack.py b/lib/ansible/module_utils/cloudstack.py
index 092ade2f0d..ddad13d05d 100644
--- a/lib/ansible/module_utils/cloudstack.py
+++ b/lib/ansible/module_utils/cloudstack.py
@@ -107,6 +107,9 @@ class AnsibleCloudStack(object):
self.module = module
self._connect()
+ # Helper for VPCs
+ self._vpc_networks_ids = None
+
self.domain = None
self.account = None
self.project = None
@@ -238,6 +241,32 @@ class AnsibleCloudStack(object):
self.module.fail_json(msg="VPC '%s' not found" % vpc)
+ def is_vm_in_vpc(self, vm):
+ for n in vm.get('nic'):
+ if n.get('isdefault', False):
+ return self.is_vpc_network(network_id=n['networkid'])
+ self.module.fail_json(msg="VM has no default nic")
+
+
+ def is_vpc_network(self, network_id):
+ """Returns True if network is in VPC."""
+ # This is an efficient way to query a lot of networks at a time
+ if self._vpc_networks_ids is 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'),
+ }
+ vpcs = self.cs.listVPCs(**args)
+ self._vpc_networks_ids = []
+ if vpcs:
+ for vpc in vpcs['vpc']:
+ for n in vpc.get('network',[]):
+ self._vpc_networks_ids.append(n['id'])
+ return network_id in self._vpc_networks_ids
+
+
def get_network(self, key=None):
"""Return a network dictionary or the value of given key of."""
if self.network:
@@ -347,16 +376,22 @@ class AnsibleCloudStack(object):
if not vm:
self.module.fail_json(msg="Virtual machine param 'vm' is required")
+ vpc_id = self.get_vpc(key='id')
+
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'),
- 'vpcid': self.get_vpc(key='id'),
+ 'vpcid': vpc_id,
}
vms = self.cs.listVirtualMachines(**args)
if vms:
for v in vms['virtualmachine']:
+ # Due the limitation of the API, there is no easy way (yet) to get only those VMs
+ # not belonging to a VPC.
+ if not vpc_id and self.is_vm_in_vpc(vm=v):
+ continue
if vm.lower() in [ v['name'].lower(), v['displayname'].lower(), v['id'] ]:
self.vm = v
return self._get_by_key(key, self.vm)