|
|
|
@ -2,12 +2,12 @@
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import librouteros
|
|
|
|
|
import progress.bar
|
|
|
|
|
import ssl
|
|
|
|
|
import os
|
|
|
|
|
import yaml
|
|
|
|
|
import re
|
|
|
|
|
import dns.resolver, dns.reversename
|
|
|
|
|
import ipaddress
|
|
|
|
|
|
|
|
|
|
# comment format:
|
|
|
|
|
# hostname.example.com [aM flag1 flag2 key1=value1 key2=option3:value3,option4:value4] selector.example.com
|
|
|
|
@ -94,7 +94,6 @@ def router_in_groups( options, groups ):
|
|
|
|
|
def connect_routers( config, args ):
|
|
|
|
|
routers = config.get( 'router', {} )
|
|
|
|
|
rval = {}
|
|
|
|
|
with progress.bar.PixelBar( 'Connecting', max = len( routers ) ) as bar:
|
|
|
|
|
for ( name, options ) in routers.items():
|
|
|
|
|
if ( not args.only_router and not args.only_group ) or ( name in args.only_router ) or router_in_groups( options, args.only_group ):
|
|
|
|
|
kwargs = {}
|
|
|
|
@ -102,7 +101,6 @@ def connect_routers( config, args ):
|
|
|
|
|
if 'host' not in kwargs:
|
|
|
|
|
kwargs[ 'host' ] = name
|
|
|
|
|
rval[ name ] = connection( **kwargs )
|
|
|
|
|
bar.next()
|
|
|
|
|
return rval
|
|
|
|
|
|
|
|
|
|
def monty_check( config, args, routers ):
|
|
|
|
@ -179,6 +177,69 @@ def monty_fixup( config, args, routers ):
|
|
|
|
|
print( name, ":", item[ 'interface' ], new_comment )
|
|
|
|
|
ipv6_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } )
|
|
|
|
|
|
|
|
|
|
def monty_provision( config, args, routers ):
|
|
|
|
|
reverse = {}
|
|
|
|
|
statics = {}
|
|
|
|
|
print()
|
|
|
|
|
for ( name, api ) in routers.items():
|
|
|
|
|
if args.dry_run:
|
|
|
|
|
print( '#' * ( len( name ) + 2 ) )
|
|
|
|
|
print( '#', name )
|
|
|
|
|
print()
|
|
|
|
|
vlans = api.path( 'interface', 'vlan' )
|
|
|
|
|
ip_address = api.path( 'ip', 'address' )
|
|
|
|
|
ipv6_address = api.path( 'ipv6', 'address' )
|
|
|
|
|
for vlan in vlans:
|
|
|
|
|
if vlan[ 'vlan-id' ] == args.vlan:
|
|
|
|
|
rval = {}
|
|
|
|
|
if args.static:
|
|
|
|
|
rval[ 'static' ] = True
|
|
|
|
|
disabled = 'no'
|
|
|
|
|
elif name in args.home:
|
|
|
|
|
rval[ 'home' ] = True
|
|
|
|
|
disabled = 'no'
|
|
|
|
|
else:
|
|
|
|
|
disabled = 'yes'
|
|
|
|
|
comment = make_comment( args.selector, rval, args.hostname )
|
|
|
|
|
if args.dry_run:
|
|
|
|
|
if args.ipv4.network.prefixlen == 32:
|
|
|
|
|
print( '/ip address add interface="%s" address="%s" network="%s" disabled=%s comment="%s"' % ( vlan[ 'name' ], config[ 'default_ipv4_loopback' ], args.ipv4.network.network_address, disabled, comment ) )
|
|
|
|
|
else:
|
|
|
|
|
print( '/ip address add interface="%s" address="%s" disabled=%s comment="%s"' % ( vlan[ 'name' ], args.ipv4, disabled, comment ) )
|
|
|
|
|
if args.ipv6:
|
|
|
|
|
if args.static:
|
|
|
|
|
print( '/ipv6 address add interface="%s" address="%s" disabled=%s comment="%s" advertise=no' % ( vlan[ 'name' ], args.ipv6, disabled, comment ) )
|
|
|
|
|
else:
|
|
|
|
|
print( '/ipv6 address add interface="%s" address="%s" disabled=%s comment="%s" eui-64=yes advertise=yes' % ( vlan[ 'name' ], args.ipv6.network, disabled, comment ) )
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
v4addr = { 'interface': vlan[ 'name' ],
|
|
|
|
|
'disabled': disabled,
|
|
|
|
|
'comment': comment,
|
|
|
|
|
}
|
|
|
|
|
if args.ipv4.network.prefixlen == 32:
|
|
|
|
|
v4addr[ 'address' ] = config[ 'default_ipv4_loopback' ]
|
|
|
|
|
v4addr[ 'network' ] = str( args.ipv4.network.network_address )
|
|
|
|
|
else:
|
|
|
|
|
v4addr[ 'address' ] = str( args.ipv4 )
|
|
|
|
|
ip_address.add( **v4addr )
|
|
|
|
|
|
|
|
|
|
if args.ipv6:
|
|
|
|
|
v6addr = { 'interface': vlan[ 'name' ],
|
|
|
|
|
'disabled': disabled,
|
|
|
|
|
'comment': comment,
|
|
|
|
|
}
|
|
|
|
|
if args.static:
|
|
|
|
|
v6addr[ 'address' ] = str( args.ipv6 )
|
|
|
|
|
else:
|
|
|
|
|
v6addr[ 'address' ] = str( args.ipv6.network )
|
|
|
|
|
v6addr[ 'eui-64' ] = 'yes'
|
|
|
|
|
v6addr[ 'advertise' ] = 'yes'
|
|
|
|
|
ipv6_address.add( **v6addr )
|
|
|
|
|
|
|
|
|
|
if args.dry_run:
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
def load_configuration():
|
|
|
|
|
try:
|
|
|
|
|
config = open( os.path.expanduser( '~/.automonty.yaml' ), 'r' )
|
|
|
|
@ -196,7 +257,7 @@ def main():
|
|
|
|
|
|
|
|
|
|
parser.add_argument( '--only-router', action = 'append', default = [] )
|
|
|
|
|
parser.add_argument( '--only-group', action = 'append', default = [] )
|
|
|
|
|
parser.add_argument( '-n', '--dry-run', action = 'store_true' )
|
|
|
|
|
parser.add_argument( '-n', '--dry-run', action = 'store_true', default = False )
|
|
|
|
|
|
|
|
|
|
parser_check = subparsers.add_parser( 'check' )
|
|
|
|
|
parser_check.add_argument( 'addr', nargs = "*" )
|
|
|
|
@ -205,6 +266,16 @@ def main():
|
|
|
|
|
parser_fixup = subparsers.add_parser( 'fixup' )
|
|
|
|
|
parser_fixup.set_defaults( func = monty_fixup )
|
|
|
|
|
|
|
|
|
|
parser_provision = subparsers.add_parser( 'provision' )
|
|
|
|
|
parser_provision.add_argument( '--home', action = 'append', default = [] )
|
|
|
|
|
parser_provision.add_argument( '-s', '--static', action = 'store_true', default = False )
|
|
|
|
|
parser_provision.add_argument( '--selector', type = str, default = None )
|
|
|
|
|
parser_provision.add_argument( 'hostname' )
|
|
|
|
|
parser_provision.add_argument( 'vlan', type = int )
|
|
|
|
|
parser_provision.add_argument( 'ipv4', type = ipaddress.IPv4Interface )
|
|
|
|
|
parser_provision.add_argument( 'ipv6', type = ipaddress.IPv6Interface, nargs = "?" )
|
|
|
|
|
parser_provision.set_defaults( func = monty_provision )
|
|
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
routers = connect_routers( config, args )
|
|
|
|
|
args.func( config, args, routers )
|
|
|
|
|