From aa8b51a48a30e3a3c863ca0ddb8bc4667026d57a Mon Sep 17 00:00:00 2001 From: harlowja Date: Sat, 27 Oct 2012 19:25:48 -0700 Subject: Helpful cleanups. 1. Remove the usage of the path.join function now that all code should be going through the util file methods (and they can be mocked out as needed). 2. Adjust all occurences of the above join function to either not use it or replace it with the standard os.path.join (which can also be mocked out as needed) 3. Fix pylint from complaining about the tests folder 'helpers.py' not being found 4. Add a pylintrc file that is used instead of the options hidden in the 'run_pylint' tool. --- cloudinit/sources/__init__.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'cloudinit/sources/__init__.py') diff --git a/cloudinit/sources/__init__.py b/cloudinit/sources/__init__.py index b22369a8..745627d0 100644 --- a/cloudinit/sources/__init__.py +++ b/cloudinit/sources/__init__.py @@ -20,8 +20,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from email.mime.multipart import MIMEMultipart - import abc import os -- cgit v1.2.3 From 7ba753720cd95bfca61c82445cf9c7882fe5d6f1 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Mon, 12 Nov 2012 12:26:49 -0500 Subject: 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 --- ChangeLog | 1 + cloudinit/sources/DataSourceConfigDrive.py | 7 +-- cloudinit/sources/__init__.py | 56 ++++++++++++---------- .../unittests/test_datasource/test_configdrive.py | 26 ++++++++++ 4 files changed, 61 insertions(+), 29 deletions(-) (limited to 'cloudinit/sources/__init__.py') 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(): -- cgit v1.2.3