예제 #1
0
def _dp_parser_v2(logger, acls_conf, dps_conf, meters_conf, routers_conf,
                  vlans_conf):
    dps = []
    vid_dp = collections.defaultdict(set)

    def _get_vlan_by_identifier(dp_id, vlan_ident, vlans):
        if vlan_ident in vlans:
            return vlans[vlan_ident]
        for vlan in list(vlans.values()):
            if int(vlan_ident) == vlan.vid:
                return vlan
        try:
            vid = int(vlan_ident, 0)
        except ValueError:
            assert False, 'VLAN VID value (%s) is invalid' % vlan_ident

        return vlans.setdefault(vlan_ident, VLAN(vid, dp_id))

    def _dp_add_vlan(dp, vlan):
        if vlan not in dp.vlans:
            dp.add_vlan(vlan)
            vid_dp[vlan.vid].add(dp.name)

            if len(vid_dp[vlan.vid]) > 1:
                assert not vlan.bgp_routerid, (
                    'DPs %s sharing a BGP speaker VLAN is unsupported' %
                    (str.join(', ', vid_dp[vlan.vid])))

    def _dp_parse_port(dp_id, p_identifier, port_conf, vlans):
        port = Port(p_identifier, port_conf)

        if port.native_vlan is not None:
            v_identifier = port.native_vlan
            vlan = _get_vlan_by_identifier(dp_id, v_identifier, vlans)
            port.native_vlan = vlan
            vlan.add_untagged(port)
        port_tagged_vlans = []
        for v_identifier in port.tagged_vlans:
            vlan = _get_vlan_by_identifier(dp_id, v_identifier, vlans)
            port_tagged_vlans.append(vlan)
            vlan.add_tagged(port)
        port.tagged_vlans = port_tagged_vlans

        for vlan in port.vlans():
            _dp_add_vlan(dp, vlan)

        return port

    def _dp_add_ports(dp, dp_conf, dp_id, vlans):
        ports_conf = dp_conf.pop('interfaces', {})
        # as users can config port vlan by using vlan name, we store vid in
        # Port instance instead of vlan name for data consistency
        for port_num, port_conf in list(ports_conf.items()):
            port = _dp_parse_port(dp_id, port_num, port_conf, vlans)
            dp.add_port(port)

    try:
        for identifier, dp_conf in list(dps_conf.items()):
            dp = DP(identifier, dp_conf)
            dp.sanity_check()
            dp_id = dp.dp_id

            vlans = {}
            for vlan_ident, vlan_conf in list(vlans_conf.items()):
                vlans[vlan_ident] = VLAN(vlan_ident, dp_id, vlan_conf)
            acls = []
            for acl_ident, acl_conf in list(acls_conf.items()):
                acls.append((acl_ident, ACL(acl_ident, acl_conf)))
            for router_ident, router_conf in list(routers_conf.items()):
                router = Router(router_ident, router_conf)
                dp.add_router(router_ident, router)
            for meter_ident, meter_conf in list(meters_conf.items()):
                dp.meters[meter_ident] = Meter(meter_ident, meter_conf)
            _dp_add_ports(dp, dp_conf, dp_id, vlans)
            for acl_ident, acl in acls:
                dp.add_acl(acl_ident, acl)
            dps.append(dp)

        for dp in dps:
            dp.finalize_config(dps)
        for dp in dps:
            dp.resolve_stack_topology(dps)

    except AssertionError as err:
        logger.exception('Error in config file: %s', err)
        return None

    return dps