~lihaosz/cloudbase-init/cloudbase-init

« back to all changes in this revision

Viewing changes to cloudbaseinit/plugins/windows/networkconfig.py

  • Committer: Gerrit Code Review
  • Author(s): Jenkins
  • Date: 2014-12-24 14:48:56 UTC
  • mfrom: (217.1.1)
  • Revision ID: git-v1:07b6cbd77598be3571aada3ab0187e3dfcf6c414
Merge "Remove deprecated static network config method"

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#    under the License.
14
14
 
15
15
 
16
 
import re
17
 
 
18
 
from oslo.config import cfg
19
 
 
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
26
21
 
27
22
 
28
23
LOG = logging.getLogger(__name__)
29
24
 
30
 
opts = [
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.'),
34
 
]
35
 
 
36
 
CONF = cfg.CONF
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.
 
27
NET_REQUIRE = {
 
28
    ("name", "mac"): True,
 
29
    "address": True,
 
30
    "netmask": True,
 
31
    "broadcast": False,    # currently not used
 
32
    "gateway": False,
 
33
    "dnsnameservers": False
 
34
}
 
35
 
 
36
 
 
37
def _preprocess_nics(network_details, network_adapters):
 
38
    """Check NICs and fill missing data if possible."""
 
39
    # initial checks
 
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
 
48
    ind = 0
 
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}"
 
54
                .format(type(nic))
 
55
            )
 
56
        # check requirements
 
57
        final_status = True
 
58
        for fields, status in NET_REQUIRE.items():
 
59
            if not status:
 
60
                continue    # skip 'not required' entries
 
61
            if not isinstance(fields, tuple):
 
62
                fields = (fields,)
 
63
            final_status = any([getattr(nic, field) for field in fields])
 
64
            if not final_status:
 
65
                LOG.error("Incomplete NetworkDetails object %s", nic)
 
66
                break
 
67
        if final_status:
 
68
            # Complete hardware address if missing by selecting
 
69
            # the corresponding MAC in terms of naming, then ordering.
 
70
            if not nic.mac:
 
71
                mac = None
 
72
                # by name
 
73
                macs = [adapter[1] for adapter in network_adapters
 
74
                        if adapter[0] == nic.name]
 
75
                mac = macs[0] if macs else None
 
76
                # or by order
 
77
                if not mac and ind < total:
 
78
                    mac = network_adapters[ind][1]
 
79
                nic = service_base.NetworkDetails(
 
80
                    nic.name,
 
81
                    mac,
 
82
                    nic.address,
 
83
                    nic.netmask,
 
84
                    nic.broadcast,
 
85
                    nic.gateway,
 
86
                    nic.dnsnameservers
 
87
                )
 
88
            _network_details.append(nic)
 
89
        ind += 1
 
90
    return _network_details
38
91
 
39
92
 
40
93
class NetworkConfigPlugin(plugin_base.BasePlugin):
41
94
 
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.
46
 
 
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)
53
 
 
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)
58
 
 
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)
63
 
 
64
 
            LOG.debug('network config content:\n%s' % debian_network_conf)
65
 
 
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+',
74
 
                          debian_network_conf)
75
 
            if not m:
76
 
                raise exception.CloudbaseInitException(
77
 
                    "network_config format not recognized")
78
 
 
79
 
            mac = None
80
 
            network_adapters = osutils.get_network_adapters()
81
 
            if network_adapters:
82
 
                adapter_name = CONF.network_adapter
83
 
                if adapter_name:
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]
88
 
                            break
89
 
                else:
90
 
                    # configure with the first one
91
 
                    mac = network_adapters[0][1]
92
 
            network_details = [
93
 
                service_base.NetworkDetails(
94
 
                    mac,
95
 
                    m.group('address'),
96
 
                    m.group('netmask'),
97
 
                    m.group('broadcast'),
98
 
                    m.group('gateway'),
99
 
                    m.group('dnsnameservers').strip().split(' ')
100
 
                )
101
 
            ]
102
 
        # ---- END deprecated code ----
103
 
 
104
 
        # check NICs' type and save them by MAC
 
99
            return (plugin_base.PLUGIN_EXECUTION_DONE, False)
 
100
 
 
101
        # check and save NICs by MAC
 
102
        network_adapters = osutils.get_network_adapters()
 
103
        network_details = _preprocess_nics(network_details,
 
104
                                           network_adapters)
105
105
        macnics = {}
106
106
        for nic in network_details:
107
 
            if not isinstance(nic, service_base.NetworkDetails):
108
 
                raise exception.CloudbaseInitException(
109
 
                    "invalid NetworkDetails object {!r}"
110
 
                    .format(type(nic))
111
 
                )
112
107
            # assuming that the MAC address is unique
113
108
            macnics[nic.mac] = nic
 
109
 
114
110
        # try configuring all the available adapters
115
 
        adapter_macs = [pair[1] for pair in
116
 
                        osutils.get_network_adapters()]
117
 
        if not adapter_macs:
118
 
            raise exception.CloudbaseInitException(
119
 
                "no network adapters available")
120
 
        # configure each one
 
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: