From 37b22673fb21d633d1a932175107666940679072 Mon Sep 17 00:00:00 2001 From: Rene Moser Date: Fri, 30 Jun 2017 14:14:33 +0200 Subject: [PATCH] cloudstack: cs_instance: fix KeyError: 'sshkeypair' --- .../modules/cloud/cloudstack/cs_instance.py | 49 ++++++++++++------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/lib/ansible/modules/cloud/cloudstack/cs_instance.py b/lib/ansible/modules/cloud/cloudstack/cs_instance.py index ea92fbcfd65..61713dc5893 100644 --- a/lib/ansible/modules/cloud/cloudstack/cs_instance.py +++ b/lib/ansible/modules/cloud/cloudstack/cs_instance.py @@ -561,37 +561,50 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): 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.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: + 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 - if ssh_key_name == instance_ssh_key_name: - return False + # 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 - args = { - 'domainid': self.get_domain('id'), - 'account': self.get_account('name'), - 'projectid': self.get_project('id') - } - - args['name'] = instance_ssh_key_name - res = self.cs.listSSHKeyPairs(**args) - instance_ssh_key = res['sshkeypair'][0] - - args['name'] = ssh_key_name - res = self.cs.listSSHKeyPairs(**args) - param_ssh_key = res['sshkeypair'][0] - if param_ssh_key['fingerprint'] != instance_ssh_key['fingerprint']: + # 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: @@ -710,7 +723,7 @@ class AnsibleCloudStackInstance(AnsibleCloudStack): 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.module.params.get('ssh_key') + 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')