Fix improper EOL handling between the public keys
Every metadata service should return public keys as lists of space-stripped strings without counting on the existence of the current present (or not) new lines. The sshpublickeys plugin will explicitly add EOLs between the keys, therefore having a valid authorized_keys file when multiple ssh keys are retrieved. Change-Id: Idad2b9d469a544066ab4090c30dd3f274e36844e
This commit is contained in:
parent
30bab776b2
commit
a2d07e1478
@ -110,6 +110,7 @@ class BaseMetadataService(object):
|
||||
pass
|
||||
|
||||
def get_public_keys(self):
|
||||
"""Get a list of space-stripped strings as public keys."""
|
||||
pass
|
||||
|
||||
def get_network_details(self):
|
||||
|
@ -65,7 +65,7 @@ class BaseOpenStackService(base.BaseMetadataService):
|
||||
"""Get a list of all unique public keys found among the metadata."""
|
||||
public_keys = []
|
||||
meta_data = self._get_meta_data()
|
||||
public_keys_dict = meta_data.get('public_keys')
|
||||
public_keys_dict = meta_data.get("public_keys")
|
||||
if public_keys_dict:
|
||||
public_keys = list(public_keys_dict.values())
|
||||
keys = meta_data.get("keys")
|
||||
@ -73,7 +73,7 @@ class BaseOpenStackService(base.BaseMetadataService):
|
||||
for key_dict in keys:
|
||||
if key_dict["type"] == "ssh":
|
||||
public_keys.append(key_dict["data"])
|
||||
return list(set(public_keys))
|
||||
return list(set((key.strip() for key in public_keys)))
|
||||
|
||||
def get_network_details(self):
|
||||
network_config = self._get_meta_data().get('network_config')
|
||||
|
@ -97,6 +97,6 @@ class EC2Service(base.BaseMetadataService):
|
||||
ssh_key = self._get_cache_data(
|
||||
'%(version)s/meta-data/public-keys/%(idx)s/openssh-key' %
|
||||
{'version': self._metadata_version, 'idx': idx})
|
||||
ssh_keys.append(ssh_key)
|
||||
ssh_keys.append(ssh_key.strip())
|
||||
|
||||
return ssh_keys
|
||||
|
@ -118,9 +118,8 @@ class MaaSHttpService(base.BaseMetadataService):
|
||||
return [v + delimiter for v in text.split(delimiter)]
|
||||
|
||||
def get_public_keys(self):
|
||||
return self._get_list_from_text(
|
||||
self._get_cache_data('%s/meta-data/public-keys' %
|
||||
self._metadata_version), "\n")
|
||||
return self._get_cache_data('%s/meta-data/public-keys' %
|
||||
self._metadata_version).splitlines()
|
||||
|
||||
def get_client_auth_certs(self):
|
||||
return self._get_list_from_text(
|
||||
|
@ -195,7 +195,7 @@ class OpenNebulaService(base.BaseMetadataService):
|
||||
return self._get_cache_data(USER_DATA)
|
||||
|
||||
def get_public_keys(self):
|
||||
return [self._get_cache_data(PUBLIC_KEY)]
|
||||
return self._get_cache_data(PUBLIC_KEY).splitlines()
|
||||
|
||||
def get_network_details(self):
|
||||
"""Return a list of NetworkDetails objects.
|
||||
|
@ -52,6 +52,7 @@ class SetUserSSHPublicKeysPlugin(base.BasePlugin):
|
||||
LOG.info("Writing SSH public keys in: %s" % authorized_keys_path)
|
||||
with open(authorized_keys_path, 'w') as f:
|
||||
for public_key in public_keys:
|
||||
f.write(public_key)
|
||||
# All public keys are space-stripped.
|
||||
f.write(public_key + "\n")
|
||||
|
||||
return (base.PLUGIN_EXECUTION_DONE, False)
|
||||
|
@ -101,13 +101,18 @@ class TestBaseOpenStackService(unittest.TestCase):
|
||||
mock_get_meta_data.return_value.get.side_effect = \
|
||||
[self._fake_public_keys, self._fake_keys]
|
||||
response = self._service.get_public_keys()
|
||||
|
||||
mock_get_meta_data.assert_called_once_with()
|
||||
mock_get_meta_data.return_value.get.assert_any_call("public_keys")
|
||||
mock_get_meta_data.return_value.get.assert_any_call("keys")
|
||||
values = (list(self._fake_public_keys.values()) +
|
||||
[key["data"] for key in self._fake_keys
|
||||
if key["type"] == "ssh"])
|
||||
self.assertEqual(sorted(list(set(values))), sorted(response))
|
||||
|
||||
public_keys = (list(self._fake_public_keys.values()) +
|
||||
[key["data"] for key in self._fake_keys
|
||||
if key["type"] == "ssh"])
|
||||
public_keys = [key.strip() for key in public_keys]
|
||||
|
||||
self.assertEqual(sorted(list(set(public_keys))),
|
||||
sorted(response))
|
||||
|
||||
@mock.patch(MODPATH +
|
||||
".BaseOpenStackService._get_meta_data")
|
||||
|
@ -113,7 +113,7 @@ class EC2ServiceTest(unittest.TestCase):
|
||||
@mock.patch('cloudbaseinit.metadata.services.ec2service.EC2Service'
|
||||
'._get_cache_data')
|
||||
def test_get_public_keys(self, mock_get_cache_data):
|
||||
mock_get_cache_data.side_effect = ['key=info', 'fake key']
|
||||
mock_get_cache_data.side_effect = ['key=info', 'fake key\n']
|
||||
response = self._service.get_public_keys()
|
||||
expected = [
|
||||
mock.call('%s/meta-data/public-keys' %
|
||||
|
@ -163,18 +163,19 @@ class MaaSHttpServiceTest(unittest.TestCase):
|
||||
response = self._maasservice._get_list_from_text('fake:text', ':')
|
||||
self.assertEqual(['fake:', 'text:'], response)
|
||||
|
||||
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
|
||||
"._get_list_from_text")
|
||||
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
|
||||
"._get_cache_data")
|
||||
def test_get_public_keys(self, mock_get_cache_data,
|
||||
mock_get_list_from_text):
|
||||
def test_get_public_keys(self, mock_get_cache_data):
|
||||
public_keys = [
|
||||
"fake key 1",
|
||||
"fake key 2"
|
||||
]
|
||||
public_key = "\n".join(public_keys) + "\n"
|
||||
mock_get_cache_data.return_value = public_key
|
||||
response = self._maasservice.get_public_keys()
|
||||
mock_get_cache_data.assert_called_with(
|
||||
'%s/meta-data/public-keys' % self._maasservice._metadata_version)
|
||||
mock_get_list_from_text.assert_called_once_with(mock_get_cache_data(),
|
||||
"\n")
|
||||
self.assertEqual(mock_get_list_from_text.return_value, response)
|
||||
self.assertEqual(public_keys, response)
|
||||
|
||||
@mock.patch("cloudbaseinit.metadata.services.maasservice.MaaSHttpService"
|
||||
"._get_list_from_text")
|
||||
|
Loading…
Reference in New Issue
Block a user