示例#1
0
def _add_nic(iface, nics):
    if not iface or iface == IFACE_TEMPLATE:
        return  # no information gathered
    LOG.debug("Found new interface: %s", iface)
    # Each missing detail is marked as None.
    nic = service_base.NetworkDetails(**iface)
    nics.append(nic)
示例#2
0
def _preprocess_nics(network_details, network_adapters):
    """Check NICs and fill missing data if possible."""
    # Initial checks.
    if not network_adapters:
        raise exception.CloudbaseInitException("no network adapters available")
    # Sort VM adapters by name (assuming that those
    # from the context are in correct order).
    # Do this for a better matching by order
    # if hardware address is missing.
    network_adapters = sorted(network_adapters, key=lambda arg: arg[0])
    refined_network_details = []  # store here processed interfaces
    # Check and update every NetworkDetails object.
    total = len(network_adapters)
    for nic in network_details:
        if not isinstance(nic, service_base.NetworkDetails):
            raise exception.CloudbaseInitException(
                "invalid NetworkDetails object {!r}".format(type(nic)))
        # Check requirements.
        final_status = True
        for fields, status in NET_REQUIRE.items():
            if not status:
                continue  # skip 'not required' entries
            if not isinstance(fields, tuple):
                fields = (fields, )
            final_status = any([getattr(nic, field) for field in fields])
            if not final_status:
                break
        address, netmask = nic.address, nic.netmask
        if final_status:
            # Additional check for info version.
            if not (address and netmask):
                final_status = nic.address6 and nic.netmask6
                if final_status:
                    address = address or network.address6_to_4_truncate(
                        nic.address6)
                    netmask = netmask or network.netmask6_to_4_truncate(
                        nic.netmask6)
        if not final_status:
            LOG.error("Incomplete NetworkDetails object %s", nic)
            continue
        # Complete hardware address if missing by selecting
        # the corresponding MAC in terms of naming, then ordering.
        if not nic.mac:
            # By name...
            macs = [
                adapter[1] for adapter in network_adapters
                if adapter[0] == nic.name
            ]
            mac = macs[0] if macs else None
            # ...or by order.
            idx = _name2idx(nic.name)
            if not mac and idx < total:
                mac = network_adapters[idx][1]
            nic = service_base.NetworkDetails(nic.name, mac, address,
                                              nic.address6, netmask,
                                              nic.netmask6, nic.broadcast,
                                              nic.gateway, nic.gateway6,
                                              nic.dnsnameservers)
        refined_network_details.append(nic)
    return refined_network_details
示例#3
0
    def get_network_details(self):
        """Return a list of NetworkDetails objects.

        With each object from that list, the corresponding
        NIC (by mac) can be statically configured.
        If no such object is present, then is believed that
        this is handled by DHCP (user didn't provide sufficient data).
        """
        network_details = []
        ncount = self._nic_count()
        # for every interface
        for iid in range(ncount):
            try:
                # get existing values
                mac = self._get_cache_data(MAC, iid=iid).upper()
                address = self._get_cache_data(ADDRESS, iid=iid)
                gateway = self._get_cache_data(GATEWAY, iid=iid)
                # try to find/predict and compute the rest
                try:
                    netmask = self._get_cache_data(NETMASK, iid=iid)
                except base.NotExistingMetadataException:
                    netmask = self._calculate_netmask(address, gateway)
                broadcast = self._compute_broadcast(address, netmask)
                # gather them as namedtuple objects
                details = base.NetworkDetails(
                    mac, address, netmask, broadcast, gateway,
                    self._get_cache_data(DNSNS, iid=iid).split(" "))
            except base.NotExistingMetadataException:
                LOG.debug("Incomplete NIC details")
            else:
                network_details.append(details)
        return network_details
示例#4
0
    def _convert_network_data(self):
        """Parses network_data and converts to NetworkDetails namedtuple."""
        network_data = self._get_network_data()

        # Create a template because namedtuples are immutable
        nic_template = dict.fromkeys(base.NetworkDetails._fields)

        nics = []
        dns_nameservers = self._get_dns_nameservers(network_data)
        for link in network_data.get('links', []):
            nic = AttributeDict(nic_template)
            # Must make mac uppercase to match windows adapter mac.
            nic.mac = link["ethernet_mac_address"].upper()
            nic.name = link["name"]
            nic.dnsnameservers = dns_nameservers
            for network in network_data.get('networks', []):
                # Each link can have multiple networks for ipv4 and ipv6.
                # Skip if they don't match.
                if network["link"] != link["id"]:
                    continue
                if network["type"] == "ipv4":
                    self._set_ipv4_network_details(network, nic)
                elif network["type"] == "ipv6":
                    self._set_ipv6_network_details(network, nic)
            LOG.debug('Appending NetworkDetails object: %s', nic.mac)
            nics.append(base.NetworkDetails(**nic))
        return nics
示例#5
0
 def _test_execute_missing_smth(self,
                                name=False,
                                mac=False,
                                address=False,
                                address6=False,
                                netmask=False,
                                netmask6=False,
                                gateway=False,
                                fail=False):
     ind = self._count - 1
     nic = self._network_details[ind]
     nic2 = service_base.NetworkDetails(
         None if name else nic.name, None if mac else nic.mac,
         None if address else nic.address,
         None if address6 else nic.address6,
         None if netmask else nic.netmask,
         None if netmask6 else nic.netmask6, nic.broadcast,
         None if gateway else nic.gateway,
         None if gateway else nic.gateway6, nic.dnsnameservers)
     self._network_details[ind] = nic2
     # Excluding address and gateway switches...
     if not fail:
         # Even this way, all adapters should be configured.
         missed_adapters = []
         extra_network_details = [nic]
     else:
         # Both name and MAC are missing, so we can't make the match.
         # Or other vital details.
         missed_adapters = [self._network_adapters[ind]]
         extra_network_details = []
     self._partial_test_execute(missed_adapters=missed_adapters,
                                extra_network_details=extra_network_details)
 def test_execute_missing_all(self):
     nic = self._network_details[0]
     nic = service_base.NetworkDetails(nic.name, "00" + nic.mac[2:],
                                       nic.address, nic.netmask,
                                       nic.broadcast, nic.gateway,
                                       nic.dnsnameservers)
     self._network_details[:] = [nic]
     self._partial_test_execute(missed_adapters=self._network_adapters)
示例#7
0
def _add_nic(iface, nics):
    if not iface:
        return
    details = [iface[key] for key in sorted(iface)]
    LOG.debug("Found new interface: %s", details)
    # each missing detail is marked as None
    nic = service_base.NetworkDetails(*details)
    nics.append(nic)
 def _setUp(self, same_names=True, wrong_names=False, no_macs=False):
     # Generate fake pairs of NetworkDetails objects and
     # local ethernet network adapters.
     iface_name = "Ethernet" if wrong_names else "eth"
     self._count = 3
     details_names = [
         "{}{}".format(iface_name, idx) for idx in range(self._count)
     ]
     if same_names:
         adapters_names = details_names[:]
     else:
         adapters_names = ["vm " + name for name in details_names]
     macs = ["54:EE:75:19:F4:61", "54:EE:75:19:F4:62", "54:EE:75:19:F4:63"]
     addresses = [
         "192.168.122.101",
         "192.168.103.104",
         "192.168.122.105",
     ]
     netmasks = [
         "255.255.255.0",
         "255.255.0.0",
         "255.255.255.128",
     ]
     broadcasts = [
         "192.168.122.255",
         "192.168.255.255",
         "192.168.122.127",
     ]
     gateways = [
         "192.168.122.1",
         "192.168.122.16",
         "192.168.122.32",
     ]
     dnsnses = [
         "8.8.8.8",
         "8.8.8.8 8.8.4.4",
         "8.8.8.8 0.0.0.0",
     ]
     self._network_adapters = []
     self._network_details = []
     for ind in range(self._count):
         adapter = (adapters_names[ind], macs[ind])
         nic = service_base.NetworkDetails(details_names[ind],
                                           None if no_macs else macs[ind],
                                           addresses[ind], netmasks[ind],
                                           broadcasts[ind], gateways[ind],
                                           dnsnses[ind].split())
         self._network_adapters.append(adapter)
         self._network_details.append(nic)
     # get the network config plugin
     self._network_plugin = networkconfig.NetworkConfigPlugin()
     # execution wrapper
     self._partial_test_execute = functools.partial(
         self._test_execute,
         network_adapters=self._network_adapters,
         network_details=self._network_details)
示例#9
0
 def _test_parse_nics(self, no_nics=False):
     nics = debiface.parse(self.data)
     if no_nics:
         self.assertFalse(nics)
         return
     # check what we've got
     nic0 = service_base.NetworkDetails(fake_json_response.NAME0,
                                        fake_json_response.MAC0.upper(),
                                        fake_json_response.ADDRESS0,
                                        fake_json_response.NETMASK0,
                                        fake_json_response.BROADCAST0,
                                        fake_json_response.GATEWAY0,
                                        fake_json_response.DNSNS0.split())
     nic1 = service_base.NetworkDetails(fake_json_response.NAME1, None,
                                        fake_json_response.ADDRESS1,
                                        fake_json_response.NETMASK1,
                                        fake_json_response.BROADCAST1,
                                        fake_json_response.GATEWAY1, None)
     self.assertEqual([nic0, nic1], nics)
 def _test_get_network_details(self,
                               mock_get_meta_data,
                               mock_get_content,
                               network_config=None,
                               content=None,
                               search_fail=False,
                               no_path=False):
     # mock obtained data
     mock_get_meta_data().get.return_value = network_config
     mock_get_content.return_value = content
     # actual tests
     if search_fail:
         ret = self._service.get_network_details()
         self.assertFalse(ret)
         return
     ret = self._service.get_network_details()
     mock_get_meta_data().get.assert_called_once_with("network_config")
     if network_config and not no_path:
         mock_get_content.assert_called_once_with("network")
     if not network_config:
         self.assertIsNone(ret)
         return
     if no_path:
         self.assertIsNone(ret)
         return
     # check returned NICs details
     nic1 = base.NetworkDetails(fake_json_response.NAME0,
                                fake_json_response.MAC0.upper(),
                                fake_json_response.ADDRESS0,
                                fake_json_response.NETMASK0,
                                fake_json_response.BROADCAST0,
                                fake_json_response.GATEWAY0,
                                fake_json_response.DNSNS0.split())
     nic2 = base.NetworkDetails(fake_json_response.NAME1, None,
                                fake_json_response.ADDRESS1,
                                fake_json_response.NETMASK1,
                                fake_json_response.BROADCAST1,
                                fake_json_response.GATEWAY1, None)
     self.assertEqual([nic1, nic2], ret)
示例#11
0
    def _test_parse_nics(self, no_nics=False):
        with testutils.LogSnatcher('cloudbaseinit.utils.'
                                   'debiface') as snatcher:
            nics = debiface.parse(self.data)

        if no_nics:
            expected_logging = 'Invalid Debian config to parse:'
            self.assertTrue(snatcher.output[0].startswith(expected_logging))
            self.assertFalse(nics)
            return
        # check what we've got
        nic0 = service_base.NetworkDetails(
            fake_json_response.NAME0, fake_json_response.MAC0.upper(),
            fake_json_response.ADDRESS0, fake_json_response.ADDRESS60,
            fake_json_response.NETMASK0, fake_json_response.NETMASK60,
            fake_json_response.BROADCAST0, fake_json_response.GATEWAY0,
            fake_json_response.GATEWAY60, fake_json_response.DNSNS0.split())
        nic1 = service_base.NetworkDetails(
            fake_json_response.NAME1, None, fake_json_response.ADDRESS1,
            fake_json_response.ADDRESS61, fake_json_response.NETMASK1,
            fake_json_response.NETMASK61, fake_json_response.BROADCAST1,
            fake_json_response.GATEWAY1, fake_json_response.GATEWAY61, None)
        self.assertEqual([nic0, nic1], nics)
示例#12
0
def _preprocess_nics(network_details, network_adapters):
    """Check NICs and fill missing data if possible."""
    # initial checks
    if not network_adapters:
        raise exception.CloudbaseInitException("no network adapters available")
    # Sort VM adapters by name (assuming that those
    # from the context are in correct order).
    network_adapters = sorted(network_adapters, key=lambda arg: arg[0])
    _network_details = []  # store here processed data
    # check and update every NetworkDetails object
    ind = 0
    total = len(network_adapters)
    for nic in network_details:
        if not isinstance(nic, service_base.NetworkDetails):
            raise exception.CloudbaseInitException(
                "invalid NetworkDetails object {!r}".format(type(nic)))
        # check requirements
        final_status = True
        for fields, status in NET_REQUIRE.items():
            if not status:
                continue  # skip 'not required' entries
            if not isinstance(fields, tuple):
                fields = (fields, )
            final_status = any([getattr(nic, field) for field in fields])
            if not final_status:
                LOG.error("Incomplete NetworkDetails object %s", nic)
                break
        if final_status:
            # Complete hardware address if missing by selecting
            # the corresponding MAC in terms of naming, then ordering.
            if not nic.mac:
                mac = None
                # by name
                macs = [
                    adapter[1] for adapter in network_adapters
                    if adapter[0] == nic.name
                ]
                mac = macs[0] if macs else None
                # or by order
                if not mac and ind < total:
                    mac = network_adapters[ind][1]
                nic = service_base.NetworkDetails(nic.name, mac, nic.address,
                                                  nic.netmask, nic.broadcast,
                                                  nic.gateway,
                                                  nic.dnsnameservers)
            _network_details.append(nic)
        ind += 1
    return _network_details
示例#13
0
def _get_nic_details():
    details = base.NetworkDetails(MAC, ADDRESS, NETMASK, BROADCAST, GATEWAY,
                                  DNSNS.split(" "))
    return details
示例#14
0
def _get_nic_details(iid=0):
    details = base.NetworkDetails(opennebulaservice.IF_FORMAT.format(iid=iid),
                                  MAC, ADDRESS, NETMASK, BROADCAST, GATEWAY,
                                  DNSNS.split(" "))
    return details
    def _test_execute(self,
                      mock_get_os_utils,
                      search_result=mock.MagicMock(),
                      no_adapter_name=False,
                      no_adapters=False,
                      using_content=0,
                      details_list=None,
                      missing_content_path=False):
        fake_adapter = ("fake_name_0", "fake_mac_0")
        mock_service = mock.MagicMock()
        mock_osutils = mock.MagicMock()
        mock_ndetails = mock.Mock()
        re.search = mock.MagicMock(return_value=search_result)
        fake_shared_data = 'fake shared data'
        network_config = self.fake_data['network_config']
        if not details_list:
            details_list = [None] * 6
            details_list[0] = fake_adapter[1]  # set MAC for matching
        if no_adapter_name:  # nothing provided in the config file
            CONF.set_override("network_adapter", None)
        else:
            CONF.set_override("network_adapter", fake_adapter[0])
        mock_osutils.get_network_adapters.return_value = [
            fake_adapter,
            # and other adapters
            ("name1", "mac1"),
            ("name2", "mac2")
        ]
        mock_get_os_utils.return_value = mock_osutils
        mock_osutils.set_static_network_config.return_value = False
        # service method setup
        methods = ["get_network_config", "get_content", "get_network_details"]
        for method in methods:
            mock_method = getattr(mock_service, method)
            mock_method.return_value = None
        if using_content == 1:
            mock_service.get_network_config.return_value = network_config
            mock_service.get_content.return_value = search_result

        elif using_content == 2:
            mock_service.get_network_details.return_value = [mock_ndetails]
        # actual tests
        if search_result is None and using_content == 1:
            self.assertRaises(exception.CloudbaseInitException,
                              self._network_plugin.execute, mock_service,
                              fake_shared_data)
            return
        if no_adapters:
            mock_osutils.get_network_adapters.return_value = []
            self.assertRaises(exception.CloudbaseInitException,
                              self._network_plugin.execute, mock_service,
                              fake_shared_data)
            return
        attrs = [
            "address",
            "netmask",
            "broadcast",
            "gateway",
            "dnsnameservers",
        ]
        if using_content == 0:
            response = self._network_plugin.execute(mock_service,
                                                    fake_shared_data)
        elif using_content == 1:
            if missing_content_path:
                mock_service.get_network_config.return_value.pop(
                    "content_path", None)
            response = self._network_plugin.execute(mock_service,
                                                    fake_shared_data)
            if not missing_content_path:
                mock_service.get_network_config.assert_called_once_with()
                mock_service.get_content.assert_called_once_with(
                    network_config['content_path'])
                adapters = mock_osutils.get_network_adapters()
                if CONF.network_adapter:
                    mac = [
                        pair[1] for pair in adapters if pair == fake_adapter
                    ][0]
                else:
                    mac = adapters[0][1]
                (address, netmask, broadcast, gateway,
                 dnsnameserver) = map(search_result.group, attrs)
                dnsnameservers = dnsnameserver.strip().split(" ")
        elif using_content == 2:
            with self.assertRaises(exception.CloudbaseInitException):
                self._network_plugin.execute(mock_service, fake_shared_data)
            mock_service.get_network_details.reset_mock()
            mock_ndetails = service_base.NetworkDetails(*details_list)
            mock_service.get_network_details.return_value = [mock_ndetails]
            response = self._network_plugin.execute(mock_service,
                                                    fake_shared_data)
            mock_service.get_network_details.assert_called_once_with()
            mac = mock_ndetails.mac
            (address, netmask, broadcast, gateway,
             dnsnameservers) = map(lambda attr: getattr(mock_ndetails, attr),
                                   attrs)
        if using_content in (1, 2) and not missing_content_path:
            mock_osutils.set_static_network_config.assert_called_once_with(
                mac, address, netmask, broadcast, gateway, dnsnameservers)
        self.assertEqual((plugin_base.PLUGIN_EXECUTION_DONE, False), response)
示例#16
0
    def execute(self, service, shared_data):
        # FIXME(cpoieana): `network_config` is deprecated
        # * refactor all services by providing NetworkDetails objects *
        # Also, the old method is not supporting multiple NICs.

        osutils = osutils_factory.get_os_utils()
        network_details = service.get_network_details()
        if not network_details:
            network_config = service.get_network_config()
            if not network_config:
                return (plugin_base.PLUGIN_EXECUTION_DONE, False)

        # ---- BEGIN deprecated code ----
        if not network_details:
            if 'content_path' not in network_config:
                return (plugin_base.PLUGIN_EXECUTION_DONE, False)

            content_path = network_config['content_path']
            content_name = content_path.rsplit('/', 1)[-1]
            debian_network_conf = service.get_content(content_name)

            LOG.debug('network config content:\n%s' % debian_network_conf)

            # TODO(alexpilotti): implement a proper grammar
            m = re.search(
                r'iface eth0 inet static\s+'
                r'address\s+(?P<address>[^\s]+)\s+'
                r'netmask\s+(?P<netmask>[^\s]+)\s+'
                r'broadcast\s+(?P<broadcast>[^\s]+)\s+'
                r'gateway\s+(?P<gateway>[^\s]+)\s+'
                r'dns\-nameservers\s+'
                r'(?P<dnsnameservers>[^\r\n]+)\s+', debian_network_conf)
            if not m:
                raise exception.CloudbaseInitException(
                    "network_config format not recognized")

            mac = None
            network_adapters = osutils.get_network_adapters()
            if network_adapters:
                adapter_name = CONF.network_adapter
                if adapter_name:
                    # configure with the specified one
                    for network_adapter in network_adapters:
                        if network_adapter[0] == adapter_name:
                            mac = network_adapter[1]
                            break
                else:
                    # configure with the first one
                    mac = network_adapters[0][1]
            network_details = [
                service_base.NetworkDetails(
                    mac, m.group('address'), m.group('netmask'),
                    m.group('broadcast'), m.group('gateway'),
                    m.group('dnsnameservers').strip().split(' '))
            ]
        # ---- END deprecated code ----

        # check NICs' type and save them by MAC
        macnics = {}
        for nic in network_details:
            if not isinstance(nic, service_base.NetworkDetails):
                raise exception.CloudbaseInitException(
                    "invalid NetworkDetails object {!r}".format(type(nic)))
            # assuming that the MAC address is unique
            macnics[nic.mac] = nic
        # try configuring all the available adapters
        adapter_macs = [pair[1] for pair in osutils.get_network_adapters()]
        if not adapter_macs:
            raise exception.CloudbaseInitException(
                "no network adapters available")
        # configure each one
        reboot_required = False
        configured = False
        for mac in adapter_macs:
            nic = macnics.pop(mac, None)
            if not nic:
                LOG.warn("Missing details for adapter %s", mac)
                continue
            LOG.info("Configuring network adapter %s", mac)
            reboot = osutils.set_static_network_config(mac, nic.address,
                                                       nic.netmask,
                                                       nic.broadcast,
                                                       nic.gateway,
                                                       nic.dnsnameservers)
            reboot_required = reboot or reboot_required
            configured = True
        for mac in macnics:
            LOG.warn("Details not used for adapter %s", mac)
        if not configured:
            LOG.error("No adapters were configured")

        return (plugin_base.PLUGIN_EXECUTION_DONE, reboot_required)