122
124
of specifying multiple key value pairs within the same string. For
123
125
example, a string in the format of 'key1=value1, key2=value2' will
124
126
return a dict of:
128
131
2. A string in the above format, but supporting a comma-delimited list
129
132
of values for the same key. For example, a string in the format of
130
133
'key1=value1, key2=value3,value4,value5' will return a dict of:
132
'key2', 'value2,value3,value4'}
136
'key2', 'value2,value3,value4'}
134
138
3. A string containing a colon character (:) prior to an equal
135
139
character (=) will be treated as yaml and parsed as such. This can be
136
140
used to specify more complex key value pairs. For example,
137
141
a string in the format of 'key1: subkey1=value1, subkey2=value2' will
138
142
return a dict of:
139
{'key1', 'subkey1=value1, subkey2=value2'}
144
{'key1', 'subkey1=value1, subkey2=value2'}
141
146
The provided config_flags string may be a list of comma-separated values
142
147
which themselves may be comma-separated list of values.
924
927
class NeutronPortContext(OSContextGenerator):
925
NIC_PREFIXES = ['eth', 'bond']
927
929
def resolve_ports(self, ports):
928
930
"""Resolve NICs not yet bound to bridge(s)
935
937
hwaddr_to_nic = {}
936
938
hwaddr_to_ip = {}
937
for nic in list_nics(self.NIC_PREFIXES):
939
for nic in list_nics():
940
# Ignore virtual interfaces (bond masters will be identified from
942
if not is_phy_iface(nic):
945
_nic = get_bond_master(nic)
947
log("Replacing iface '%s' with bond master '%s'" % (nic, _nic),
938
951
hwaddr = get_nic_hwaddr(nic)
939
952
hwaddr_to_nic[hwaddr] = nic
940
953
addresses = get_ipv4_addr(nic, fatal=False)
1050
1064
:param config_file : Service's config file to query sections
1051
1065
:param interface : Subordinate interface to inspect
1053
self.service = service
1054
1067
self.config_file = config_file
1055
self.interface = interface
1068
if isinstance(service, list):
1069
self.services = service
1071
self.services = [service]
1072
if isinstance(interface, list):
1073
self.interfaces = interface
1075
self.interfaces = [interface]
1057
1077
def __call__(self):
1058
1078
ctxt = {'sections': {}}
1059
for rid in relation_ids(self.interface):
1080
for interface in self.interfaces:
1081
rids.extend(relation_ids(interface))
1060
1083
for unit in related_units(rid):
1061
1084
sub_config = relation_get('subordinate_configuration',
1062
1085
rid=rid, unit=unit)
1068
1091
'setting from %s' % rid, level=ERROR)
1071
if self.service not in sub_config:
1072
log('Found subordinate_config on %s but it contained'
1073
'nothing for %s service' % (rid, self.service),
1077
sub_config = sub_config[self.service]
1078
if self.config_file not in sub_config:
1079
log('Found subordinate_config on %s but it contained'
1080
'nothing for %s' % (rid, self.config_file),
1084
sub_config = sub_config[self.config_file]
1085
for k, v in six.iteritems(sub_config):
1087
for section, config_dict in six.iteritems(v):
1088
log("adding section '%s'" % (section),
1090
ctxt[k][section] = config_dict
1094
for service in self.services:
1095
if service not in sub_config:
1096
log('Found subordinate_config on %s but it contained'
1097
'nothing for %s service' % (rid, service),
1101
sub_config = sub_config[service]
1102
if self.config_file not in sub_config:
1103
log('Found subordinate_config on %s but it contained'
1104
'nothing for %s' % (rid, self.config_file),
1108
sub_config = sub_config[self.config_file]
1109
for k, v in six.iteritems(sub_config):
1111
for section, config_list in six.iteritems(v):
1112
log("adding section '%s'" % (section),
1114
if ctxt[k].get(section):
1115
ctxt[k][section].extend(config_list)
1117
ctxt[k][section] = config_list
1094
1120
log("%d section(s) found" % (len(ctxt['sections'])), level=DEBUG)
1267
1293
def __call__(self):
1268
1294
ports = config('data-port')
1296
# Map of {port/mac:bridge}
1270
1297
portmap = parse_data_port_mappings(ports)
1271
ports = portmap.values()
1298
ports = portmap.keys()
1299
# Resolve provided ports or mac addresses and filter out those
1300
# already attached to a bridge.
1272
1301
resolved = self.resolve_ports(ports)
1302
# FIXME: is this necessary?
1273
1303
normalized = {get_nic_hwaddr(port): port for port in resolved
1274
1304
if port not in ports}
1275
1305
normalized.update({port: port for port in resolved
1276
1306
if port in ports})
1278
return {bridge: normalized[port] for bridge, port in
1308
return {bridge: normalized[port] for port, bridge in
1279
1309
six.iteritems(portmap) if port in normalized.keys()}