summaryrefslogtreecommitdiff
path: root/cloudinit/sources/DataSourceGCE.py
diff options
context:
space:
mode:
authorRick Wright <rickw@google.com>2019-08-09 17:11:05 +0000
committerServer Team CI Bot <josh.powers+server-team-bot@canonical.com>2019-08-09 17:11:05 +0000
commit155847209e6a3ed5face91a133d8488a703f3f93 (patch)
tree7736a89809a0368b974f8c8afd20a034df6e5145 /cloudinit/sources/DataSourceGCE.py
parent4dfed67d0e82970f8717d0b524c593962698ca4f (diff)
downloadvyos-cloud-init-155847209e6a3ed5face91a133d8488a703f3f93.tar.gz
vyos-cloud-init-155847209e6a3ed5face91a133d8488a703f3f93.zip
Add support for publishing host keys to GCE guest attributes
This adds an empty publish_host_keys() method to the default datasource that is called by cc_ssh.py. This feature can be controlled by the 'ssh_publish_hostkeys' config option. It is enabled by default but can be disabled by setting 'enabled' to false. Also, a blacklist of key types is supported. In addition, this change implements ssh_publish_hostkeys() for the GCE datasource, attempting to write the hostkeys to the instance's guest attributes. Using these hostkeys for ssh connections is currently supported by the alpha version of Google's 'gcloud' command-line tool. (On Google Compute Engine, this feature will be enabled by setting the 'enable-guest-attributes' metadata key to 'true' for the project/instance that you would like to use this feature for. When connecting to the instance for the first time using 'gcloud compute ssh' the hostkeys will be read from the guest attributes for the instance and written to the user's local known_hosts file for Google Compute Engine instances.)
Diffstat (limited to 'cloudinit/sources/DataSourceGCE.py')
-rw-r--r--cloudinit/sources/DataSourceGCE.py22
1 files changed, 20 insertions, 2 deletions
diff --git a/cloudinit/sources/DataSourceGCE.py b/cloudinit/sources/DataSourceGCE.py
index d8162623..6cbfbbac 100644
--- a/cloudinit/sources/DataSourceGCE.py
+++ b/cloudinit/sources/DataSourceGCE.py
@@ -18,10 +18,13 @@ LOG = logging.getLogger(__name__)
MD_V1_URL = 'http://metadata.google.internal/computeMetadata/v1/'
BUILTIN_DS_CONFIG = {'metadata_url': MD_V1_URL}
REQUIRED_FIELDS = ('instance-id', 'availability-zone', 'local-hostname')
+GUEST_ATTRIBUTES_URL = ('http://metadata.google.internal/computeMetadata/'
+ 'v1/instance/guest-attributes')
+HOSTKEY_NAMESPACE = 'hostkeys'
+HEADERS = {'Metadata-Flavor': 'Google'}
class GoogleMetadataFetcher(object):
- headers = {'Metadata-Flavor': 'Google'}
def __init__(self, metadata_address):
self.metadata_address = metadata_address
@@ -32,7 +35,7 @@ class GoogleMetadataFetcher(object):
url = self.metadata_address + path
if is_recursive:
url += '/?recursive=True'
- resp = url_helper.readurl(url=url, headers=self.headers)
+ resp = url_helper.readurl(url=url, headers=HEADERS)
except url_helper.UrlError as exc:
msg = "url %s raised exception %s"
LOG.debug(msg, path, exc)
@@ -90,6 +93,10 @@ class DataSourceGCE(sources.DataSource):
public_keys_data = self.metadata['public-keys-data']
return _parse_public_keys(public_keys_data, self.default_user)
+ def publish_host_keys(self, hostkeys):
+ for key in hostkeys:
+ _write_host_key_to_guest_attributes(*key)
+
def get_hostname(self, fqdn=False, resolve_ip=False, metadata_only=False):
# GCE has long FDQN's and has asked for short hostnames.
return self.metadata['local-hostname'].split('.')[0]
@@ -103,6 +110,17 @@ class DataSourceGCE(sources.DataSource):
return self.availability_zone.rsplit('-', 1)[0]
+def _write_host_key_to_guest_attributes(key_type, key_value):
+ url = '%s/%s/%s' % (GUEST_ATTRIBUTES_URL, HOSTKEY_NAMESPACE, key_type)
+ key_value = key_value.encode('utf-8')
+ resp = url_helper.readurl(url=url, data=key_value, headers=HEADERS,
+ request_method='PUT', check_status=False)
+ if resp.ok():
+ LOG.debug('Wrote %s host key to guest attributes.', key_type)
+ else:
+ LOG.debug('Unable to write %s host key to guest attributes.', key_type)
+
+
def _has_expired(public_key):
# Check whether an SSH key is expired. Public key input is a single SSH
# public key in the GCE specific key format documented here: