blob: c5d799824bd07f655fa9596dadd77fcd78a497f5 [file] [log] [blame]
akutz77457a62018-08-22 16:07:21 -05001# vi: ts=4 expandtab
2#
3# Copyright (C) 2017 VMware Inc.
4#
5# Author: Anish Swaminathan <anishs@vmware.com>
6#
7import os
8import base64
9
10from cloudinit import log as logging
11from cloudinit import sources
12from cloudinit import util
13
14from distutils.spawn import find_executable
15
16LOG = logging.getLogger(__name__)
17
18class DataSourceVmxGuestinfo(sources.DataSource):
19 def __init__(self, sys_cfg, distro, paths, ud_proc=None):
20 sources.DataSource.__init__(self, sys_cfg, distro, paths, ud_proc)
21 self.metadata = {}
22 self.userdata_raw = ''
23 self.vmtoolsd = find_executable("vmtoolsd")
24 if not self.vmtoolsd:
25 LOG.error("Failed to find vmtoolsd")
26
27 def get_data(self):
28 if not self.vmtoolsd:
29 LOG.error("vmtoolsd is required to fetch guestinfo value")
30 return False
31 hostname = self._get_guestinfo_value('hostname')
32 if hostname:
33 self.distro.set_hostname(hostname)
34 ud = self._get_guestinfo_value('userdata')
35 if ud:
36 LOG.debug("Decoding base64 format guestinfo.userdata")
37 self.userdata_raw = base64.b64decode(ud)
38 found = True
39 dev_index = 0
40 network_settings = ''
41 while found:
42 key_begin = 'interface.' + str(dev_index)
43 key_iname = key_begin + '.name'
44 interface_name = self._get_guestinfo_value(key_iname)
45 if interface_name:
46 network_settings += 'auto ' + interface_name + '\n'
47 network_settings += 'iface ' + interface_name
48 key_proto = key_begin + '.dhcp'
49 dhcp_enabled = self._get_guestinfo_value(key_proto)
50 key_address = key_begin + '.address'
51 address = self._get_guestinfo_value(key_address)
52 bootproto = 'dhcp'
53 if dhcp_enabled:
54 if dhcp_enabled == 'yes':
55 network_settings += ' dhcp\n'
56 elif dhcp_enabled == 'no':
57 network_settings += ' static\n'
58 bootproto = 'static'
59 else:
60 LOG.warning("Invalid value for yes/no parameter for %s, setting to dhcp", key_proto)
61 elif address:
62 bootproto = 'static'
63 dhcp_enabled == 'no'
64 network_settings += ' static\n'
65 else:
66 dhcp_enabled == 'yes'
67 network_settings += ' dhcp\n'
68 LOG.debug("Setting network bootproto to dhcp by default")
69 key_mac = key_begin + '.mac'
70 mac = self._get_guestinfo_value(key_mac)
71 if address:
72 network_settings += 'address ' + address + '\n'
73 if mac:
74 network_settings += 'hwaddress ' + mac + '\n'
75 key_netmask = key_begin + '.netmask'
76 netmask = self._get_guestinfo_value(key_netmask)
77 if netmask:
78 network_settings += 'netmask ' + netmask + '\n'
79 key_dnsserver = 'dns.servers'
80 dnsserver = self._get_guestinfo_value(key_dnsserver)
81 if dnsserver:
82 network_settings += 'dns-nameservers '
83 dnsserver = dnsserver.split(',')
84 for d in dnsserver:
85 network_settings += d + ' '
86 network_settings += '\n'
87 key_dnsdomain = 'dns.domains'
88 dnsdomain = self._get_guestinfo_value(key_dnsdomain)
89 if dnsdomain:
90 network_settings += 'dns-search '
91 dnsdomain = dnsdomain.split(',')
92 for d in dnsdomain:
93 network_settings += d + ' '
94 network_settings += '\n'
95 route_index = 0
96 default_destination_set = False
97 while True:
98 key_route = key_begin + '.route.' + str(route_index)
99 route = self._get_guestinfo_value(key_route)
100 if route:
101 network_settings += "routes.%s " % (route_index)
102 route = route.split(',')
103 if len(route) > 2:
104 LOG.debug("Route information for %s route in %s device incorrect - ",
105 "expected 2 values", route_index, dev_index)
106 continue
107 elif len(route) == 2:
108 network_settings += route[0] + ' ' + route[1] + '\n'# Gateway Destination
109 else: #length = 1
110 if not default_destination_set:
111 network_settings += route[0] + ' 0.0.0.0/0' + '\n'
112 default_destination_set = True
113 else:
114 LOG.debug("Default destination set previously, not setting route %s", route_index)
115 else:
116 break
117 route_index += 1
118 else:
119 found = False
120 dev_index += 1
121 self.distro.apply_network(network_settings, False)
122 return True
123
124 def _get_guestinfo_value(self, key):
125 LOG.debug("Getting guestinfo value for key %s", key)
126 value = ''
127 try:
128 (value, _err) = util.subp([self.vmtoolsd, "--cmd", "info-get guestinfo." + key])
129 if _err:
130 LOG.error("Failed to get guestinfo value for key %s", key)
131 except util.ProcessExecutionError as error:
132 util.logexc(LOG,"Failed to get guestinfo value for key %s: %s", key, error)
133 except Exception:
134 util.logexc(LOG,"Unexpected error while trying to get guestinfo value for key %s", key)
135 return value.rstrip()
136
137 def get_instance_id(self):
138 with open('/sys/class/dmi/id/product_uuid', 'r') as id_file:
139 return str(id_file.read()).rstrip()
140
141def get_datasource_list(depends):
142 """
143 Return a list of data sources that match this set of dependencies
144 """
145 return [DataSourceVmxGuestinfo]