diff -Nru cloud-init-0.7.7~bzr1091/debian/changelog cloud-init-0.7.7~bzr1091/debian/changelog --- cloud-init-0.7.7~bzr1091/debian/changelog 2015-11-05 19:36:44.000000000 +0000 +++ cloud-init-0.7.7~bzr1091/debian/changelog 2015-11-17 17:40:42.000000000 +0000 @@ -1,3 +1,11 @@ +cloud-init (0.7.7~bzr1091-0ubuntu12) vivid; urgency=medium + + * d/patches/lp-1506244-azure-ssh-key-values.patch: AZURE: Add support + and preference for fabric provided public SSH public key values over + fingerprints (LP: #1506244). + + -- Ben Howard Tue, 17 Nov 2015 10:02:41 -0700 + cloud-init (0.7.7~bzr1091-0ubuntu11) vivid; urgency=medium * d/patches/lp-1177432-same-archives-as-ubuntu-server.patch: use the diff -Nru cloud-init-0.7.7~bzr1091/debian/patches/lp-1506244-azure-ssh-key-values.patch cloud-init-0.7.7~bzr1091/debian/patches/lp-1506244-azure-ssh-key-values.patch --- cloud-init-0.7.7~bzr1091/debian/patches/lp-1506244-azure-ssh-key-values.patch 1970-01-01 00:00:00.000000000 +0000 +++ cloud-init-0.7.7~bzr1091/debian/patches/lp-1506244-azure-ssh-key-values.patch 2015-11-17 17:17:01.000000000 +0000 @@ -0,0 +1,150 @@ +Description: AZURE: add support/preference for SSH public key values + Azure has started to support SSH public key values in addition to SSH + public key fingerprints. Per MS, this patch prefers fabric provided + values instead of fingerprints. +Author: Ben Howard +Origin: upstream, http://bazaar.launchpad.net/~cloud-init-dev/cloud-init/trunk/revision/1149 +Bug: https://bugs.launchpad.net/cloud-init/+bug/1506244 + +--- a/cloudinit/sources/DataSourceAzure.py ++++ b/cloudinit/sources/DataSourceAzure.py +@@ -148,9 +148,15 @@ + wait_for = [shcfgxml] + + fp_files = [] ++ key_value = None + for pk in self.cfg.get('_pubkeys', []): +- bname = str(pk['fingerprint'] + ".crt") +- fp_files += [os.path.join(ddir, bname)] ++ if pk.get('value', None): ++ key_value = pk['value'] ++ LOG.debug("ssh authentication: using value from fabric") ++ else: ++ bname = str(pk['fingerprint'] + ".crt") ++ fp_files += [os.path.join(ddir, bname)] ++ LOG.debug("ssh authentication: using fingerprint from fabirc") + + missing = util.log_time(logfunc=LOG.debug, msg="waiting for files", + func=wait_for_files, +@@ -166,7 +172,8 @@ + metadata['instance-id'] = iid_from_shared_config(shcfgxml) + except ValueError as e: + LOG.warn("failed to get instance id in %s: %s", shcfgxml, e) +- metadata['public-keys'] = pubkeys_from_crt_files(fp_files) ++ ++ metadata['public-keys'] = key_value or pubkeys_from_crt_files(fp_files) + return metadata + + def get_data(self): +@@ -433,7 +440,7 @@ + elem.text != DEF_PASSWD_REDACTION): + elem.text = DEF_PASSWD_REDACTION + return ET.tostring(root) +- except Exception as e: ++ except Exception: + LOG.critical("failed to redact userpassword in {}".format(fname)) + return cnt + +@@ -497,7 +504,8 @@ + for pk_node in pubkeys: + if not pk_node.hasChildNodes(): + continue +- cur = {'fingerprint': "", 'path': ""} ++ ++ cur = {'fingerprint': "", 'path': "", 'value': ""} + for child in pk_node.childNodes: + if child.nodeType == text_node or not child.localName: + continue +--- a/tests/unittests/test_datasource/test_azure.py ++++ b/tests/unittests/test_datasource/test_azure.py +@@ -54,10 +54,13 @@ + + if pubkeys: + content += "\n" +- for fp, path in pubkeys: ++ for fp, path, value in pubkeys: + content += " " +- content += ("%s%s" % +- (fp, path)) ++ if fp and path: ++ content += ("%s%s" % ++ (fp, path)) ++ if value: ++ content += "%s" % value + content += "\n" + content += "" + content += """ +@@ -174,7 +177,7 @@ + def xml_notequals(self, oxml, nxml): + try: + self.xml_equals(oxml, nxml) +- except AssertionError as e: ++ except AssertionError: + return + raise AssertionError("XML is the same") + +@@ -297,10 +300,10 @@ + self.assertFalse(ret) + self.assertFalse('agent_invoked' in data) + +- def test_cfg_has_pubkeys(self): ++ def test_cfg_has_pubkeys_fingerprint(self): + odata = {'HostName': "myhost", 'UserName': "myuser"} +- mypklist = [{'fingerprint': 'fp1', 'path': 'path1'}] +- pubkeys = [(x['fingerprint'], x['path']) for x in mypklist] ++ mypklist = [{'fingerprint': 'fp1', 'path': 'path1', 'value': ''}] ++ pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist] + data = {'ovfcontent': construct_valid_ovf_env(data=odata, + pubkeys=pubkeys)} + +@@ -309,6 +312,39 @@ + self.assertTrue(ret) + for mypk in mypklist: + self.assertIn(mypk, dsrc.cfg['_pubkeys']) ++ self.assertIn('pubkey_from', dsrc.metadata['public-keys'][-1]) ++ ++ def test_cfg_has_pubkeys_value(self): ++ # make sure that provided key is used over fingerprint ++ odata = {'HostName': "myhost", 'UserName': "myuser"} ++ mypklist = [{'fingerprint': 'fp1', 'path': 'path1', 'value': 'value1'}] ++ pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist] ++ data = {'ovfcontent': construct_valid_ovf_env(data=odata, ++ pubkeys=pubkeys)} ++ ++ dsrc = self._get_ds(data) ++ ret = dsrc.get_data() ++ self.assertTrue(ret) ++ ++ for mypk in mypklist: ++ self.assertIn(mypk, dsrc.cfg['_pubkeys']) ++ self.assertIn(mypk['value'], dsrc.metadata['public-keys']) ++ ++ def test_cfg_has_no_fingerprint_has_value(self): ++ # test value is used when fingerprint not provided ++ odata = {'HostName': "myhost", 'UserName': "myuser"} ++ mypklist = [{'fingerprint': None, 'path': 'path1', 'value': 'value1'}] ++ pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist] ++ data = {'ovfcontent': construct_valid_ovf_env(data=odata, ++ pubkeys=pubkeys)} ++ ++ dsrc = self._get_ds(data) ++ ret = dsrc.get_data() ++ self.assertTrue(ret) ++ ++ for mypk in mypklist: ++ self.assertIn(mypk['value'], dsrc.metadata['public-keys']) ++ + + def test_default_ephemeral(self): + # make sure the ephemeral device works +@@ -642,8 +678,8 @@ + DataSourceAzure.read_azure_ovf, invalid_xml) + + def test_load_with_pubkeys(self): +- mypklist = [{'fingerprint': 'fp1', 'path': 'path1'}] +- pubkeys = [(x['fingerprint'], x['path']) for x in mypklist] ++ mypklist = [{'fingerprint': 'fp1', 'path': 'path1', 'value': ''}] ++ pubkeys = [(x['fingerprint'], x['path'], x['value']) for x in mypklist] + content = construct_valid_ovf_env(pubkeys=pubkeys) + (_md, _ud, cfg) = DataSourceAzure.read_azure_ovf(content) + for mypk in mypklist: diff -Nru cloud-init-0.7.7~bzr1091/debian/patches/series cloud-init-0.7.7~bzr1091/debian/patches/series --- cloud-init-0.7.7~bzr1091/debian/patches/series 2015-11-05 19:37:34.000000000 +0000 +++ cloud-init-0.7.7~bzr1091/debian/patches/series 2015-11-17 17:02:41.000000000 +0000 @@ -12,3 +12,4 @@ lp-1493453-nocloudds-vendor_data.patch lp-1461242-generate-ed25519-host-keys.patch lp-1177432-same-archives-as-ubuntu-server.patch +lp-1506244-azure-ssh-key-values.patch