summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2012-11-12 12:26:49 -0500
committerScott Moser <smoser@ubuntu.com>2012-11-12 12:26:49 -0500
commit7ba753720cd95bfca61c82445cf9c7882fe5d6f1 (patch)
tree1a39ce4eaa65be910c10b0155f5d4c463e6a4027
parent8730e143ec07372107d794abe9f4857ead6d4718 (diff)
downloadvyos-cloud-init-7ba753720cd95bfca61c82445cf9c7882fe5d6f1.tar.gz
vyos-cloud-init-7ba753720cd95bfca61c82445cf9c7882fe5d6f1.zip
config-drive-v2: support public keys
This does a couple things: * separates out the 'normalize_public_keys' from the DataSource's get_public_ssh_keys * uses that from config-drive datasource * supports config drive v1 or v2 public-keys * adds a test. LP: #1077700
-rw-r--r--ChangeLog1
-rw-r--r--cloudinit/sources/DataSourceConfigDrive.py7
-rw-r--r--cloudinit/sources/__init__.py56
-rw-r--r--tests/unittests/test_datasource/test_configdrive.py26
4 files changed, 61 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index de1bcbff..a68e196e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,7 @@
- work around the lazy loading of get_instance_metadata in boto >= 2.6.0
by fully walking the dictionary. (LP: #1068801)
Added dependency on distribute's python-pkg-resources
+ - fix public key importing with config-drive-v2 datasource (LP: #1077700)
0.7.0:
- add a 'exception_cb' argument to 'wait_for_url'. If provided, this
method will be called back with the exception received and the message.
diff --git a/cloudinit/sources/DataSourceConfigDrive.py b/cloudinit/sources/DataSourceConfigDrive.py
index 9729cfb9..c7826851 100644
--- a/cloudinit/sources/DataSourceConfigDrive.py
+++ b/cloudinit/sources/DataSourceConfigDrive.py
@@ -219,9 +219,10 @@ class DataSourceConfigDrive(sources.DataSource):
return True
def get_public_ssh_keys(self):
- if not 'public-keys' in self.metadata:
- return []
- return self.metadata['public-keys']
+ name = "public_keys"
+ if self.version == 1:
+ name = "public-keys"
+ return sources.normalize_pubkey_data(self.metadata.get(name))
class DataSourceConfigDriveNet(DataSourceConfigDrive):
diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py
index 745627d0..96baff90 100644
--- a/cloudinit/sources/__init__.py
+++ b/cloudinit/sources/__init__.py
@@ -100,32 +100,7 @@ class DataSource(object):
return {}
def get_public_ssh_keys(self):
- keys = []
-
- if not self.metadata or 'public-keys' not in self.metadata:
- return keys
-
- if isinstance(self.metadata['public-keys'], (basestring, str)):
- return str(self.metadata['public-keys']).splitlines()
-
- if isinstance(self.metadata['public-keys'], (list, set)):
- return list(self.metadata['public-keys'])
-
- if isinstance(self.metadata['public-keys'], (dict)):
- for (_keyname, klist) in self.metadata['public-keys'].iteritems():
- # lp:506332 uec metadata service responds with
- # data that makes boto populate a string for 'klist' rather
- # than a list.
- if isinstance(klist, (str, basestring)):
- klist = [klist]
- if isinstance(klist, (list, set)):
- for pkey in klist:
- # There is an empty string at
- # the end of the keylist, trim it
- if pkey:
- keys.append(pkey)
-
- return keys
+ return normalize_pubkey_data(self.metadata.get('public-keys'))
def _remap_device(self, short_name):
# LP: #611137
@@ -208,6 +183,35 @@ class DataSource(object):
availability_zone=self.availability_zone)
+def normalize_pubkey_data(pubkey_data):
+ keys = []
+
+ if not pubkey_data:
+ return keys
+
+ if isinstance(pubkey_data, (basestring, str)):
+ return str(pubkey_data).splitlines()
+
+ if isinstance(pubkey_data, (list, set)):
+ return list(pubkey_data)
+
+ if isinstance(pubkey_data, (dict)):
+ for (_keyname, klist) in pubkey_data.iteritems():
+ # lp:506332 uec metadata service responds with
+ # data that makes boto populate a string for 'klist' rather
+ # than a list.
+ if isinstance(klist, (str, basestring)):
+ klist = [klist]
+ if isinstance(klist, (list, set)):
+ for pkey in klist:
+ # There is an empty string at
+ # the end of the keylist, trim it
+ if pkey:
+ keys.append(pkey)
+
+ return keys
+
+
def find_source(sys_cfg, distro, paths, ds_deps, cfg_list, pkg_list):
ds_list = list_sources(cfg_list, ds_deps, pkg_list)
ds_names = [util.obj_name(f) for f in ds_list]
diff --git a/tests/unittests/test_datasource/test_configdrive.py b/tests/unittests/test_datasource/test_configdrive.py
index 00379e03..aa5b98ed 100644
--- a/tests/unittests/test_datasource/test_configdrive.py
+++ b/tests/unittests/test_datasource/test_configdrive.py
@@ -288,6 +288,32 @@ class TestConfigDriveDataSource(MockerTestCase):
finally:
util.find_devs_with = orig_find_devs_with
+ def test_pubkeys_v2(self):
+ """Verify that public-keys work in config-drive-v2."""
+ populate_dir(self.tmp, CFG_DRIVE_FILES_V2)
+ myds = cfg_ds_from_dir(self.tmp)
+ self.assertEqual(myds.get_public_ssh_keys(),
+ [OSTACK_META['public_keys']['mykey']])
+
+
+def cfg_ds_from_dir(seed_d):
+ found = ds.read_config_drive_dir(seed_d)
+ cfg_ds = ds.DataSourceConfigDrive(settings.CFG_BUILTIN, None,
+ helpers.Paths({}))
+ populate_ds_from_read_config(cfg_ds, seed_d, found)
+ return cfg_ds
+
+
+def populate_ds_from_read_config(cfg_ds, source, results):
+ """Patch the DataSourceConfigDrive from the results of
+ read_config_drive_dir hopefully in line with what it would have
+ if cfg_ds.get_data had been successfully called"""
+ cfg_ds.source = source
+ cfg_ds.metadata = results.get('metadata')
+ cfg_ds.ec2_metadata = results.get('ec2-metadata')
+ cfg_ds.userdata_raw = results.get('userdata')
+ cfg_ds.version = results.get('cfgdrive_ver')
+
def populate_dir(seed_dir, files):
for (name, content) in files.iteritems():