summaryrefslogtreecommitdiff
path: root/cloudinit/net/dhcp.py
diff options
context:
space:
mode:
authorDimitri John Ledkov <xnox@ubuntu.com>2017-09-30 00:00:18 -0400
committerScott Moser <smoser@brickies.net>2017-10-03 08:59:43 -0400
commit9d2a87dc386b7aed1a8243d599676e78ed358749 (patch)
tree9d24ff110b5a08d6cdaf6e37023feb9abe7a9ec9 /cloudinit/net/dhcp.py
parent946232bb9eda2f4bc66c4464db9e72d3edfd9900 (diff)
downloadvyos-cloud-init-9d2a87dc386b7aed1a8243d599676e78ed358749.tar.gz
vyos-cloud-init-9d2a87dc386b7aed1a8243d599676e78ed358749.zip
Azure, CloudStack: Support reading dhcp options from systemd-networkd.
Systems that used systemd-networkd's dhcp client would not be able to get information on the Azure endpoint (placed in Option 245) or the CloudStack server (in 'server_address'). The change here supports reading these files in /run/systemd/netif/leases. The files declare that "This is private data. Do not parse.", but at this point we do not have another option. LP: #1718029
Diffstat (limited to 'cloudinit/net/dhcp.py')
-rw-r--r--cloudinit/net/dhcp.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/cloudinit/net/dhcp.py b/cloudinit/net/dhcp.py
index 05350639..0cba7032 100644
--- a/cloudinit/net/dhcp.py
+++ b/cloudinit/net/dhcp.py
@@ -4,6 +4,7 @@
#
# This file is part of cloud-init. See LICENSE file for license information.
+import configobj
import logging
import os
import re
@@ -11,9 +12,12 @@ import re
from cloudinit.net import find_fallback_nic, get_devicelist
from cloudinit import temp_utils
from cloudinit import util
+from six import StringIO
LOG = logging.getLogger(__name__)
+NETWORKD_LEASES_DIR = '/run/systemd/netif/leases'
+
class InvalidDHCPLeaseFileError(Exception):
"""Raised when parsing an empty or invalid dhcp.leases file.
@@ -118,4 +122,42 @@ def dhcp_discovery(dhclient_cmd_path, interface, cleandir):
return parse_dhcp_lease_file(lease_file)
+def networkd_parse_lease(content):
+ """Parse a systemd lease file content as in /run/systemd/netif/leases/
+
+ Parse this (almost) ini style file even though it says:
+ # This is private data. Do not parse.
+
+ Simply return a dictionary of key/values."""
+
+ return dict(configobj.ConfigObj(StringIO(content), list_values=False))
+
+
+def networkd_load_leases(leases_d=None):
+ """Return a dictionary of dictionaries representing each lease
+ found in lease_d.i
+
+ The top level key will be the filename, which is typically the ifindex."""
+
+ if leases_d is None:
+ leases_d = NETWORKD_LEASES_DIR
+
+ ret = {}
+ if not os.path.isdir(leases_d):
+ return ret
+ for lfile in os.listdir(leases_d):
+ ret[lfile] = networkd_parse_lease(
+ util.load_file(os.path.join(leases_d, lfile)))
+ return ret
+
+
+def networkd_get_option_from_leases(keyname, leases_d=None):
+ if leases_d is None:
+ leases_d = NETWORKD_LEASES_DIR
+ leases = networkd_load_leases(leases_d=leases_d)
+ for ifindex, data in sorted(leases.items()):
+ if data.get(keyname):
+ return data[keyname]
+ return None
+
# vi: ts=4 expandtab