From a1cf55e5e6331b9b3a4f9ceb412dd14c78abb5ea Mon Sep 17 00:00:00 2001 From: eb3095 <45504889+eb3095@users.noreply.github.com> Date: Wed, 1 Dec 2021 13:35:28 -0500 Subject: Fix missing metadata routes for vultr (#1125) Vultr uses 169.254.169.254 for the metadata server. Some distros are having trouble with this on IPv6 only servers because the route is not being assigned to the link-local interface by default as it is in other distros. This change sets that route before attempting to fetch the metadata avoiding the current issue. --- cloudinit/sources/helpers/vultr.py | 52 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'cloudinit/sources/helpers') diff --git a/cloudinit/sources/helpers/vultr.py b/cloudinit/sources/helpers/vultr.py index 55487ac3..ad347bea 100644 --- a/cloudinit/sources/helpers/vultr.py +++ b/cloudinit/sources/helpers/vultr.py @@ -9,6 +9,8 @@ from cloudinit import url_helper from cloudinit import dmi from cloudinit import util from cloudinit import net +from cloudinit import netinfo +from cloudinit import subp from cloudinit.net.dhcp import EphemeralDHCPv4, NoDHCPLeaseError from functools import lru_cache @@ -21,6 +23,9 @@ def get_metadata(url, timeout, retries, sec_between, agent): # Bring up interface try: with EphemeralDHCPv4(connectivity_url_data={"url": url}): + # Set metadata route + set_route() + # Fetch the metadata v1 = read_metadata(url, timeout, retries, sec_between, agent) except (NoDHCPLeaseError) as exc: @@ -30,6 +35,53 @@ def get_metadata(url, timeout, retries, sec_between, agent): return json.loads(v1) +# Set route for metadata +def set_route(): + # Get routes, confirm entry does not exist + routes = netinfo.route_info() + + # If no tools exist and empty dict is returned + if 'ipv4' not in routes: + return + + # We only care about IPv4 + routes = routes['ipv4'] + + # Searchable list + dests = [] + + # Parse each route into a more searchable format + for route in routes: + dests.append(route['destination']) + + gw_present = '100.64.0.0' in dests or '100.64.0.0/10' in dests + dest_present = '169.254.169.254' in dests + + # If not IPv6 only (No link local) + # or the route is already present + if not gw_present or dest_present: + return + + # Set metadata route + if subp.which('ip'): + subp.subp([ + 'ip', + 'route', + 'add', + '169.254.169.254/32', + 'dev', + net.find_fallback_nic() + ]) + elif subp.which('route'): + subp.subp([ + 'route', + 'add', + '-net', + '169.254.169.254/32', + '100.64.0.1' + ]) + + # Read the system information from SMBIOS def get_sysinfo(): return { -- cgit v1.2.3