summaryrefslogtreecommitdiff
path: root/cloudinit
diff options
context:
space:
mode:
authorJoshua Harlow <harlowja@gmail.com>2016-06-13 13:10:07 -0700
committerJoshua Harlow <harlowja@gmail.com>2016-06-13 13:10:07 -0700
commit6e19efb17609cd5c49941ea4f1608900b8459ca8 (patch)
treeb27786b0581f215f258f2a754d616a95b3eecaa1 /cloudinit
parentf666f6116be64cb1c033ed6d0f829bdb2f21ba69 (diff)
downloadvyos-cloud-init-6e19efb17609cd5c49941ea4f1608900b8459ca8.tar.gz
vyos-cloud-init-6e19efb17609cd5c49941ea4f1608900b8459ca8.zip
Refactor some of sysconfig changes -> network_state module
Diffstat (limited to 'cloudinit')
-rw-r--r--cloudinit/net/eni.py22
-rw-r--r--cloudinit/net/network_state.py103
-rw-r--r--cloudinit/net/sysconfig.py26
3 files changed, 87 insertions, 64 deletions
diff --git a/cloudinit/net/eni.py b/cloudinit/net/eni.py
index a695f5ed..df0df9b2 100644
--- a/cloudinit/net/eni.py
+++ b/cloudinit/net/eni.py
@@ -360,7 +360,15 @@ class Renderer(object):
'''Given state, emit etc/network/interfaces content.'''
content = ""
- interfaces = network_state.get('interfaces')
+ content += "auto lo\niface lo inet loopback\n"
+
+ nameservers = network_state.dns_nameservers
+ if nameservers:
+ content += " dns-nameservers %s\n" % (" ".join(nameservers))
+ searchdomains = network_state.dns_searchdomains
+ if searchdomains:
+ content += " dns-search %s\n" % (" ".join(searchdomains))
+
''' Apply a sort order to ensure that we write out
the physical interfaces first; this is critical for
bonding
@@ -371,12 +379,7 @@ class Renderer(object):
'bridge': 2,
'vlan': 3,
}
- content += "auto lo\niface lo inet loopback\n"
- for dnskey, value in network_state.get('dns', {}).items():
- if len(value):
- content += " dns-{} {}\n".format(dnskey, " ".join(value))
-
- for iface in sorted(interfaces.values(),
+ for iface in sorted(network_state.iter_interfaces(),
key=lambda k: (order[k['type']], k['name'])):
if content[-2:] != "\n\n":
@@ -409,7 +412,7 @@ class Renderer(object):
content += "iface {name} {inet} {mode}\n".format(**iface)
content += _iface_add_attrs(iface)
- for route in network_state.get('routes'):
+ for route in network_state.iter_routes():
content += self._render_route(route)
# global replacements until v2 format
@@ -441,8 +444,7 @@ class Renderer(object):
fp_prefix = os.path.sep.join((target, links_prefix))
for f in glob.glob(fp_prefix + "*"):
os.unlink(f)
- interfaces = network_state.get('interfaces')
- for iface in interfaces.values():
+ for iface in network_state.iter_interfaces():
if (iface['type'] == 'physical' and 'name' in iface and
iface.get('mac_address')):
fname = fp_prefix + iface['name'] + ".link"
diff --git a/cloudinit/net/network_state.py b/cloudinit/net/network_state.py
index a8be5e26..d75fc852 100644
--- a/cloudinit/net/network_state.py
+++ b/cloudinit/net/network_state.py
@@ -38,10 +38,10 @@ def parse_net_config_data(net_config, skip_broken=True):
"""
state = None
if 'version' in net_config and 'config' in net_config:
- ns = NetworkState(version=net_config.get('version'),
- config=net_config.get('config'))
- ns.parse_config(skip_broken=skip_broken)
- state = ns.network_state
+ nsi = NetworkStateInterpreter(version=net_config.get('version'),
+ config=net_config.get('config'))
+ nsi.parse_config(skip_broken=skip_broken)
+ state = nsi.network_state
return state
@@ -57,11 +57,10 @@ def parse_net_config(path, skip_broken=True):
def from_state_file(state_file):
- network_state = None
state = util.read_conf(state_file)
- network_state = NetworkState()
- network_state.load(state)
- return network_state
+ nsi = NetworkStateInterpreter()
+ nsi.load(state)
+ return nsi
def diff_keys(expected, actual):
@@ -113,9 +112,51 @@ class CommandHandlerMeta(type):
parents, dct)
-@six.add_metaclass(CommandHandlerMeta)
class NetworkState(object):
+ def __init__(self, network_state, version=NETWORK_STATE_VERSION):
+ self._network_state = copy.deepcopy(network_state)
+ self._version = version
+
+ @property
+ def version(self):
+ return self._version
+
+ def iter_routes(self, filter_func=None):
+ for route in self._network_state.get('routes', []):
+ if filter_func is not None:
+ if filter_func(route):
+ yield route
+ else:
+ yield route
+
+ @property
+ def dns_nameservers(self):
+ try:
+ return self._network_state['dns']['nameservers']
+ except KeyError:
+ return []
+
+ @property
+ def dns_searchdomains(self):
+ try:
+ return self._network_state['dns']['search']
+ except KeyError:
+ return []
+
+ def iter_interfaces(self, filter_func=None):
+ ifaces = self._network_state.get('interfaces', {})
+ for iface in six.itervalues(ifaces):
+ if filter_func is None:
+ yield iface
+ else:
+ if filter_func(iface):
+ yield iface
+
+
+@six.add_metaclass(CommandHandlerMeta)
+class NetworkStateInterpreter(object):
+
initial_network_state = {
'interfaces': {},
'routes': [],
@@ -126,22 +167,26 @@ class NetworkState(object):
}
def __init__(self, version=NETWORK_STATE_VERSION, config=None):
- self.version = version
- self.config = config
- self.network_state = copy.deepcopy(self.initial_network_state)
+ self._version = version
+ self._config = config
+ self._network_state = copy.deepcopy(self.initial_network_state)
+
+ @property
+ def network_state(self):
+ return NetworkState(self._network_state, version=self._version)
def dump(self):
state = {
- 'version': self.version,
- 'config': self.config,
- 'network_state': self.network_state,
+ 'version': self._version,
+ 'config': self._config,
+ 'network_state': self._network_state,
}
return util.yaml_dumps(state)
def load(self, state):
if 'version' not in state:
LOG.error('Invalid state, missing version field')
- raise Exception('Invalid state, missing version field')
+ raise ValueError('Invalid state, missing version field')
required_keys = NETWORK_STATE_REQUIRED_KEYS[state['version']]
missing_keys = diff_keys(required_keys, state)
@@ -155,11 +200,11 @@ class NetworkState(object):
setattr(self, key, state[key])
def dump_network_state(self):
- return util.yaml_dumps(self.network_state)
+ return util.yaml_dumps(self._network_state)
def parse_config(self, skip_broken=True):
# rebuild network state
- for command in self.config:
+ for command in self._config:
command_type = command['type']
try:
handler = self.command_handlers[command_type]
@@ -189,7 +234,7 @@ class NetworkState(object):
}
'''
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces', {})
iface = interfaces.get(command['name'], {})
for param, val in command.get('params', {}).items():
iface.update({param: val})
@@ -215,7 +260,7 @@ class NetworkState(object):
'gateway': None,
'subnets': subnets,
})
- self.network_state['interfaces'].update({command.get('name'): iface})
+ self._network_state['interfaces'].update({command.get('name'): iface})
self.dump_network_state()
@ensure_command_keys(['name', 'vlan_id', 'vlan_link'])
@@ -228,7 +273,7 @@ class NetworkState(object):
hwaddress ether BC:76:4E:06:96:B3
vlan-raw-device eth0
'''
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces', {})
self.handle_physical(command)
iface = interfaces.get(command.get('name'), {})
iface['vlan-raw-device'] = command.get('vlan_link')
@@ -263,12 +308,12 @@ class NetworkState(object):
'''
self.handle_physical(command)
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces')
iface = interfaces.get(command.get('name'), {})
for param, val in command.get('params').items():
iface.update({param: val})
iface.update({'bond-slaves': 'none'})
- self.network_state['interfaces'].update({iface['name']: iface})
+ self._network_state['interfaces'].update({iface['name']: iface})
# handle bond slaves
for ifname in command.get('bond_interfaces'):
@@ -280,13 +325,13 @@ class NetworkState(object):
# inject placeholder
self.handle_physical(cmd)
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces', {})
bond_if = interfaces.get(ifname)
bond_if['bond-master'] = command.get('name')
# copy in bond config into slave
for param, val in command.get('params').items():
bond_if.update({param: val})
- self.network_state['interfaces'].update({ifname: bond_if})
+ self._network_state['interfaces'].update({ifname: bond_if})
@ensure_command_keys(['name', 'bridge_interfaces', 'params'])
def handle_bridge(self, command):
@@ -319,7 +364,7 @@ class NetworkState(object):
# find one of the bridge port ifaces to get mac_addr
# handle bridge_slaves
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces', {})
for ifname in command.get('bridge_interfaces'):
if ifname in interfaces:
continue
@@ -330,7 +375,7 @@ class NetworkState(object):
# inject placeholder
self.handle_physical(cmd)
- interfaces = self.network_state.get('interfaces')
+ interfaces = self._network_state.get('interfaces', {})
self.handle_physical(command)
iface = interfaces.get(command.get('name'), {})
iface['bridge_ports'] = command['bridge_interfaces']
@@ -341,7 +386,7 @@ class NetworkState(object):
@ensure_command_keys(['address'])
def handle_nameserver(self, command):
- dns = self.network_state.get('dns')
+ dns = self._network_state.get('dns')
if 'address' in command:
addrs = command['address']
if not type(addrs) == list:
@@ -357,7 +402,7 @@ class NetworkState(object):
@ensure_command_keys(['destination'])
def handle_route(self, command):
- routes = self.network_state.get('routes')
+ routes = self._network_state.get('routes', [])
network, cidr = command['destination'].split("/")
netmask = cidr2mask(int(cidr))
route = {
diff --git a/cloudinit/net/sysconfig.py b/cloudinit/net/sysconfig.py
index a4bcaaad..647ca3ed 100644
--- a/cloudinit/net/sysconfig.py
+++ b/cloudinit/net/sysconfig.py
@@ -67,29 +67,6 @@ def _quote_value(value):
return value
-class NetworkStateHelper(object):
- def __init__(self, network_state):
- self._network_state = network_state.copy()
-
- @property
- def dns_nameservers(self):
- return self._network_state['dns']['nameservers']
-
- @property
- def dns_searchdomains(self):
- return self._network_state['dns']['search']
-
- def iter_interfaces(self, filter_func=None):
- ifaces = self._network_state.get('interfaces')
- if ifaces:
- for iface in ifaces.values():
- if filter_func is None:
- yield iface
- else:
- if filter_func(iface):
- yield iface
-
-
class ConfigMap(object):
"""Sysconfig like dictionary object."""
@@ -424,7 +401,6 @@ class Renderer(object):
self, target, network_state, sysconf_dir="etc/sysconfig/",
netrules='etc/udev/rules.d/70-persistent-net.rules',
dns='etc/resolv.conf'):
- network_state = NetworkStateHelper(network_state)
if target:
base_sysconf_dir = os.path.join(target, sysconf_dir)
else:
@@ -480,7 +456,7 @@ def main():
net_state = network_state.parse_net_config_data(
openstack.convert_net_json(network_json), skip_broken=False)
r = Renderer()
- r.render_network_state(args.dir, NetworkStateHelper(net_state))
+ r.render_network_state(args.dir, net_state)
if __name__ == '__main__':