summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreb3095 <45504889+eb3095@users.noreply.github.com>2021-12-01 13:35:28 -0500
committerGitHub <noreply@github.com>2021-12-01 12:35:28 -0600
commita1cf55e5e6331b9b3a4f9ceb412dd14c78abb5ea (patch)
treef9aa09f129138393139c4b9be6f2602c680cf773
parentc39d4f455d6663948c06c1f8186ab69b24ea0013 (diff)
downloadvyos-cloud-init-a1cf55e5e6331b9b3a4f9ceb412dd14c78abb5ea.tar.gz
vyos-cloud-init-a1cf55e5e6331b9b3a4f9ceb412dd14c78abb5ea.zip
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.
-rw-r--r--cloudinit/sources/helpers/vultr.py52
1 files changed, 52 insertions, 0 deletions
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 {