diff options
author | Joshua Harlow <harlowja@gmail.com> | 2016-06-06 18:42:29 -0700 |
---|---|---|
committer | Joshua Harlow <harlowja@gmail.com> | 2016-06-06 18:42:29 -0700 |
commit | f640797e342b6efbfb838a6350b312935222e992 (patch) | |
tree | 4e893298101cf3141d80b4bf2a2d6e009462502d /cloudinit/sources/helpers | |
parent | 85a53d66ad0241b2d6453d902487bb2edc1512b8 (diff) | |
parent | bc9bd58d1533d996029770da758f73217c15af33 (diff) | |
download | vyos-cloud-init-f640797e342b6efbfb838a6350b312935222e992.tar.gz vyos-cloud-init-f640797e342b6efbfb838a6350b312935222e992.zip |
Rebase against master
Diffstat (limited to 'cloudinit/sources/helpers')
-rw-r--r-- | cloudinit/sources/helpers/openstack.py | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/cloudinit/sources/helpers/openstack.py b/cloudinit/sources/helpers/openstack.py index 1af99118..494335b3 100644 --- a/cloudinit/sources/helpers/openstack.py +++ b/cloudinit/sources/helpers/openstack.py @@ -28,6 +28,7 @@ import six from cloudinit import ec2_utils from cloudinit import log as logging +from cloudinit import net from cloudinit import sources from cloudinit import url_helper from cloudinit import util @@ -190,14 +191,14 @@ class BaseReader(object): versions_available) return selected_version - def _read_content_path(self, item): + def _read_content_path(self, item, decode=False): path = item.get('content_path', '').lstrip("/") path_pieces = path.split("/") valid_pieces = [p for p in path_pieces if len(p)] if not valid_pieces: raise BrokenMetadata("Item %s has no valid content path" % (item)) path = self._path_join(self.base_path, "openstack", *path_pieces) - return self._path_read(path) + return self._path_read(path, decode=decode) def read_v2(self): """Reads a version 2 formatted location. @@ -298,7 +299,8 @@ class BaseReader(object): net_item = metadata.get("network_config", None) if net_item: try: - results['network_config'] = self._read_content_path(net_item) + content = self._read_content_path(net_item, decode=True) + results['network_config'] = content except IOError as e: raise BrokenMetadata("Failed to read network" " configuration: %s" % (e)) @@ -333,8 +335,8 @@ class ConfigDriveReader(BaseReader): components = [base] + list(add_ons) return os.path.join(*components) - def _path_read(self, path): - return util.load_file(path, decode=False) + def _path_read(self, path, decode=False): + return util.load_file(path, decode=decode) def _fetch_available_versions(self): if self._versions is None: @@ -446,7 +448,7 @@ class MetadataReader(BaseReader): self._versions = found return self._versions - def _path_read(self, path): + def _path_read(self, path, decode=False): def should_retry_cb(_request_args, cause): try: @@ -463,7 +465,10 @@ class MetadataReader(BaseReader): ssl_details=self.ssl_details, timeout=self.timeout, exception_cb=should_retry_cb) - return response.contents + if decode: + return response.contents.decode() + else: + return response.contents def _path_join(self, base, *add_ons): return url_helper.combine_url(base, *add_ons) @@ -474,7 +479,8 @@ class MetadataReader(BaseReader): retries=self.retries) -def convert_net_json(network_json): +# Convert OpenStack ConfigDrive NetworkData json to network_config yaml +def convert_net_json(network_json=None, known_macs=None): """Return a dictionary of network_config by parsing provided OpenStack ConfigDrive NetworkData json format @@ -501,8 +507,10 @@ def convert_net_json(network_json): enumerate a dictionary of valid keys for network_yaml and apply filtering to drop these superflous keys from the network_config yaml. """ + if network_json is None: + return None - # Dict of network_config key for filtering network_json + # dict of network_config key for filtering network_json valid_keys = { 'physical': [ 'name', @@ -510,6 +518,7 @@ def convert_net_json(network_json): 'mac_address', 'subnets', 'params', + 'mtu', ], 'subnet': [ 'type', @@ -519,7 +528,6 @@ def convert_net_json(network_json): 'metric', 'gateway', 'pointopoint', - 'mtu', 'scope', 'dns_nameservers', 'dns_search', @@ -534,13 +542,19 @@ def convert_net_json(network_json): config = [] for link in links: subnets = [] - cfg = dict((k, v) for k, v in link.items() - if k in valid_keys['physical']) - cfg.update({'name': link['id']}) - for network in [net for net in networks - if net['link'] == link['id']]: - subnet = dict((k, v) for k, v in network.items() - if k in valid_keys['subnet']) + cfg = {k: v for k, v in link.items() + if k in valid_keys['physical']} + # 'name' is not in openstack spec yet, but we will support it if it is + # present. The 'id' in the spec is currently implemented as the host + # nic's name, meaning something like 'tap-adfasdffd'. We do not want + # to name guest devices with such ugly names. + if 'name' in link: + cfg['name'] = link['name'] + + for network in [n for n in networks + if n['link'] == link['id']]: + subnet = {k: v for k, v in network.items() + if k in valid_keys['subnet']} if 'dhcp' in network['type']: t = 'dhcp6' if network['type'].startswith('ipv6') else 'dhcp4' subnet.update({ @@ -551,13 +565,13 @@ def convert_net_json(network_json): 'type': 'static', 'address': network.get('ip_address'), }) - if network['type'] == 'ipv6': - subnet['ipv6'] = True - else: - subnet['ipv4'] = True + if network['type'] == 'ipv4': + subnet['ipv4'] = True + if network['type'] == 'ipv6': + subnet['ipv6'] = True subnets.append(subnet) cfg.update({'subnets': subnets}) - if link['type'] in ['ethernet', 'vif', 'ovs', 'phy']: + if link['type'] in ['ethernet', 'vif', 'ovs', 'phy', 'bridge']: cfg.update({ 'type': 'physical', 'mac_address': link['ethernet_mac_address']}) @@ -580,19 +594,29 @@ def convert_net_json(network_json): 'vlan_id': link['vlan_id'], 'mac_address': link['vlan_mac_address'], }) - elif link['type'] in ['bridge']: - cfg.update({ - 'type': 'bridge', - 'mac_address': link['ethernet_mac_address'], - 'mtu': link['mtu']}) else: raise ValueError( 'Unknown network_data link type: %s' % link['type']) config.append(cfg) + need_names = [d for d in config + if d.get('type') == 'physical' and 'name' not in d] + + if need_names: + if known_macs is None: + known_macs = net.get_interfaces_by_mac() + + for d in need_names: + mac = d.get('mac_address') + if not mac: + raise ValueError("No mac_address or name entry for %s" % d) + if mac not in known_macs: + raise ValueError("Unable to find a system nic for %s" % d) + d['name'] = known_macs[mac] + for service in services: - cfg = copy.deepcopy(service) + cfg = service cfg.update({'type': 'nameserver'}) config.append(cfg) |