From 851f2357de75a87dae40aef7522ebb065140dd50 Mon Sep 17 00:00:00 2001 From: Marek Isalski Date: Sat, 15 Aug 2020 13:48:58 +0100 Subject: [PATCH] add dry-run, and use reverse DNS for fixup --- Pipfile | 1 + automonty | 59 +++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/Pipfile b/Pipfile index 7867ba7..c998200 100644 --- a/Pipfile +++ b/Pipfile @@ -9,6 +9,7 @@ verify_ssl = true librouteros = "==3.*" progress = "*" pyyaml = "*" +dnspython = "*" [requires] python_version = "3.8" diff --git a/automonty b/automonty index 25e200a..75e2899 100755 --- a/automonty +++ b/automonty @@ -7,6 +7,7 @@ import ssl import os import yaml import re +import dns.resolver, dns.reversename # comment format: # hostname.example.com [aM flag1 flag2 key1=value1 key2=option3:value3,option4:value4] selector.example.com @@ -44,6 +45,12 @@ def parse_comment( comment ): else: return ( None, None, comment ) +def reverse_dns( address ): + try: + return str( dns.resolver.resolve( dns.reversename.from_address( address ), 'PTR' )[ 0 ] ) + except: + return address + def make_comment( selector, rval, hostname ): rvalbits = [ "aM" ] for ( k, v ) in rval.items(): @@ -105,23 +112,39 @@ def monty_check( config, args, routers ): print( name, ": v6", 'ENABLED' if active else 'disabled', item[ 'interface' ] ) def monty_fixup( config, args, routers ): + reverse = {} + statics = {} for ( name, api ) in routers.items(): ip_address = api.path( 'ip', 'address' ) ipv6_address = api.path( 'ipv6', 'address' ) for item in ip_address: - if item[ 'interface' ].startswith( "loop" ): - continue - if item[ 'address' ] not in config[ 'loopbacks' ]: - continue ( sel, rval, hst ) = parse_comment( item.get( 'comment', '' ) ) if sel is None: rval = {} active = not item[ 'disabled' ] and not item[ 'invalid' ] - if active: - rval[ 'home' ] = True - new_comment = make_comment( hst, rval, hst ) - print( name, ":", item[ 'interface' ], new_comment ) - ip_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } ) + if item[ 'address' ] in config[ 'loopbacks' ]: + if active: + rval[ 'home' ] = True + else: + rval[ 'static' ] = True + statics[ item[ 'interface' ] ] = True + if not hst: + hst = reverse_dns( item[ 'network' ] ) + while hst.endswith( "." ): + hst = hst[ :-1 ] + if not sel: + if item[ 'interface' ] not in reverse: + rev = reverse_dns( item[ 'network' ] ) + while rev.endswith( "." ): + rev = rev[ :-1 ] + reverse[ item[ 'interface' ] ] = rev + sel = rev + new_comment = make_comment( sel, rval, hst ) + if args.dry_run: + print( item[ 'interface' ], item[ 'address' ], '->', new_comment ) + else: + print( name, ":", item[ 'interface' ], new_comment ) + ip_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } ) for item in ipv6_address: if item[ 'interface' ].startswith( "loop" ): continue @@ -131,11 +154,20 @@ def monty_fixup( config, args, routers ): if sel is None: rval = {} active = not item[ 'disabled' ] and not item[ 'invalid' ] - if active: + if statics.get( item[ 'interface' ], False ): + rval[ 'static' ] = True + elif active: rval[ 'home' ] = True - new_comment = make_comment( hst, rval, hst ) - print( name, ":", item[ 'interface' ], new_comment ) - ipv6_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } ) + if not sel: + sel = reverse.get( item[ 'interface' ], "XXX " + item[ 'interface' ] ) + if not hst: + hst = reverse.get( item[ 'interface' ], "XXX " + item[ 'interface' ] ) + new_comment = make_comment( sel, rval, hst ) + if args.dry_run: + print( item[ 'interface' ], item[ 'address' ], '->', new_comment ) + else: + print( name, ":", item[ 'interface' ], new_comment ) + ipv6_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } ) def load_configuration(): try: @@ -153,6 +185,7 @@ def main(): subparsers = parser.add_subparsers() parser.add_argument( '--only', action = 'append' ) + parser.add_argument( '-n', '--dry-run', action = 'store_true' ) parser_check = subparsers.add_parser( 'check' ) parser_check.add_argument( 'addr', nargs = "*" )