Browse Source

Add script to generate peer config based on PeeringDB
Add support dynamic number of IX
Add support multiple session

McKay1717 6 years ago
parent
commit
d73c989e14
4 changed files with 108 additions and 30 deletions
  1. 39 28
      generate_config_bird.py
  2. 67 0
      generate_peers.py
  3. 1 1
      templates/bird_v4.j2
  4. 1 1
      templates/bird_v6.j2

+ 39 - 28
generate_config_bird.py

@@ -9,7 +9,8 @@ import glob
 from jinja2 import Environment, FileSystemLoader
 from termcolor import colored
 
-def parse_peers(peer_file):
+
+def parse_peers(peer_file, version):
     """parse_peers: Just a simple function for peers parsing
     :peer_file: The YAML peer file to parse
     :returns: Just a return code if the file is correctly parsed or not
@@ -35,47 +36,57 @@ def parse_peers(peer_file):
         acceptable_exports = ['AS-GITOYEN', 'NOT ANY', 'ANY']
         if not peerings[asn]['export'] in acceptable_exports:
             print colored('ERROR', 'red') + ": export must be one of the following: %s" \
-                % " ".join(acceptable_exports)
+            % " ".join(acceptable_exports)
             sys.exit(2)
 
+        session = 0
         for peer in peerings[asn]['peerings']:
             try:
                 peer_ip = ipaddr.IPAddress(peer)
+                session += 1
                 if type(ipaddr.IPAddress(peer_ip)) is ipaddr.IPv4Address:
                     neighbor_ipv4 = peer_ip
-                    if ixp == 'sfinx':
-                        ix4_group = 'SFINX'
-                    else:
-                        ix4_group = 'AMS-IX-PEERS'
                 elif type(ipaddr.IPAddress(peer_ip)) is ipaddr.IPv6Address:
                     neighbor_ipv6 = peer_ip
-                    if ixp == 'sfinx':
-                        ix6_group = 'SFINXV6'
-                    else:
-                        ix6_group = 'AMS-IX6-PEERS'
             except ValueError:
                 print colored('ERROR', 'red') + ": %s in %s is not a valid IP" % (peer, asn)
                 sys.exit(2)
 
-        try:
-            limit_ipv4 = peerings[asn]['limit_ipv4']
-        except:
-            limit_ipv4 = False
+            try:
+                limit_ipv4 = peerings[asn]['limit_ipv4']
+            except:
+                limit_ipv4 = False
+
+            try:
+                limit_ipv6 = peerings[asn]['limit_ipv6']
+            except:
+                limit_ipv6 = False
+
+            env = Environment(loader=FileSystemLoader('./'))
 
-        try:
-            limit_ipv6 = peerings[asn]['limit_ipv6']
-        except:
-            limit_ipv6 = False
+            if version == 6 and 'neighbor_ipv6' in locals():
+                #Generate IPV6
+                tpl = env.get_template('templates/bird_v6.j2')
 
-        env = Environment(loader=FileSystemLoader('./'))
-        tpl = env.get_template('templates/bird_v4.j2')
+                print tpl.render(neighbor_as=asn, description=
+                peerings[asn]['description'], export_as=peerings[asn]['export'],
+                           import_as=peerings[asn]['import'],
+                           neighbor_ipv6=neighbor_ipv6, ix_name=
+                           ixp, limit_ipv6=limit_ipv6, session_num=session)
+            else:
+                if 'neighbor_ipv4' in locals():
+                    #Generate IPV4
+                    tpl = env.get_template('templates/bird_v4.j2')
 
-        print tpl.render(neighbor_as = asn, description =
-                peerings[asn]['description'], export_as = peerings[asn]['export'],
-                import_as = peerings[asn]['import'], neighbor_ipv4 =
-                neighbor_ipv4, neighbor_ipv6 = neighbor_ipv6, ix4_name =
-                ix4_group, ix6_name = ix6_group, limit_ipv4 = limit_ipv4,
-                limit_ipv6 = limit_ipv6)
+                    print tpl.render(neighbor_as=asn, description=
+                    peerings[asn]['description'], export_as=peerings[asn]['export'],
+                               import_as=peerings[asn]['import'], neighbor_ipv4=
+                               neighbor_ipv4,ix_name=ixp,
+                               limit_ipv4=limit_ipv4, session_num=session)
 
-for peer_files in ('peers/franceix.yml', 'peers/amsix.yml'):
-    parse_peers(peer_files)
+#Basicly check arg
+if len(sys.argv) == 2:
+    for peer_files in glob.glob('peers/*.yml'):
+        parse_peers(peer_files, int(sys.argv[1]))
+else:
+    print("Invalide argument number, You must specify IP version 4 or 6")

+ 67 - 0
generate_peers.py

@@ -0,0 +1,67 @@
+import requests
+import yaml
+
+GITOYEN_ASN = 20766
+PEER_ASN_LIST = [20940,
+                 26496,
+                 714,
+                 13768,
+                 8359,
+                 2119,
+                 36236,
+                 36692,
+                 14340,
+                 2635,
+                 19679,
+                 6507,
+                 3265,
+                 14413,
+                 36459,
+                 25459,
+                 39386,
+                 29686,
+                 55818,
+                 3262,
+                 42459,
+                 7500,
+                 200020
+                 ]
+
+gitoyen_peering_factory = []
+ses = requests.session()
+peer = dict()
+
+# List Gitoyen Factory with IPv6 avaidable
+factory_request = ses.get("https://peeringdb.com//api/netixlan?asn=" + str(GITOYEN_ASN))
+for factory in factory_request.json()['data']:
+    if factory['ipaddr6'] is not None:
+        gitoyen_peering_factory.append(factory)
+
+for factory in gitoyen_peering_factory:
+    name = (str(factory['name'])).split(' ')[0].lower()
+    print("Generation en cours pour " + name)
+    peer[name] = dict()
+    for asn in PEER_ASN_LIST:
+        info_request = ses.get(
+            "https://peeringdb.com/api/netixlan?asn=" + str(asn) + "&ix_id=" + str(factory['ix_id']))
+        result = info_request.json()['data']
+        name_request = ses.get('https://peeringdb.com/api/net?asn=' + str(asn))
+        peer[name][asn] = dict()
+        peer[name][asn]['description'] = name_request.json()['data'][0]['name']
+        peer[name][asn]['import'] = "AS" + str(asn)
+        peer[name][asn]['export'] =  "AS-GITOYEN"
+        peer[name][asn]['peerings'] = []
+        delete = True
+        for routeur in result:
+            if routeur['ipaddr4'] is not None:
+                peer[name][asn]['peerings'].append(routeur['ipaddr4'])
+            if routeur['ipaddr6'] is not None:
+                peer[name][asn]['peerings'].append(routeur['ipaddr6'])
+            delete = False
+        if delete:
+            peer[name].pop(asn, None)
+
+for gix in peer:
+    with open("peers/"+gix+'.yml', 'w') as outfile:
+        yaml.dump(peer[gix], outfile, default_flow_style=False)
+        outfile.close()

+ 1 - 1
templates/bird_v4.j2

@@ -1,4 +1,4 @@
-protocol bgp {{ ix_name }}_{{ neighbor_as }} from tpl_{{ ix_name }}_peers {
+protocol bgp {{ ix_name }}_{{ neighbor_as }}_{{ session_num }} from tpl_{{ ix_name }}_peers {
     neighbor {{ neighbor_ipv4 }} as {{ neighbor_as }};
     description "{{ ix_name }} / {{ description }}";
     {%- if limit_ipv4 %}

+ 1 - 1
templates/bird_v6.j2

@@ -1,4 +1,4 @@
-protocol bgp {{ ix_name }}_{{ neighbor_as }} from tpl_{{ ix_name }}_peers {
+protocol bgp {{ ix_name }}_{{ neighbor_as }}_{{ session_num }}  from tpl_{{ ix_name }}_peers {
     neighbor {{ neighbor_ipv6 }} as {{ neighbor_as }};
     description "{{ ix_name }} / {{ description }}";
     {%- if limit_ipv6 %}