From c2660558e862640c780e025d8c340eee45ce12cc Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Mon, 14 Mar 2022 17:54:13 -0600 Subject: [PATCH 1/9] Make package ssh-import-id "suggested" by cloud-init --- packages/debian/control.in | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/debian/control.in b/packages/debian/control.in index 72895b47af1..7cded051134 100644 --- a/packages/debian/control.in +++ b/packages/debian/control.in @@ -14,6 +14,7 @@ Depends: ${misc:Depends}, iproute2, isc-dhcp-client Recommends: eatmydata, sudo, software-properties-common, gdisk +Suggests: ssh-import-id Description: Init scripts for cloud instances Cloud instances need special scripts to run during initialisation to retrieve and install ssh keys and to let the user run various scripts. From 04abd5dd6976fcc64fd8486875e9eae785c063c5 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Thu, 14 Apr 2022 11:21:58 -0600 Subject: [PATCH 2/9] warn and exit if ssh-import-id not available --- cloudinit/config/cc_ssh_import_id.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index e5864878387..eac17a9e4da 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -18,6 +18,7 @@ # https://launchpad.net/ssh-import-id distros = ["ubuntu", "debian"] +SSH_IMPORT_ID = "ssh-import-id" MODULE_DESCRIPTION = """\ This module imports SSH keys from either a public keyserver, usually launchpad or github using ``ssh-import-id``. Keys are referenced by the username they are @@ -49,6 +50,13 @@ def handle(_name, cfg, cloud, log, args): + if cfg.get("ssh_import_id") and subp.which(SSH_IMPORT_ID): + log.warn( + "ssh-import-id is not installed, but module ssh_import_id is " + "configured. Skipping module." + ) + return + # import for "user: XXXXX" if len(args) != 0: user = args[0] @@ -138,7 +146,7 @@ def import_ssh_ids(ids, user, log): "--preserve-env=https_proxy", "-Hu", user, - "ssh-import-id", + SSH_IMPORT_ID, ] + ids log.debug("Importing SSH ids for user %s.", user) From e935bb79b1007676790e51c8b74cd434ae0adb39 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Thu, 14 Apr 2022 14:26:55 -0600 Subject: [PATCH 3/9] skip if bin _is not_ found --- cloudinit/config/cc_ssh_import_id.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index eac17a9e4da..a5be4eb363f 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -50,7 +50,7 @@ def handle(_name, cfg, cloud, log, args): - if cfg.get("ssh_import_id") and subp.which(SSH_IMPORT_ID): + if cfg.get("ssh_import_id") and not subp.which(SSH_IMPORT_ID): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." From 896e6d05055a8a2cebeed4e253eb34683e71960e Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Fri, 15 Apr 2022 13:38:38 -0600 Subject: [PATCH 4/9] s/SSH_IMPORT_ID/SSH_IMPORT_ID_BINARY/ --- cloudinit/config/cc_ssh_import_id.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index a5be4eb363f..49b56c5c127 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -18,7 +18,7 @@ # https://launchpad.net/ssh-import-id distros = ["ubuntu", "debian"] -SSH_IMPORT_ID = "ssh-import-id" +SSH_IMPORT_ID_BINARY = "ssh-import-id" MODULE_DESCRIPTION = """\ This module imports SSH keys from either a public keyserver, usually launchpad or github using ``ssh-import-id``. Keys are referenced by the username they are @@ -50,7 +50,7 @@ def handle(_name, cfg, cloud, log, args): - if cfg.get("ssh_import_id") and not subp.which(SSH_IMPORT_ID): + if cfg.get("ssh_import_id") and not subp.which(SSH_IMPORT_ID_BINARY): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." @@ -146,7 +146,7 @@ def import_ssh_ids(ids, user, log): "--preserve-env=https_proxy", "-Hu", user, - SSH_IMPORT_ID, + SSH_IMPORT_ID_BINARY, ] + ids log.debug("Importing SSH ids for user %s.", user) From 1dd6da3b1365c0e4879f9f4e0c09d63cf6cad452 Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Fri, 15 Apr 2022 16:16:16 -0600 Subject: [PATCH 5/9] don't check for ssh_import_id key --- cloudinit/config/cc_ssh_import_id.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index 49b56c5c127..672d91a043f 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -50,7 +50,7 @@ def handle(_name, cfg, cloud, log, args): - if cfg.get("ssh_import_id") and not subp.which(SSH_IMPORT_ID_BINARY): + if not subp.which(SSH_IMPORT_ID_BINARY): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." From bec04bfa23ec86ab5de6a0e9f957a86d6a0adaad Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Mon, 18 Apr 2022 09:41:32 -0600 Subject: [PATCH 6/9] find embedded keys --- cloudinit/config/cc_ssh_import_id.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index 672d91a043f..f93854d52dc 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -50,7 +50,7 @@ def handle(_name, cfg, cloud, log, args): - if not subp.which(SSH_IMPORT_ID_BINARY): + if is_key_in_nested_dict(cfg, "ssh_import_id") and not subp.which(SSH_IMPORT_ID_BINARY): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." @@ -157,4 +157,21 @@ def import_ssh_ids(ids, user, log): raise exc -# vi: ts=4 expandtab +def is_key_in_nested_dict(config: dict, search_key: str) -> bool: + """Search for key nested in config. + + Note: A dict embedded in a list of lists will not be found walked - but in + this case we don't need it. + """ + for config_key in config.keys(): + if search_key == config_key: + return True + if isinstance(config[config_key], dict): + return is_key_in_nested_dict(config[config_key], search_key) + if isinstance(config[config_key], list): + # this code could probably be generalized to walking the whole + # config by iterating lists in search of dictionaries + for item in config[config_key]: + if isinstance(item, dict): + return is_key_in_nested_dict(item, search_key) + return False From 13058fc05dc1b6bdd9cfbd5053fc59965371a5db Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Tue, 19 Apr 2022 08:20:51 -0600 Subject: [PATCH 7/9] fmt --- cloudinit/config/cc_ssh_import_id.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index f93854d52dc..715d6bc91e5 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -50,7 +50,9 @@ def handle(_name, cfg, cloud, log, args): - if is_key_in_nested_dict(cfg, "ssh_import_id") and not subp.which(SSH_IMPORT_ID_BINARY): + if is_key_in_nested_dict(cfg, "ssh_import_id") and not subp.which( + SSH_IMPORT_ID_BINARY + ): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." From b8e30d6ff193ddd626c8ccb846c91a4a2105f3df Mon Sep 17 00:00:00 2001 From: Brett Holman Date: Tue, 19 Apr 2022 13:57:02 -0600 Subject: [PATCH 8/9] early exit based on key presence, suggested by @blackboxsw Co-authored-by: ubuntu-server-builder --- cloudinit/config/cc_ssh_import_id.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index 715d6bc91e5..143abba74a4 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -50,9 +50,10 @@ def handle(_name, cfg, cloud, log, args): - if is_key_in_nested_dict(cfg, "ssh_import_id") and not subp.which( - SSH_IMPORT_ID_BINARY - ): + if not is_key_in_nested_dict(cfg, "ssh_import_id"): + log.debug("Skipping module named ssh-import-id, no 'ssh_import_id' directives found.") + return + elif not subp.which(SSH_IMPORT_ID_BINARY): log.warn( "ssh-import-id is not installed, but module ssh_import_id is " "configured. Skipping module." From b7461e4d5162c9e86e65f4d31867f1a780d71416 Mon Sep 17 00:00:00 2001 From: Chad Smith Date: Tue, 19 Apr 2022 15:38:32 -0600 Subject: [PATCH 9/9] flake --- cloudinit/config/cc_ssh_import_id.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cloudinit/config/cc_ssh_import_id.py b/cloudinit/config/cc_ssh_import_id.py index 143abba74a4..b6bca84179b 100755 --- a/cloudinit/config/cc_ssh_import_id.py +++ b/cloudinit/config/cc_ssh_import_id.py @@ -51,7 +51,10 @@ def handle(_name, cfg, cloud, log, args): if not is_key_in_nested_dict(cfg, "ssh_import_id"): - log.debug("Skipping module named ssh-import-id, no 'ssh_import_id' directives found.") + log.debug( + "Skipping module named ssh-import-id, no 'ssh_import_id'" + " directives found." + ) return elif not subp.which(SSH_IMPORT_ID_BINARY): log.warn(