Skip to content

Commit fd83fcb

Browse files
nocloud: accept dict-of-strings public-keys format
Some sources serialise public-keys as a dict of {name: key-string} rather than {name: {'openssh-key': key-string}}. KubeVirt's accessCredentials sshPublicKey noCloud propagation does this, defining NoCloudMetadata.PublicSSHKeys as map[string]string [1] and assigning it directly in readCloudInitNoCloudMetaData [2]. The current third branch of get_public_keys() then calls .get('openssh-key') on a string value and raises "'str' object has no attribute 'get'". Accept both shapes. [1] https://github.com/kubevirt/kubevirt/blob/623bf15e7553875860ece1a382a9e35bfbd61a26/pkg/cloud-init/cloud-init.go#L84 [2] https://github.com/kubevirt/kubevirt/blob/623bf15e7553875860ece1a382a9e35bfbd61a26/pkg/cloud-init/cloud-init.go#L402-L408 AI-assisted contribution: I reviewed the change and submit it under the DCO terms at https://github.com/cloudbase/cloudbase-init/blob/master/DCO#L16 (clause (a) — the contribution is mine). Signed-off-by: mattia-eleuteri <mattia@hidora.io>
1 parent e7058ec commit fd83fcb

2 files changed

Lines changed: 20 additions & 1 deletion

File tree

cloudbaseinit/metadata/services/nocloudservice.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,13 @@ def get_public_keys(self):
695695
if isinstance(raw_ssh_keys, list):
696696
return raw_ssh_keys
697697

698-
return [raw_ssh_keys[key].get('openssh-key') for key in raw_ssh_keys]
698+
keys = []
699+
for value in raw_ssh_keys.values():
700+
if isinstance(value, str):
701+
keys.append(value)
702+
else:
703+
keys.append(value.get('openssh-key'))
704+
return keys
699705

700706
def get_network_details(self):
701707
debian_net_config = self._get_meta_data().get('network-interfaces')

cloudbaseinit/tests/metadata/services/test_nocloudservice.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,19 @@ def test_get_public_keys_alt_fmt(self, mock_get_metadata):
516516
result = self._config_drive.get_public_keys()
517517
self.assertEqual(result, expected_result)
518518

519+
@mock.patch(MODULE_PATH + '.NoCloudConfigDriveService._get_meta_data')
520+
def test_get_public_keys_dict_of_strings(self, mock_get_metadata):
521+
fake_key0 = 'ssh-rsa AAAA0 user0@host'
522+
fake_key1 = 'ssh-rsa AAAA1 user1@host'
523+
mock_get_metadata.return_value = {
524+
'public-keys': {
525+
'key0': fake_key0,
526+
'key1': fake_key1,
527+
}
528+
}
529+
result = sorted(self._config_drive.get_public_keys())
530+
self.assertEqual(result, sorted([fake_key0, fake_key1]))
531+
519532
@ddt.data(('', ('V2 network metadata is empty', None)),
520533
('1', ('V2 network metadata is not a dictionary', None)),
521534
('{}', ('V2 network metadata is empty', None)),

0 commit comments

Comments
 (0)