13
13
# under the License.
18
from oslo.config import cfg
20
16
from cloudbaseinit import exception
21
17
from cloudbaseinit.metadata.services import base as service_base
22
18
from cloudbaseinit.openstack.common import log as logging
23
19
from cloudbaseinit.osutils import factory as osutils_factory
24
20
from cloudbaseinit.plugins import base as plugin_base
25
from cloudbaseinit.utils import encoding
28
23
LOG = logging.getLogger(__name__)
31
cfg.StrOpt('network_adapter', default=None, help='Network adapter to '
32
'configure. If not specified, the first available ethernet '
33
'adapter will be chosen.'),
37
CONF.register_opts(opts)
25
# Mandatory network details are marked with True. And
26
# if the key is a tuple, then at least one field must exists.
28
("name", "mac"): True,
31
"broadcast": False, # currently not used
33
"dnsnameservers": False
37
def _preprocess_nics(network_details, network_adapters):
38
"""Check NICs and fill missing data if possible."""
40
if not network_adapters:
41
raise exception.CloudbaseInitException(
42
"no network adapters available")
43
# Sort VM adapters by name (assuming that those
44
# from the context are in correct order).
45
network_adapters = sorted(network_adapters, key=lambda arg: arg[0])
46
_network_details = [] # store here processed data
47
# check and update every NetworkDetails object
49
total = len(network_adapters)
50
for nic in network_details:
51
if not isinstance(nic, service_base.NetworkDetails):
52
raise exception.CloudbaseInitException(
53
"invalid NetworkDetails object {!r}"
58
for fields, status in NET_REQUIRE.items():
60
continue # skip 'not required' entries
61
if not isinstance(fields, tuple):
63
final_status = any([getattr(nic, field) for field in fields])
65
LOG.error("Incomplete NetworkDetails object %s", nic)
68
# Complete hardware address if missing by selecting
69
# the corresponding MAC in terms of naming, then ordering.
73
macs = [adapter[1] for adapter in network_adapters
74
if adapter[0] == nic.name]
75
mac = macs[0] if macs else None
77
if not mac and ind < total:
78
mac = network_adapters[ind][1]
79
nic = service_base.NetworkDetails(
88
_network_details.append(nic)
90
return _network_details
40
93
class NetworkConfigPlugin(plugin_base.BasePlugin):
42
95
def execute(self, service, shared_data):
43
# FIXME(cpoieana): `network_config` is deprecated
44
# * refactor all services by providing NetworkDetails objects *
45
# Also, the old method is not supporting multiple NICs.
47
96
osutils = osutils_factory.get_os_utils()
48
97
network_details = service.get_network_details()
49
98
if not network_details:
50
network_config = service.get_network_config()
51
if not network_config:
52
return (plugin_base.PLUGIN_EXECUTION_DONE, False)
54
# ---- BEGIN deprecated code ----
55
if not network_details:
56
if 'content_path' not in network_config:
57
return (plugin_base.PLUGIN_EXECUTION_DONE, False)
59
content_path = network_config['content_path']
60
content_name = content_path.rsplit('/', 1)[-1]
61
debian_network_conf = service.get_content(content_name)
62
debian_network_conf = encoding.get_as_string(debian_network_conf)
64
LOG.debug('network config content:\n%s' % debian_network_conf)
66
# TODO(alexpilotti): implement a proper grammar
67
m = re.search(r'iface eth0 inet static\s+'
68
r'address\s+(?P<address>[^\s]+)\s+'
69
r'netmask\s+(?P<netmask>[^\s]+)\s+'
70
r'broadcast\s+(?P<broadcast>[^\s]+)\s+'
71
r'gateway\s+(?P<gateway>[^\s]+)\s+'
72
r'dns\-nameservers\s+'
73
r'(?P<dnsnameservers>[^\r\n]+)\s+',
76
raise exception.CloudbaseInitException(
77
"network_config format not recognized")
80
network_adapters = osutils.get_network_adapters()
82
adapter_name = CONF.network_adapter
84
# configure with the specified one
85
for network_adapter in network_adapters:
86
if network_adapter[0] == adapter_name:
87
mac = network_adapter[1]
90
# configure with the first one
91
mac = network_adapters[0][1]
93
service_base.NetworkDetails(
99
m.group('dnsnameservers').strip().split(' ')
102
# ---- END deprecated code ----
104
# check NICs' type and save them by MAC
99
return (plugin_base.PLUGIN_EXECUTION_DONE, False)
101
# check and save NICs by MAC
102
network_adapters = osutils.get_network_adapters()
103
network_details = _preprocess_nics(network_details,
106
106
for nic in network_details:
107
if not isinstance(nic, service_base.NetworkDetails):
108
raise exception.CloudbaseInitException(
109
"invalid NetworkDetails object {!r}"
112
107
# assuming that the MAC address is unique
113
108
macnics[nic.mac] = nic
114
110
# try configuring all the available adapters
115
adapter_macs = [pair[1] for pair in
116
osutils.get_network_adapters()]
118
raise exception.CloudbaseInitException(
119
"no network adapters available")
111
adapter_macs = [pair[1] for pair in network_adapters]
121
112
reboot_required = False
122
113
configured = False
123
114
for mac in adapter_macs: