diff options
author | Markus Schade <markus.schade@hetzner.com> | 2020-10-29 15:45:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-29 10:45:47 -0400 |
commit | 1431c8a1bddaabf85e1bbb32bf316a3aef20036e (patch) | |
tree | 098c9b77663c134c114795c0c94b48b5aab0abe7 /cloudinit/sources | |
parent | b46e4a8cff667c8441622089cf7d57aeb88220cd (diff) | |
download | vyos-cloud-init-1431c8a1bddaabf85e1bbb32bf316a3aef20036e.tar.gz vyos-cloud-init-1431c8a1bddaabf85e1bbb32bf316a3aef20036e.zip |
Hetzner: initialize instance_id from system-serial-number (#630)
Hetzner Cloud also provides the instance ID in SMBIOS information. Use
it to locally check_instance_id and to compared with instance_id from
metadata service.
LP: #1885527
Diffstat (limited to 'cloudinit/sources')
-rw-r--r-- | cloudinit/sources/DataSourceHetzner.py | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/cloudinit/sources/DataSourceHetzner.py b/cloudinit/sources/DataSourceHetzner.py index 79353882..1d965bf7 100644 --- a/cloudinit/sources/DataSourceHetzner.py +++ b/cloudinit/sources/DataSourceHetzner.py @@ -3,15 +3,18 @@ # # This file is part of cloud-init. See LICENSE file for license information. # -"""Hetzner Cloud API Documentation. +"""Hetzner Cloud API Documentation https://docs.hetzner.cloud/""" +from cloudinit import log as logging from cloudinit import net as cloudnet from cloudinit import sources from cloudinit import util import cloudinit.sources.helpers.hetzner as hc_helper +LOG = logging.getLogger(__name__) + BASE_URL_V1 = 'http://169.254.169.254/hetzner/v1' BUILTIN_DS_CONFIG = { @@ -43,9 +46,12 @@ class DataSourceHetzner(sources.DataSource): self._network_config = None self.dsmode = sources.DSMODE_NETWORK - def get_data(self): - if not on_hetzner(): + def _get_data(self): + (on_hetzner, serial) = get_hcloud_data() + + if not on_hetzner: return False + nic = cloudnet.find_fallback_nic() with cloudnet.EphemeralIPv4Network(nic, "169.254.0.1", 16, "169.254.255.255"): @@ -75,8 +81,18 @@ class DataSourceHetzner(sources.DataSource): self.metadata['public-keys'] = md.get('public-keys', None) self.vendordata_raw = md.get("vendor_data", None) + # instance-id and serial from SMBIOS should be identical + if self.metadata['instance-id'] != serial: + raise RuntimeError( + "SMBIOS serial does not match instance ID from metadata" + ) + return True + def check_instance_id(self, sys_cfg): + return sources.instance_id_matches_system_uuid( + self.get_instance_id(), 'system-serial-number') + @property def network_config(self): """Configure the networking. This needs to be done each boot, since @@ -96,8 +112,18 @@ class DataSourceHetzner(sources.DataSource): return self._network_config -def on_hetzner(): - return util.read_dmi_data('system-manufacturer') == "Hetzner" +def get_hcloud_data(): + vendor_name = util.read_dmi_data('system-manufacturer') + if vendor_name != "Hetzner": + return (False, None) + + serial = util.read_dmi_data("system-serial-number") + if serial: + LOG.debug("Running on Hetzner Cloud: serial=%s", serial) + else: + raise RuntimeError("Hetzner Cloud detected, but no serial found") + + return (True, serial) # Used to match classes to dependencies |