def add_port(self, port_num, port_conf=None): # add port specific vlans or fall back to defaults port_conf = copy.copy(port_conf) if port_conf else {} port = self.ports.setdefault(port_num, Port(port_num, port_conf)) port_conf.setdefault('mirror', None) if port_conf['mirror'] is not None: from_port_num = port_conf['mirror'] self.mirror_from_port[from_port_num] = port_num # other configuration entries ignored. return # add native vlan port_conf.setdefault('native_vlan', None) if port_conf['native_vlan'] is not None: vid = port_conf['native_vlan'] if vid not in self.vlans: self.vlans[vid] = VLAN(vid) self.vlans[vid].untagged.append(self.ports[port_num]) # add vlans port_conf.setdefault('tagged_vlans', []) for vid in port_conf['tagged_vlans']: if vid not in self.vlans: self.vlans[vid] = VLAN(vid) self.vlans[vid].tagged.append(port) # add ACL port_conf.setdefault('acl_in', None) if port_conf['acl_in'] is not None: self.acl_in[port_num] = port_conf['acl_in']
def process_chunk(chunk): line = chunk[0] commands = [] if "vlan" in line: vlan = VLAN(chunk, iface_map) commands = vlan.generate_junos() elif "interface ve" in line: ve = VE(chunk) elif "interface ethernet" in line: iface = INTERFACE(chunk) # print(iface) elif "lag" in line: lag = LAG(chunk, iface_map) commands = lag.generate_junos() for c in commands: print(c) elif "snmp-server" in line: snmp = SNMP(chunk) elif "router ospf" in line: ospf = OSPF(chunk, debug=0) commands = ospf.generate_junos() elif "router bgp" in line: bgp = BGP(chunk) commands = bgp.generate_junos() return commands
def get_vlans(self, host): """docstring""" self.db_print('getVLANs') replies = [] var_bind_table = Crawler.snmp.walk(host.ip, self.oid.vlans) for var_bind_table_row in var_bind_table: for name, val in var_bind_table_row: #print('%s = %s' % (name.prettyPrint(), val.prettyPrint())) if int(val) == 1: replies.append(name) #print('vlan ' + str(name) + ' is operational') for reply in replies: vlan = VLAN() vlan.number = int(str(reply).split('.')[-1]) if vlan.number not in self.vlans: self.vlans[str(vlan.number)] = { 'hosts': [] } # print(vlan.number) #self.vlans.append(vlan) print('vlans:') print(self.vlans)
def test_generate_junos(self): """ Test the function generate_junos in the VLAN class """ # Define a static map of interfaces iface_map = {"eth 1/1": "et-1/0/1"} chunk = [ "vlan 2 name TEST", "untagged ethe 1/1", "router-interface ve 2" ] result = ["set vlans TEST", "set vlans TEST vlan-id 2"] vlan = VLAN(chunk, iface_map) commands = vlan.generate_junos() self.assertEqual(commands, result)
def port_parser(dp_id, p_identifier, port_conf, vlans): port = Port(p_identifier, port_conf) if port.mirror is not None: # ignore other config return port if port.native_vlan is not None: v_identifier = port.native_vlan vlan = vlans.setdefault(v_identifier, VLAN(v_identifier, dp_id)) vlan.untagged.append(port) for v_identifier in port.tagged_vlans: vlan = vlans.setdefault(v_identifier, VLAN(v_identifier, dp_id)) vlan.tagged.append(port) return port
def _dp_parser_v1(conf, config_file, logname): logger = get_logger(logname) config_path = _dp_config_path(config_file) # TODO: warn when the configuration contains meaningless elements # they are probably typos if 'dp_id' not in conf: logger.error('dp_id not configured in file %s', config_file) dp_id = conf['dp_id'] dp = DP(dp_id, conf) interfaces_conf = conf.pop('interfaces', {}) vlans_conf = conf.pop('vlans', {}) acls_conf = conf.pop('acls', {}) logger.info(str(dp)) vlans = {} for vid, vlan_conf in vlans_conf.iteritems(): vlans[vid] = VLAN(vid, dp_id, vlan_conf) for port_num, port_conf in interfaces_conf.iteritems(): dp.add_port(port_parser(dp_id, port_num, port_conf, vlans)) for acl_num, acl_conf in acls_conf.iteritems(): dp.add_acl(acl_num, acl_conf) for vlan in vlans.itervalues(): dp.add_vlan(vlan) try: dp.sanity_check() except AssertionError as err: logger.exception('Error in config file: %s', err) return None return ({config_path: config_file_hash(config_path)}, [dp])
def _dp_parser_v2(conf, config_file, logname): logger = get_logger(logname) config_path = _dp_config_path(config_file) config_hashes = {} dps_conf = {} vlans_conf = {} acls_conf = {} if not _dp_include(config_hashes, None, config_path, dps_conf, vlans_conf, acls_conf, logname): logger.critical('error found while loading config file: %s', config_path) return None if not dps_conf: logger.critical('dps not configured in file: %s', config_path) return None dps = [] vid_dp = {} for identifier, dp_conf in dps_conf.iteritems(): ports_conf = dp_conf.pop('interfaces', {}) dp = DP(identifier, dp_conf) dp.sanity_check() dp_id = dp.dp_id vlans = {} ports = {} for vid, vlan_conf in vlans_conf.iteritems(): vlans[vid] = VLAN(vid, dp_id, vlan_conf) try: for port_num, port_conf in ports_conf.iteritems(): port = port_parser(dp_id, port_num, port_conf, vlans) ports[port_num] = port if port.native_vlan is not None: _dp_add_vlan(vid_dp, dp, vlans[port.native_vlan], logname) if port.tagged_vlans is not None: for vid in port.tagged_vlans: _dp_add_vlan(vid_dp, dp, vlans[vid], logname) except AssertionError as err: logger.exception('Error in config file: %s', err) return None for port in ports.itervalues(): dp.add_port(port) for a_identifier, acl_conf in acls_conf.iteritems(): # TODO: turn this into an object dp.add_acl(a_identifier, acl_conf) # Once the the datapath (dp) object is created containing everything from the yaml file it then appends to the datapaths object dps.append(dp) # returns an array of data paths return (config_hashes, dps)
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_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 _dp_add_vlan(vid_dp, dp, vlan) if port.tagged_vlans is not None: tagged_vlans = [] for v_identifier in port.tagged_vlans: vlan = vlans[v_identifier] tagged_vlans.append(vlan) _dp_add_vlan(vid_dp, dp, vlan) port.tagged_vlans = tagged_vlans 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(conf, config_file, logname): logger = get_logger(logname) if 'dps' not in conf: logger.error("dps not configured in file: {0}".format(config_file)) return None vlans_conf = conf.pop('vlans', {}) acls_conf = conf.pop('acls', {}) dps = [] vid_dp = {} for identifier, dp_conf in conf['dps'].iteritems(): ports_conf = dp_conf.pop('interfaces', {}) dp = DP(identifier, dp_conf) dp.sanity_check() dp_id = dp.dp_id vlans = {} ports = {} for vid, vlan_conf in vlans_conf.iteritems(): vlans[vid] = VLAN(vid, dp_id, vlan_conf) try: for port_num, port_conf in ports_conf.iteritems(): port = port_parser(dp_id, port_num, port_conf, vlans) ports[port_num] = port if port.native_vlan is not None: _dp_add_vlan(vid_dp, dp, vlans[port.native_vlan], logname) if port.tagged_vlans is not None: for vid in port.tagged_vlans: _dp_add_vlan(vid_dp, dp, vlans[vid], logname) except AssertionError as err: logger.exception("Error in config file: {0}".format(err)) return None for port in ports.itervalues(): # now that all ports are created, handle mirroring rewriting if port.mirror is not None: port.mirror = ports[port.mirror].number dp.add_port(port) for a_identifier, acl_conf in acls_conf.iteritems(): # TODO: turn this into an object dp.add_acl(a_identifier, acl_conf) dps.append(dp) return dps
def _dp_parser_v2(logger, acls_conf, dps_conf, meters_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 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) 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 = _get_vlan_by_identifier(dp_id, port.native_vlan, vlans) port.native_vlan = vlan _dp_add_vlan(vid_dp, dp, vlan) if port.tagged_vlans is not None: tagged_vlans = [] for vlan_ident in port.tagged_vlans: vlan = _get_vlan_by_identifier(dp_id, vlan_ident, vlans) tagged_vlans.append(vlan) _dp_add_vlan(vid_dp, dp, vlan) port.tagged_vlans = tagged_vlans 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 _get_vlan_by_identifier(dp_id, vlan_ident, vlans): """v_identifier can be a name or anything used to identify a vlan. v_identifier will be used as vid when vid is omitted in vlan config """ 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: assert False, 'VLAN VID value (%s) is invalid' % vlan_ident return vlans.setdefault(vlan_ident, VLAN(vid, dp_id))
def _get_untagged_vlan(self): """ Get the untagged VLAN configured on this port. """ # Import vlan.VLAN here to avoid circular import from vlan import VLAN untagged_vlan = VLAN( self.switch, int(self.switch.snmp_get(("dot1qPvid", self.base_port)))) # If no untagged VLAN is configured, dot1qPvid is still DEFAULT_VLAN, # so check if the port is really in the VLAN if self in untagged_vlan.untagged_ports: return untagged_vlan else: return None
def _get_vlan_by_identifier(dp_id, v_identifier, vlans): '''v_identifier can be a name or anything used to identify a vlan. v_identifier will be used as vid when vid is omitted in vlan config''' vid = v_identifier for vlan in list(vlans.values()): if v_identifier == vlan._id: vid = vlan.vid break if isinstance(vid, str): try: vid = int(vid, 0) except: assert False, 'vid value (%s) is invalid' % vid vlan = vlans.setdefault(v_identifier, VLAN(vid, dp_id)) return vlan
def _get_tagged_vlans(self): """ Get a list of the tagged VLANs configured on this port. """ from vlan import VLAN egress_ports = self.switch.snmp_get_subtree( ("dot1qVlanStaticEgressPorts", )) tagged_vlans = [] untagged_vlan = self.untagged_vlan for egress_port in egress_ports: oid, port_list = egress_port vlan_id = oid[-1] for port in get_port_list_enabled_ports(self.switch, port_list): if self == port and (untagged_vlan is None or vlan_id != untagged_vlan.vid): tagged_vlans.append(VLAN(self.switch, vlan_id)) return tagged_vlans
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
def add_port(self, k, v={}): # add port specific vlans or fall back to defaults v = copy.copy(v) if v else {} if 'exclude' in self.config_default: excluded = self.is_excluded(self.config_default['exclude'], k) else: excluded = False # set default vlans if we have any if not excluded and 'vlans' in self.config_default: v.setdefault('vlans', self.config_default['vlans']) else: v.setdefault('vlans', []) # set default type if not excluded and 'type' in self.config_default: v.setdefault('type', self.config_default['type']) else: v.setdefault('type', self.default_type) # set default acls if not excluded and 'acls' in self.config_default: v.setdefault('acls', self.config_default['acls']) else: v.setdefault('acls', []) # add vlans & acls configured on a port for vid in v['vlans']: if vid not in self.vlans: self.vlans[vid] = VLAN(vid) if k not in self.ports: self.ports[k] = Port(k, v['type'], v['acls']) self.vlans[vid].add_port(self.ports[k]) # add configuration that should be on all ports for c in self.config_all: c.setdefault('vlans', []) c.setdefault('type', v['type']) c.setdefault('exclude', []) c.setdefault('acls', []) # exclude ports if self.is_excluded(c['exclude'], k): continue # add port to 'all' vlans for vid in c['vlans']: if k not in self.ports: self.ports[k] = Port(k, c['type'], v['acls']) port = self.ports[k] if vid in self.vlans and port in self.vlans[vid].get_ports(): # port is already in vlan, skip continue if vid not in self.vlans: self.vlans[vid] = VLAN(vid) self.vlans[vid].add_port(port) # add 'all' acls to port for acl in c['acls']: self.ports[k].add_acl(acl)
def add_vlan(self, vid, vlan_conf=None): vlan_conf = copy.copy(vlan_conf) if vlan_conf else {} self.vlans.setdefault(vid, VLAN(vid, vlan_conf))