diff options
author | René Moser <mail@renemoser.net> | 2016-11-20 23:51:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-20 23:51:50 +0100 |
commit | 72f75fd9e08cd7e1412bbb94390e255ed3059d3e (patch) | |
tree | 4d5c76866e918c2368af507987eb4f97ce5e3e3d | |
parent | 493fb4b665225397259e9e6480c6d3e951726989 (diff) | |
download | ansible-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.py | 37 |
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) |