diff options
author | Michael Elkins <melkins@tislabs.com> | 2012-01-17 05:02:46 +0000 |
---|---|---|
committer | Michael Elkins <melkins@tislabs.com> | 2012-01-17 05:02:46 +0000 |
commit | 56d2ec46c6b87e5fab0add0f5668cba58cddf05d (patch) | |
tree | 5b9005cd57f4fba12e6c896f6bcd70e34202527c /rpkid/portal-gui/scripts/rpkigui-import-routes.py | |
parent | 133939aa88fef6dc0e9b4a2aecf337139628aa28 (diff) |
updated routeviews data handling
refactor common IP range tables into rpki.gui.models.
rework import script to load data into a staging table and swap with the
active table upon completion.
use separate tables for v4 and v6.
svn path=/branches/tk161/; revision=4163
Diffstat (limited to 'rpkid/portal-gui/scripts/rpkigui-import-routes.py')
-rw-r--r-- | rpkid/portal-gui/scripts/rpkigui-import-routes.py | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/rpkid/portal-gui/scripts/rpkigui-import-routes.py b/rpkid/portal-gui/scripts/rpkigui-import-routes.py index b8d2413d..4ca8ef96 100644 --- a/rpkid/portal-gui/scripts/rpkigui-import-routes.py +++ b/rpkid/portal-gui/scripts/rpkigui-import-routes.py @@ -1,7 +1,11 @@ import sys, itertools, re +import struct +import _mysql_exceptions from django.db import transaction, connection +import rpki +import rpki.gui.models from rpki.gui.routeview import models from rpki.resource_set import resource_range_ipv4, resource_range_ipv6 @@ -14,31 +18,50 @@ ip_re = re.compile(r'^[0-9a-fA-F:.]+/\d{1,3}$') class InvalidPrefix(Exception): pass +last_prefix = None +last_asn = None + for row in itertools.islice(f, 5, None): try: cols = row.split() prefix = cols[1] - # validate the prefix since the "sh ip bgp" output is sometimes corrupt - # by no space between the prefix and the next hop IP address. - if not ip_re.match(prefix): - raise InvalidPrefix(prefix) - # index -1 is i/e/? for igp/egp origin_as = cols[-2] - # skip AS_SETs + # FIXME: skip AS_SETs if origin_as[0] == '{': continue + # the output may contain multiple paths to the same origin. + # if this is the same prefix as the last entry, we don't need + # to validate it again. + if prefix != last_prefix: + # validate the prefix since the "sh ip bgp" output is sometimes corrupt + # by no space between the prefix and the next hop IP address. + + if not ip_re.match(prefix): + net, bits = prefix.split('/') + if len(bits) > 2 and int(bits[0]) <= 3: + print 'mask for %s looks fishy...' % prefix, + prefix = '%s/%s' % (net, bits[0:2]) + print 'assuming it should be %s' % prefix + if not ip_re.match(prefix): + raise InvalidPrefix(prefix) + last_prefix = prefix + elif origin_as == last_asn: + # we are only interested in origins, so skip alternate paths + # to same origin as last entry. + continue + last_asn = origin_as + asns = prefixes.get(prefix) if not asns: asns = set() prefixes[prefix] = asns asns.add(int(origin_as)) - #print 'prefix=%s asns=%s' % (prefix, asns) except InvalidPrefix, e: print >>sys.stderr, 'skipping bad entry: ' + row, print >>sys.stderr, e @@ -48,17 +71,17 @@ f.close() def commit(): cursor = connection.cursor() - # an OperationalError exception is thrown when the index doesn't exist try: - print 'Removing existing index...' - cursor.execute('DROP INDEX routeview_routeorigin_idx ON routeview_routeorigin') - except Exception, e: - print type(e) - print e - cursor.execute('BEGIN') + print 'Dropping existing staging table...' + cursor.execute('DROP TABLE IF EXISTS routeview_routeorigin_new') + except _mysql_exceptions.Warning: + pass - print 'Deleting rows from table...' - cursor.execute('DELETE FROM routeview_routeorigin') + print 'Creating staging table...' + cursor.execute('CREATE TABLE routeview_routeorigin_new LIKE routeview_routeorigin') + + print 'Disabling autocommit...' + cursor.execute('SET autocommit=0') print 'Adding rows to table...' for prefix, asns in prefixes.iteritems(): @@ -66,14 +89,25 @@ def commit(): cls = resource_range_ipv6 if family == 6 else resource_range_ipv4 rng = cls.parse_str(prefix) - cursor.executemany("INSERT INTO routeview_routeorigin SET family=%s, asn=%s, prefix_min=X%s, prefix_max=X%s", - [(family, asn, '%032x' % rng.min, '%032x' % rng.max) for asn in asns]) + if family == 4: + xform = long + else: + xform = lambda v: struct.pack('!QQ', (long(v) >> 64) &0xffffffffffffffffL, long(v) & 0xFFFFFFFFFFFFFFFFL) + + cursor.executemany("INSERT INTO routeview_routeorigin_new SET asn=%s, prefix_min=%s, prefix_max=%s", + [(asn, xform(rng.min), xform(rng.max)) for asn in asns]) print 'Committing...' cursor.execute('COMMIT') - print 'Creating index on table...' - cursor.execute('CREATE INDEX routeview_routeorigin_idx ON routeview_routeorigin (family, prefix_min, prefix_max)') + try: + print 'Dropping old table...' + cursor.execute('DROP TABLE IF EXISTS routeview_routeorigin_old') + except _mysql_exceptions.Warning: + pass + + print 'Swapping staging table with live table...' + cursor.execute('RENAME TABLE routeview_routeorigin TO routeview_routeorigin_old, routeview_routeorigin_new TO routeview_routeorigin') transaction.commit_unless_managed() |