def setup_config(): api_config.register_config() config.register() cfg.CONF( args=sys.argv[1:], project='bagpipe-bgp', default_config_files=['/etc/bagpipe-bgp/bgp.conf'], version=( '%%(prog)s %s' % pbr.version.VersionInfo('networking-bagpipe').release_string()))
def main(): api_config.register_config() cfg.CONF(args=[], project='bagpipe-rest-attach', default_config_files=['/etc/bagpipe-bgp/bgp.conf']) usage = "usage: %prog [--attach|--detach] --network-type (ipvpn|evpn) "\ "--port (<port>|netns) --ip <ip>[/<mask>] [options] (see --help)" parser = optparse.OptionParser(usage) parser.add_option("--attach", dest="operation", action="store_const", const="attach", help="attach local port") parser.add_option("--detach", dest="operation", action="store_const", const="detach", help="detach local port") parser.add_option("--network-type", dest="network_type", help="network type (ipvpn or evpn)", choices=[const.IPVPN, const.EVPN]) parser.add_option("--vpn-instance-id", dest="vpn_instance_id", help="UUID for the network instance " "(default: %default-(ipvpn|evpn))", default=DEFAULT_VPN_INSTANCE_ID) parser.add_option("--port", dest="port", help="local port to attach/detach (use special port " "'netns[:if]' to have an interface to a local network " "namespace attached/detached " "[with 'if' as the name of the interface to the netns]") parser.add_option("--direction", dest="direction", choices=[const.TO_PORT, const.FROM_PORT, const.BOTH], default=const.BOTH, help=("local port direction (to-port|from-port|both) " "in VPN (default: %default)")) parser.add_option("--rt", dest="route_targets", help="route target [default: 64512:0] (can be " "specified multiple times)", default=[], action="append") parser.add_option("--import-rt", dest="import_only_rts", help="import-only route target (can be specified" "multiple times)", default=[], action="append") parser.add_option("--export-rt", dest="export_only_rts", help="export-only route target (can be specified" "multiple times)", default=[], action="append") parser.add_option("--ip", dest="ip", help="IP prefix / mask (mask defaults to /24)") parser.add_option("--gateway-ip", dest="gw_ip", help="IP address of network gateway (optional, " "defaults to last IP in range)") parser.add_option("--mac", dest="mac", help="MAC address (required for evpn if port" " is not 'netns')") parser.set_defaults(advertise_subnet=False) parser.add_option("--advertise-singleton", action="store_false", dest="advertise_subnet", help="advertise IP address as a /32 (default)") parser.add_option("--advertise-subnet", action="store_true", dest="advertise_subnet", help="advertise the whole IP subnet") parser.add_option("--ovs-preplug", action="store_true", dest="ovs_preplug", default=False, help="should we prealably plug the port " "into an OVS bridge") parser.add_option("--ovs-bridge", dest="bridge", default="br-int", help="if preplug, specifies which OVS bridge to use" " (default: %default)") parser.add_option("--ovs-vlan", dest="ovs_vlan", type='int', help="if specified, only this VLAN from the OVS " "interface will be attached to the VPN instance " "(optional)") parser.add_option("--netns", dest="netns", help="name of network namespace (optional, for use with" " --port netns)") parser.add_option("--if2vpn", dest="if2vpn", default=NS2VPN_DEFAULT_IFNAME, help="name of interface in netns toward VPN" "defaults to %default " "(optional, for use with --port netns)") parser.add_option("--readv-from-rt", dest="readv_from_rts", help="enables route readvertisement from these RTs," " works in conjunction with --readv-to-rt", default=[], action="append") parser.add_option("--readv-to-rt", dest="readv_to_rts", help="enables route readvertisement to these RTs," " works in conjunction with --readv-from-rt", default=[], action="append") parser.add_option("--redirect-rts", dest="redirect_rts", help="Redirection Route Targets to attract traffic, " "matching the traffic classifier, in specified VRF from " "any VRF importing this route target", default=[], action="append") parser.add_option("--source-prefix", dest="sourcePrefix", type="string", help="Traffic classifier source prefix " "filter", action="callback", callback=classifier_callback) parser.add_option("--destination-prefix", dest="destinationPrefix", type="string", help="Traffic classifier destination " "prefix filter", action="callback", callback=classifier_callback) parser.add_option("--source-port", dest="sourcePort", type="string", help="Traffic classifier source port " "number or range filter", action="callback", callback=classifier_callback) parser.add_option("--destination-port", dest="destinationPort", type="string", help="Traffic classifier destination port" " number or range filter", action="callback", callback=classifier_callback) parser.add_option("--protocol", dest="protocol", type="string", help="Traffic classifier IP protocol " "filter", action="callback", callback=classifier_callback) parser.add_option("--attract-to-rt", dest="attract_to_rts", help="enables route advertisement to these RTs," " works in conjunction with " "--static-destination-prefix", default=[], action="append") parser.add_option("--static-destination-prefix", dest="static_dest_prefixes", help="static destination prefix to advertise," " works in conjunction with --attract-to-rts", default=[], action="append") parser.add_option("--lb-consistent-hash-order", dest="lb_consistent_hash_order", default=0, type="int", help="Load Balancing consistent hash sort order") parser.add_option("--vni", dest="vni", default=0, type="int", help="VXLAN VNI to use for this VPN instance (optional)") parser.add_option("--local-pref", dest="local_pref", default=None, type="int", help="BGP LOCAL PREF attribute (optional)") (options, _) = parser.parse_args() if not (options.operation): parser.error("Need to specify --attach or --detach") if not (options.port): parser.error("Need to specify --port <localport>") if not (options.network_type): parser.error("Need to specify --network-type") if not (options.ip): parser.error("Need to specify --ip") if (len(options.route_targets) == 0 and not (options.import_only_rts or options.export_only_rts)): if options.network_type == const.IPVPN: options.route_targets = ["64512:512"] else: options.route_targets = ["64512:513"] import_rts = copy.copy(options.route_targets or []) for rt in options.import_only_rts: import_rts.append(rt) export_rts = copy.copy(options.route_targets or []) for rt in options.export_only_rts: export_rts.append(rt) if not re.match('.*/[0-9]+$', options.ip): options.ip = options.ip + "/24" if not (options.gw_ip): net = netaddr.IPNetwork(options.ip) print("using %s as gateway address" % str(net[-2])) options.gw_ip = str(net[-2]) if options.vpn_instance_id == DEFAULT_VPN_INSTANCE_ID: options.vpn_instance_id = "%s-%s" % (options.network_type, options.vpn_instance_id) if options.port.startswith("netns"): if not options.netns: options.netns = options.vpn_instance_id try: (_, options.if2netns) = options.port.split(":") except Exception: options.if2netns = get_vpn2ns_if_name(options.netns) if options.operation == "attach": create_special_netns_port(options) options.port = options.if2netns if not options.mac: options.mac = net_utils.get_device_mac(run_log_command, options.if2vpn, options.netns) print("Local port: %s (%s)" % (options.port, options.mac)) run_log_command("ip link show %s" % options.port) local_port = {} if options.port[:5] == "evpn:": if (options.network_type == const.IPVPN): print("will plug evpn %s into the IPVPN" % options.port[5:]) local_port['evpn'] = {'id': options.port[5:]} else: raise Exception("Can only plug an evpn into an ipvpn") else: local_port['linuxif'] = options.port # currently our only the MPLS OVS driver for ipvpn requires preplug if (options.ovs_preplug and options.network_type == const.IPVPN): print("pre-plugging %s into %s" % (options.port, options.bridge)) run_log_command("ovs-vsctl del-port %s %s" % (options.bridge, options.port), raise_on_error=False) run_log_command("ovs-vsctl add-port %s %s" % (options.bridge, options.port)) local_port['ovs'] = {'port_name': options.port, 'plugged': True} if options.ovs_vlan: local_port['ovs']['vlan'] = options.ovs_vlan if not options.mac: if options.network_type == const.IPVPN: options.mac = "52:54:00:99:99:22" else: parser.error("Need to specify --mac for an EVPN network " "attachment if port is not 'netns'") readvertise = None if options.readv_to_rts: readvertise = { "from_rt": options.readv_from_rts, "to_rt": options.readv_to_rts } attract_traffic = dict() if options.redirect_rts: if options.classifier: attract_traffic.update( dict(redirect_rts=options.redirect_rts, classifier=options.classifier)) else: parser.error("Need to specify --redirect-rt and at least one " "traffic classifier option") if options.attract_to_rts: if options.static_dest_prefixes: attract_traffic.update( dict(to=options.attract_to_rts, static_destination_prefixes=options. static_dest_prefixes)) else: parser.error("Need to specify --attract-to-rt and at least " "one static destination prefix option") data = { "import_rt": import_rts, "export_rt": export_rts, "local_port": local_port, "vpn_instance_id": options.vpn_instance_id, "vpn_type": options.network_type, "gateway_ip": options.gw_ip, "mac_address": options.mac, "ip_address": options.ip, "advertise_subnet": options.advertise_subnet, "readvertise": readvertise, "attract_traffic": attract_traffic, "lb_consistent_hash_order": options.lb_consistent_hash_order, "vni": options.vni } if options.local_pref: data['local_pref'] = options.local_pref if options.direction: data['direction'] = options.direction json_data = jsonutils.dumps(data) print("request: %s" % json_data) os.environ['NO_PROXY'] = "127.0.0.1" req = urllib2.Request( "http://127.0.0.1:%d/%s_localport" % (cfg.CONF.API.port, options.operation), json_data, {'Content-Type': 'application/json'}) try: response = urllib2.urlopen(req) response_content = response.read() response.close() print("response: %d %s" % (response.getcode(), response_content)) except urllib2.HTTPError as e: error_content = e.read() print(" %s" % error_content) sys.exit("error %d, reason: %s" % (e.code, e.reason))
def main(): api_config.register_config() try: cfg.CONF(args=[], project='bagpipe-looking-glass', default_config_files=['/etc/bagpipe-bgp/bgp.conf']) api_port = cfg.CONF.API.port except cfg.ConfigFilesNotFoundError: api_port = api_config.DEFAULT_PORT usage = """ %prog [--server <ip>] path to object in looking-glass e.g.: %prog vpns instances""" parser = optparse.OptionParser(usage) parser.add_option( "--server", dest="server", default="127.0.0.1", help="IP address of BaGPipe BGP (optional, default: %default)") parser.add_option("--port", dest="port", type="int", default=api_port, help="Port of BaGPipe BGP (optional, default: %default)") parser.add_option( "--prefix", dest="prefix", default=LOOKING_GLASS_BASE, help="Looking-glass URL Prefix (optional, default: %default)") parser.add_option( "-r", "--recurse", dest="recurse", action="store_true", default=False, help="Recurse down into the whole looking-glass (disabled by default)") (options, args) = parser.parse_args() quoted_args = [urllib2.quote(arg) for arg in args] target_url = "http://%s:%d/%s/%s" % (options.server, options.port, options.prefix, "/".join(quoted_args)) try: os.environ['NO_PROXY'] = options.server response = urllib2.urlopen(target_url) if response.getcode() == 200: data = jsonutils.load(response) if (isinstance(data, dict) and "href" in data): target_url_bis = data["href"] response_bis = urllib2.urlopen(target_url_bis) if response.getcode() == 200: target_url = target_url_bis data = jsonutils.load(response_bis) pretty_print_recurse(data, 0, options.recurse, target_url, already_anew_line=True) except urllib2.HTTPError as e: if e.code == 404: print("No such looking glass path: %s\n(%s)" % (" ".join(quoted_args), target_url)) else: print("Error code %d: %s" % (e.getcode(), e.read())) return except urllib2.URLError as e: print("No server at http://%s:%d : %s" % (options.server, options.port, e))
def main(): api_config.register_config() try: cfg.CONF(args=[], project='bagpipe-impex2dot', default_config_files=['/etc/bagpipe-bgp/bgp.conf']) api_port = cfg.CONF.API.port except cfg.ConfigFilesNotFoundError: api_port = api_config.DEFAULT_PORT usage = """ %prog [options] Example: bagpipe-impex2dot --server s1 --server s2 | dot -Tpdf > impex.pdf """ parser = optparse.OptionParser(usage) parser.add_option( "--server", dest="servers", default=[], action="append", help="IP address of a BaGPipe BGP instances (default: localhost)") parser.add_option( "--port", dest="port", type="int", default=api_port, help="Port of BaGPipe BGP (optional, default: %default)") parser.add_option( "--prefix", dest="prefix", default=LOOKING_GLASS_BASE, help="Looking-glass URL Prefix (optional, default: %default)") (options, _) = parser.parse_args() if len(options.servers) == 0: options.servers = ["localhost"] ports = set() dests = set() print('digraph import_export {') print(' node [fontname="Helvetica"];') print(' edge [fontname="Helvetica"];') print(' nodesep=0.55;') (rts, vpns) = get_all(options) print(' subgraph rts {') print(' rank=same;') for rt in rts: label = rt.upper().replace('_', '\\n') print(' %s [shape="circle",label="%s",%s];' % (rt, label, RT_TXT_STYLE)) print(' }') print(' subgraph ipvpns {') print(' rank=same;') for (server, vpn, _) in filter(lambda x: x[2] == 'VRF', vpns): server_spec = ("\\n[%s]" % server) if server != 'localhost' else '' print(' %s [label="{<0>VRF\\n%s%s|<readv>}",' 'shape="record"];' % (vpn_uid(server, vpn), vpn_short(vpn), server_spec)) print(' }') print(' subgraph evpns {') for (server, vpn, _) in filter(lambda x: x[2] == 'EVI', vpns): server_spec = ("\\n[%s]" % server) if server != 'localhost' else '' print(' %s [label="{<0>EVI\\n%s%s}",' 'shape="record"];' % (vpn_uid(server, vpn), vpn_short(vpn), server_spec)) print(' }') for (server, vpn, _) in vpns: print(' /* %s:%s */' % (server, vpn)) uid = vpn_uid(server, vpn) for rt_i in request(options, server, ["vpns", "instances", vpn, "route_targets", "import"]): print(' %s -> %s:0 [%s];' % (normalize(rt_i), uid, RT_STYLE)) for rt_e in request(options, server, ["vpns", "instances", vpn, "route_targets", "export"]): print(' %s:0 -> %s [%s];' % (uid, normalize(rt_e), RT_STYLE)) readvertise = request(options, server, ["vpns", "instances", vpn, "readvertise"]) if readvertise: readv = "%s:readv" % vpn_uid(server, vpn) print(' %s -> %s [label="",%s];' % (normalize(readvertise['from'][0]), readv, RT_STYLE_REDIR_FROM_RT)) print(' %s -> %s [label="",%s];' % (readv, normalize(readvertise['to'][0]), RT_STYLE_REDIR_TO_RT)) attract = readvertise.get('attract_traffic', None) if attract: intermediate = "%s_%s_attract" % (normalize(server), normalize(vpn)) print(' %s [style=invis,height=0,width=0,' 'fixedsize=true,rank=1]' % intermediate) redir_rt = attract['redirect_rts'][0] # readv -> intermediate print(' %s -> %s [label="flow",%s];' % (readv, intermediate, RT_STYLE_FLOWSPEC_INTER)) # intermediate -> flowspec route RT print(' %s -> %s [label="",weight=50,%s];' % (intermediate, normalize(redir_rt), RT_STYLE_FLOWSPEC)) # intermediate -> flowspec route redirect action RT print(' %s -> %s [label="action",%s,arrowhead=none' ',weight=20];' % (intermediate, normalize(readvertise['to'][0]), RT_STYLE_FLOWSPEC_ACTION)) for port in request(options, server, ["vpns", "instances", vpn, "ports"]).keys(): print(' %s -> port_%s_%s [%s,weight=5];' % (uid, normalize(server), normalize(port), PORT_LINK_STYLE)) ports.add((server, normalize(port))) # possible link between an E-VPN and an IPVPN ? ipvpn = request(options, server, ["vpns", "instances", vpn, "gateway_port", "ipvpn"]) if ipvpn: ipvpn_id = ipvpn['external_instance_id'] print(' %s -> %s [weight=500];' % (uid, vpn_uid(server, ipvpn_id)) ) for (server, port) in ports: print(' port_%s_%s [label="",style=invis,height=0,width=0,' 'fixedsize=true];' % (normalize(server), normalize(port))) if port.startswith('to_'): dest = port.split('_')[1] print(' port_%s_%s -> dest_%s_%s [style=dashed,' 'dir=none,color="gray"' ',weight=5];' % (normalize(server), normalize(port), normalize(server), dest)) dests.add((server, dest)) for (server, dest) in dests: print(' dest_%s_%s [label="%s\\n[%s]",shape="square",' 'color="gray"];' % (normalize(server), normalize(dest), dest, server)) print('}')