def _dp_parser_v2(logger, acls_conf, dps_conf, routers_conf, vlans_conf): dps = [] vid_dp = {} for identifier, dp_conf in list(dps_conf.items()): try: dp = DP(identifier, dp_conf) dp.sanity_check() dp_id = dp.dp_id vlans = {} for vid, vlan_conf in list(vlans_conf.items()): vlans[vid] = VLAN(vid, dp_id, vlan_conf) acls = [] for acl_ident, acl_conf in list(acls_conf.items()): acls.append((acl_ident, ACL(acl_ident, acl_conf))) routers = [] for router_ident, router_conf in list(routers_conf.items()): routers.append((router_ident, Router(router_ident, router_conf))) if routers: assert len(routers) == 1, 'only one router supported' router_ident, router = routers[0] assert set(router.vlans) == set( vlans.keys()), 'only global routing supported' dp.add_router(router_ident, router) ports_conf = dp_conf.pop('interfaces', {}) ports = {} # 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 = port_parser(dp_id, port_num, port_conf, vlans) ports[port_num] = port if port.native_vlan is not None: vlan = vlans[port.native_vlan] port.native_vlan = vlan.vid _dp_add_vlan(vid_dp, dp, vlan) if port.tagged_vlans is not None: tagged_vids = [] for v_identifier in port.tagged_vlans: vlan = vlans[v_identifier] tagged_vids.append(vlan.vid) _dp_add_vlan(vid_dp, dp, vlan) port.tagged_vlans = tagged_vids except AssertionError as err: logger.exception('Error in config file: %s', err) return None for port in list(ports.values()): dp.add_port(port) for acl_ident, acl in acls: dp.add_acl(acl_ident, acl) dps.append(dp) return dps
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 = [ _get_vlan_by_identifier(dp_id, v_identifier, vlans) for v_identifier in port.tagged_vlans ] port.tagged_vlans = port_tagged_vlans for vlan in port.tagged_vlans: vlan.add_tagged(port) 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