示例#1
0
    def get_network_details_v2(self):
        network_data = self._get_network_data()
        if not network_data:
            return

        version = network_data.get("version")
        if version != 1:
            raise exception.CloudbaseInitException(
                'Unsupported MAAS network metadata version: %s' % version)

        links = []
        networks = []
        services = []

        config = network_data.get("config", [])
        for config_item in config:
            link, link_networks, service = self._parse_config_item(config_item)
            if link:
                links.append(link)
            if link_networks:
                networks.extend(link_networks),
            if service:
                services.append(service)

        self._enable_bond_physical_links(links)

        return network_model.NetworkDetailsV2(links=links,
                                              networks=networks,
                                              services=services)
示例#2
0
 def _parse_nameserver_config_item(self, item):
     return network_model.NetworkDetailsV2(
         links=[],
         networks=[],
         services=[
             network_model.NameServerService(addresses=item.get(
                 'address', []),
                                             search=item.get('search'))
         ])
示例#3
0
    def get_network_details_v2(self):
        network_data = self._get_network_data()

        links = self._parse_network_data_links(network_data.get("links", []))
        networks = self._parse_network_data_networks(
            network_data.get("networks", []))
        services = self._parse_network_data_services(
            network_data.get("services", []))

        return network_model.NetworkDetailsV2(links=links,
                                              networks=networks,
                                              services=services)
示例#4
0
    def _parse_bond_config_item(self, item):
        if not item.get('name'):
            LOG.warning("Bond does not have a name.")
            return

        bond_params = item.get('params')
        if not bond_params:
            LOG.warning("Bond does not have parameters")
            return

        bond_mode = bond_params.get('bond-mode')
        if bond_mode not in network_model.AVAILABLE_BOND_TYPES:
            raise exception.CloudbaseInitException(
                "Unsupported bond mode: %s" % bond_mode)

        bond_lacp_rate = None
        if bond_mode == network_model.BOND_TYPE_8023AD:
            bond_lacp_rate = bond_params.get('bond-lacp-rate')
            if (bond_lacp_rate and bond_lacp_rate
                    not in network_model.AVAILABLE_BOND_LACP_RATES):
                raise exception.CloudbaseInitException(
                    "Unsupported bond lacp rate: %s" % bond_lacp_rate)

        bond_xmit_hash_policy = bond_params.get('xmit_hash_policy')
        if (bond_xmit_hash_policy and bond_xmit_hash_policy
                not in network_model.AVAILABLE_BOND_LB_ALGORITHMS):
            raise exception.CloudbaseInitException(
                "Unsupported bond hash policy: %s" % bond_xmit_hash_policy)

        bond_interfaces = item.get('bond_interfaces')

        bond = network_model.Bond(
            members=bond_interfaces,
            type=bond_mode,
            lb_algorithm=bond_xmit_hash_policy,
            lacp_rate=bond_lacp_rate,
        )

        link = network_model.Link(id=item.get('name'),
                                  name=item.get('name'),
                                  type=network_model.LINK_TYPE_BOND,
                                  enabled=True,
                                  mac_address=item.get('mac_address'),
                                  mtu=item.get('mtu'),
                                  bond=bond,
                                  vlan_link=None,
                                  vlan_id=None)

        return network_model.NetworkDetailsV2(links=[link],
                                              networks=self._parse_subnets(
                                                  item.get("subnets"),
                                                  link.name),
                                              services=[])
    def get_network_details_v2(self):
        try:
            network_data = self._get_network_data()
        except base.NotExistingMetadataException:
            LOG.info("V2 network metadata not found")
            return

        links = self._parse_network_data_links(network_data.get("links", []))
        networks = self._parse_network_data_networks(
            network_data.get("networks", []))
        services = self._parse_network_data_services(
            network_data.get("services", []))

        return network_model.NetworkDetailsV2(links=links,
                                              networks=networks,
                                              services=services)
示例#6
0
    def _parse_physical_config_item(self, item):
        if not item.get('name'):
            LOG.warning("Physical NIC does not have a name.")
            return

        link = network_model.Link(id=item.get('name'),
                                  name=item.get('name'),
                                  type=network_model.LINK_TYPE_PHYSICAL,
                                  enabled=True,
                                  mac_address=item.get('mac_address'),
                                  mtu=item.get('mtu'),
                                  bond=None,
                                  vlan_link=None,
                                  vlan_id=None)

        return network_model.NetworkDetailsV2(links=[link],
                                              networks=self._parse_subnets(
                                                  item.get("subnets"),
                                                  link.name),
                                              services=[])
示例#7
0
    def parse(self, network_config):
        links = []
        networks = []
        services = []

        if not network_config:
            LOG.warning("Network configuration is empty")
            return

        if not isinstance(network_config, list):
            LOG.warning("Network config '%s' is not a list.", network_config)
            return

        for network_config_item in network_config:
            if not isinstance(network_config_item, dict):
                LOG.warning("Network config item '%s' is not a dictionary",
                            network_config_item)
                continue

            net_conf_type = network_config_item.get("type")
            if net_conf_type not in self.SUPPORTED_NETWORK_CONFIG_TYPES:
                LOG.warning("Network config type '%s' is not supported",
                            net_conf_type)
                continue

            net_details = (self._get_network_config_parser(net_conf_type)(
                network_config_item))

            if net_details:
                links += net_details.links
                networks += net_details.networks
                services += net_details.services

        return network_model.NetworkDetailsV2(links=links,
                                              networks=networks,
                                              services=services)
    def _get_network_details_v2(self):
        links = []
        link1 = network_model.Link(id=mock.sentinel.link_id1,
                                   name=mock.sentinel.link_name1,
                                   type=network_model.LINK_TYPE_PHYSICAL,
                                   enabled=mock.sentinel.link_enabled1,
                                   mac_address=mock.sentinel.link_mac1,
                                   mtu=mock.sentinel.link_mtu1,
                                   bond=None,
                                   vlan_link=None,
                                   vlan_id=None)
        links.append(link1)

        bond1 = network_model.Bond(members=[mock.sentinel.link_id1],
                                   type=mock.sentinel.bond_type1,
                                   lb_algorithm=mock.sentinel.bond_lb_algo1,
                                   lacp_rate=mock.sentinel.lacp_rate1)

        bond_link1 = network_model.Link(
            id=mock.sentinel.bond_link_id1,
            name=mock.sentinel.bond_link_name1,
            type=network_model.LINK_TYPE_BOND,
            enabled=mock.sentinel.bond_link_enabled1,
            mac_address=mock.sentinel.bond_link_mac1,
            mtu=mock.sentinel.bond_link_mtu1,
            bond=bond1,
            vlan_link=None,
            vlan_id=None)
        links.append(bond_link1)

        vlan_link1 = network_model.Link(
            id=mock.sentinel.vlan_link_id1,
            name=mock.sentinel.vlan_link_name1,
            type=network_model.LINK_TYPE_VLAN,
            enabled=mock.sentinel.vlan_link_enabled1,
            mac_address=mock.sentinel.vlan_link_mac1,
            mtu=mock.sentinel.vlan_link_mtu1,
            bond=None,
            vlan_link=mock.sentinel.bond_link_id1,
            vlan_id=mock.sentinel.vlan_id1)
        links.append(vlan_link1)

        networks = []
        route1 = network_model.Route(network_cidr=mock.sentinel.network_cidr1,
                                     gateway=mock.sentinel.gateway1)

        route2 = network_model.Route(network_cidr=mock.sentinel.network_cidr2,
                                     gateway=mock.sentinel.gateway2)

        network1 = network_model.Network(
            link=mock.sentinel.link_id1,
            address_cidr=mock.sentinel.address_cidr1,
            dns_nameservers=mock.sentinel.network_dns_list1,
            routes=[route1, route2])
        networks.append(network1)

        services = []
        service1 = network_model.NameServerService(
            addresses=[mock.sentinel.dns1, mock.sentinel.dns3],
            search=mock.sentinel.dns_search1)
        services.append(service1)

        return network_model.NetworkDetailsV2(links=links,
                                              networks=networks,
                                              services=services)
class TestNoCloudNetworkConfigV1Parser(unittest.TestCase):
    def setUp(self):
        module = importlib.import_module(MODULE_PATH)
        self._parser = module.NoCloudNetworkConfigV1Parser()
        self.snatcher = testutils.LogSnatcher(MODULE_PATH)

    @ddt.data(
        ('', ('Network configuration is empty', None)),
        ('{t: 1}', ("Network config '{'t': 1}' is not a list", None)),
        ('["1"]', ("Network config item '1' is not a dictionary",
                   nm.NetworkDetailsV2(links=[], networks=[], services=[]))),
        ('[{"type": "router"}]',
         ("Network config type 'router' is not supported",
          nm.NetworkDetailsV2(links=[], networks=[], services=[]))))
    @ddt.unpack
    def test_parse_empty_result(self, input, expected_result):

        with self.snatcher:
            result = self._parser.parse(serialization.parse_json_yaml(input))

        self.assertEqual(True, expected_result[0] in self.snatcher.output[0])
        self.assertEqual(result, expected_result[1])

    def test_network_details_v2(self):
        expected_bond = nm.Bond(
            members=["gbe0", "gbe1"],
            type=nm.BOND_TYPE_ACTIVE_BACKUP,
            lb_algorithm=None,
            lacp_rate=None,
        )
        expected_link_bond = nm.Link(
            id='bond0',
            name='bond0',
            type=nm.LINK_TYPE_BOND,
            enabled=True,
            mac_address="52:54:00:12:34:00",
            mtu=1450,
            bond=expected_bond,
            vlan_link=None,
            vlan_id=None,
        )
        expected_link = nm.Link(
            id='interface0',
            name='interface0',
            type=nm.LINK_TYPE_PHYSICAL,
            enabled=True,
            mac_address="52:54:00:12:34:00",
            mtu=1450,
            bond=None,
            vlan_link=None,
            vlan_id=None,
        )
        expected_link_vlan = nm.Link(
            id='vlan0',
            name='vlan0',
            type=nm.LINK_TYPE_VLAN,
            enabled=True,
            mac_address="52:54:00:12:34:00",
            mtu=1450,
            bond=None,
            vlan_link='eth1',
            vlan_id=150,
        )
        expected_network = nm.Network(
            link='interface0',
            address_cidr='192.168.1.10/24',
            dns_nameservers=['192.168.1.11'],
            routes=[nm.Route(network_cidr='0.0.0.0/0', gateway="192.168.1.1")])

        expected_network_bond = nm.Network(
            link='bond0',
            address_cidr='192.168.1.10/24',
            dns_nameservers=['192.168.1.11'],
            routes=[],
        )

        expected_network_vlan = nm.Network(
            link='vlan0',
            address_cidr='192.168.1.10/24',
            dns_nameservers=['192.168.1.11'],
            routes=[],
        )
        expected_nameservers = nm.NameServerService(
            addresses=['192.168.23.2', '8.8.8.8'], search='acme.local')

        parser_data = """
           - type: physical
             name: interface0
             mac_address: "52:54:00:12:34:00"
             mtu: 1450
             subnets:
                - type: static
                  address: 192.168.1.10
                  netmask: 255.255.255.0
                  gateway: 192.168.1.1
                  dns_nameservers:
                    - 192.168.1.11
           - type: bond
             name: bond0
             bond_interfaces:
               - gbe0
               - gbe1
             mac_address: "52:54:00:12:34:00"
             params:
               bond-mode: active-backup
               bond-lacp-rate: false
             mtu: 1450
             subnets:
                - type: static
                  address: 192.168.1.10
                  netmask: 255.255.255.0
                  dns_nameservers:
                    - 192.168.1.11
           - type: vlan
             name: vlan0
             vlan_link: eth1
             vlan_id: 150
             mac_address: "52:54:00:12:34:00"
             mtu: 1450
             subnets:
                - type: static
                  address: 192.168.1.10
                  netmask: 255.255.255.0
                  dns_nameservers:
                    - 192.168.1.11
           - type: nameserver
             address:
               - 192.168.23.2
               - 8.8.8.8
             search: acme.local
        """

        result = self._parser.parse(serialization.parse_json_yaml(parser_data))

        self.assertEqual(result.links[0], expected_link)
        self.assertEqual(result.networks[0], expected_network)

        self.assertEqual(result.links[1], expected_link_bond)
        self.assertEqual(result.networks[1], expected_network_bond)

        self.assertEqual(result.links[2], expected_link_vlan)
        self.assertEqual(result.networks[2], expected_network_vlan)

        self.assertEqual(result.services[0], expected_nameservers)