Created
May 25, 2016 22:50
-
-
Save harlowja/12e0a56ff0ee0182cc943f966bef8ec0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=== modified file 'cloudinit/sources/DataSourceConfigDrive.py' | |
--- cloudinit/sources/DataSourceConfigDrive.py 2016-05-19 22:33:15 +0000 | |
+++ cloudinit/sources/DataSourceConfigDrive.py 2016-05-25 22:49:19 +0000 | |
@@ -137,6 +137,7 @@ | |
self.ec2_metadata = results.get('ec2-metadata') | |
self.userdata_raw = results.get('userdata') | |
self.version = results['version'] | |
+ self.osversion = results.get('osversion') | |
self.files.update(results.get('files', {})) | |
vd = results.get('vendordata') | |
@@ -163,8 +164,10 @@ | |
def network_config(self): | |
if self._network_config is None: | |
if self.network_json is not None: | |
- self._network_config = openstack.convert_net_json( | |
- self.network_json) | |
+ reader = openstack.NetJsonReader() | |
+ network_config = reader.read(self.network_json, | |
+ osversion=self.osversion) | |
+ self._network_config = network_config | |
return self._network_config | |
=== modified file 'cloudinit/sources/helpers/openstack.py' | |
--- cloudinit/sources/helpers/openstack.py 2016-05-19 21:26:30 +0000 | |
+++ cloudinit/sources/helpers/openstack.py 2016-05-25 22:47:57 +0000 | |
@@ -242,7 +242,9 @@ | |
'userdata': '', | |
'version': 2, | |
} | |
- data = datafiles(self._find_working_version()) | |
+ os_version = self._find_working_version() | |
+ results['osversion'] = os_version | |
+ data = datafiles(os_version) | |
for (name, (path, required, translator)) in data.items(): | |
path = self._path_join(self.base_path, path) | |
data = None | |
@@ -474,22 +476,22 @@ | |
retries=self.retries) | |
-def convert_net_json(network_json): | |
- """Return a dictionary of network_config by parsing provided | |
- OpenStack ConfigDrive NetworkData json format | |
- | |
- OpenStack network_data.json provides a 3 element dictionary | |
- - "links" (links are network devices, physical or virtual) | |
- - "networks" (networks are ip network configurations for one or more | |
- links) | |
- - services (non-ip services, like dns) | |
- | |
- networks and links are combined via network items referencing specific | |
- links via a 'link_id' which maps to a links 'id' field. | |
- | |
- To convert this format to network_config yaml, we first iterate over the | |
- links and then walk the network list to determine if any of the networks | |
- utilize the current link; if so we generate a subnet entry for the device | |
+class NetJsonReader(object): | |
+ """Reader that understands how to convert openstack format to our format. | |
+ | |
+ OpenStack ``network_data.json`` provides a 3 element dictionary: | |
+ | |
+ - "links" (links are network devices, physical or virtual) | |
+ - "networks" (networks are ip network configurations for one or more links) | |
+ - services (non-ip services, like dns) | |
+ | |
+ ``networks`` and ``links`` are combined via network items referencing | |
+ specific links via a 'link_id' which maps to a links 'id' field. | |
+ | |
+ To convert this format to ``network_config`` yaml, we first iterate over | |
+ the links and then walk the network list to determine if any of the | |
+ networks utilize the current link; if so we generate a subnet entry for | |
+ the device | |
We also need to map network_data.json fields to network_config fields. For | |
example, the network_data links 'id' field is equivalent to network_config | |
@@ -527,76 +529,102 @@ | |
], | |
} | |
- links = network_json.get('links', []) | |
- networks = network_json.get('networks', []) | |
- services = network_json.get('services', []) | |
- | |
- 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']) | |
- if 'dhcp' in network['type']: | |
- t = 'dhcp6' if network['type'].startswith('ipv6') else 'dhcp4' | |
- subnet.update({ | |
- 'type': t, | |
- }) | |
+ def _fixup_2015_10_15(self, network_json): | |
+ fixed_links = [] | |
+ fixed = False | |
+ for link in network_json.get('links', []): | |
+ # See: http://lists.openstack.org/pipermail/openstack-dev/\ | |
+ # 2016-May/thread.html#95835 | |
+ if link['type'] in ['ethernet', 'vif', 'ovs', 'bridge']: | |
+ link = copy.deepcopy(link) | |
+ link['type'] = 'phy' | |
+ fixed = True | |
+ fixed_links.append(link) | |
+ if fixed: | |
+ network_json = copy.deepcopy(network_json) | |
+ network_json['links'] = fixed_links | |
+ return network_json | |
+ | |
+ def _fixup_latest(self, network_json): | |
+ # Until ML bug(?) is fixed... | |
+ return self._fixup_2015_10_15(network_json) | |
+ | |
+ def read(self, network_json, osversion=None): | |
+ if osversion: | |
+ osversion = osversion.replace("-", "_") | |
+ try: | |
+ fixer_func = getattr(self, "_fixup_%s" % osversion) | |
+ except AttributeError: | |
+ pass | |
else: | |
- subnet.update({ | |
- 'type': 'static', | |
- 'address': network.get('ip_address'), | |
- }) | |
- if network['type'] == 'ipv6': | |
- subnet['ipv6'] = True | |
+ network_json = fixer_func(network_json) | |
+ | |
+ links = network_json.get('links', []) | |
+ networks = network_json.get('networks', []) | |
+ services = network_json.get('services', []) | |
+ | |
+ 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']) | |
+ if 'dhcp' in network['type']: | |
+ t = 'dhcp6' if network['type'].startswith('ipv6') else 'dhcp4' | |
+ subnet.update({ | |
+ 'type': t, | |
+ }) | |
else: | |
- subnet['ipv4'] = True | |
- subnets.append(subnet) | |
- cfg.update({'subnets': subnets}) | |
- if link['type'] in ['ethernet', 'vif', 'ovs', 'phy']: | |
- cfg.update({ | |
- 'type': 'physical', | |
- 'mac_address': link['ethernet_mac_address']}) | |
- elif link['type'] in ['bond']: | |
- params = {} | |
- for k, v in link.items(): | |
- if k == 'bond_links': | |
- continue | |
- elif k.startswith('bond'): | |
- params.update({k: v}) | |
- cfg.update({ | |
- 'bond_interfaces': copy.deepcopy(link['bond_links']), | |
- 'params': params, | |
- }) | |
- elif link['type'] in ['vlan']: | |
- cfg.update({ | |
- 'name': "%s.%s" % (link['vlan_link'], | |
- link['vlan_id']), | |
- 'vlan_link': link['vlan_link'], | |
- '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) | |
- | |
- for service in services: | |
- cfg = copy.deepcopy(service) | |
- cfg.update({'type': 'nameserver'}) | |
- config.append(cfg) | |
- | |
- return {'version': 1, 'config': config} | |
+ subnet.update({ | |
+ 'type': 'static', | |
+ 'address': network.get('ip_address'), | |
+ }) | |
+ if network['type'] == 'ipv6': | |
+ subnet['ipv6'] = True | |
+ else: | |
+ subnet['ipv4'] = True | |
+ subnets.append(subnet) | |
+ cfg.update({'subnets': subnets}) | |
+ if link['type'] in ['phy']: | |
+ cfg.update({ | |
+ 'type': 'physical', | |
+ 'mac_address': link['ethernet_mac_address'], | |
+ 'mtu': link['mtu']}) | |
+ elif link['type'] in ['bond']: | |
+ params = {} | |
+ for k, v in link.items(): | |
+ if k == 'bond_links': | |
+ continue | |
+ elif k.startswith('bond'): | |
+ params.update({k: v}) | |
+ cfg.update({ | |
+ 'bond_interfaces': copy.deepcopy(link['bond_links']), | |
+ 'params': params, | |
+ }) | |
+ elif link['type'] in ['vlan']: | |
+ cfg.update({ | |
+ 'name': "%s.%s" % (link['vlan_link'], | |
+ link['vlan_id']), | |
+ 'vlan_link': link['vlan_link'], | |
+ 'vlan_id': link['vlan_id'], | |
+ 'mac_address': link['vlan_mac_address'], | |
+ }) | |
+ else: | |
+ raise ValueError( | |
+ 'Unknown network_data link type: %s' % link['type']) | |
+ | |
+ config.append(cfg) | |
+ | |
+ for service in services: | |
+ cfg = copy.deepcopy(service) | |
+ cfg.update({'type': 'nameserver'}) | |
+ config.append(cfg) | |
+ | |
+ return {'version': 1, 'config': config} | |
def convert_vendordata_json(data, recurse=True): |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment