promote, demote, and migrate seem to work
This commit is contained in:
		@ -56,6 +56,8 @@ loopbacks:
 | 
				
			|||||||
  - 46.227.207.255/32
 | 
					  - 46.227.207.255/32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
default_ipv4_loopback: 46.227.207.255/32
 | 
					default_ipv4_loopback: 46.227.207.255/32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					routing_filter_chain: automonty
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We have specified:
 | 
					We have specified:
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										267
									
								
								automonty
									
									
									
									
									
								
							
							
						
						
									
										267
									
								
								automonty
									
									
									
									
									
								
							@ -10,14 +10,17 @@ import dns.resolver, dns.reversename
 | 
				
			|||||||
import ipaddress
 | 
					import ipaddress
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# comment format:
 | 
					# comment format:
 | 
				
			||||||
# hostname.example.com [aM flag1 flag2 key1=value1 key2=option3:value3,option4:value4] selector.example.com
 | 
					#   hostname.example.com [aM flag1 flag2 key1=value1 key2=option3:value3,option4:value4] selector.example.com
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# flags:
 | 
					# flags:
 | 
				
			||||||
#   static - do not auto-enable or auto-disable this address (loopbacks, linknets)
 | 
					#   static - do not auto-enable or auto-disable this address (loopbacks, linknets)
 | 
				
			||||||
#   home - this is the normal home-location of the IP
 | 
					#   home - this is the normal home-location of the IP
 | 
				
			||||||
#   evacuated - this has been moved from this host to elsewhere
 | 
					#   standby - this is an active interface, but not intended as primary route
 | 
				
			||||||
#   evacuee - this is an evacuated address
 | 
					 | 
				
			||||||
#   teardown - being destroyed
 | 
					#   teardown - being destroyed
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# keys:
 | 
				
			||||||
 | 
					#   evacuated=router - this address has been moved from this host to router
 | 
				
			||||||
 | 
					#   evacuee=router - this is an evacuated address originally from router
 | 
				
			||||||
 | 
					
 | 
				
			||||||
aM1 = re.compile( r"\[aM ?([^]]*)\]" )
 | 
					aM1 = re.compile( r"\[aM ?([^]]*)\]" )
 | 
				
			||||||
def parse_comment( comment ):
 | 
					def parse_comment( comment ):
 | 
				
			||||||
@ -59,7 +62,7 @@ def make_comment( selector, rval, hostname ):
 | 
				
			|||||||
            rvalbits.append( k )
 | 
					            rvalbits.append( k )
 | 
				
			||||||
        elif isinstance( v, dict ):
 | 
					        elif isinstance( v, dict ):
 | 
				
			||||||
            rvalbits.append( "%s=%s" % ( k, ",".join( "%s:%s" % vi for vi in v.items() ) ) )
 | 
					            rvalbits.append( "%s=%s" % ( k, ",".join( "%s:%s" % vi for vi in v.items() ) ) )
 | 
				
			||||||
        else:
 | 
					        elif v:
 | 
				
			||||||
            rvalbits.append( "%s=%s" % ( k, v ) )
 | 
					            rvalbits.append( "%s=%s" % ( k, v ) )
 | 
				
			||||||
    if selector == hostname or selector is None:
 | 
					    if selector == hostname or selector is None:
 | 
				
			||||||
        return "%s [%s]" % ( hostname, " ".join( rvalbits ) )
 | 
					        return "%s [%s]" % ( hostname, " ".join( rvalbits ) )
 | 
				
			||||||
@ -154,6 +157,11 @@ def monty_fixup( config, args, routers ):
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    print( name, ":", item[ 'interface' ], new_comment )
 | 
					                    print( name, ":", item[ 'interface' ], new_comment )
 | 
				
			||||||
                    ip_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } )
 | 
					                    ip_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } )
 | 
				
			||||||
 | 
					            addr = ipaddress.ip_interface( item[ 'address' ] )
 | 
				
			||||||
 | 
					            if item[ 'address' ] in config[ 'loopbacks' ]:
 | 
				
			||||||
 | 
					                addr = ipaddress.ip_interface( item[ 'network' ] )
 | 
				
			||||||
 | 
					            _adjust_filter( config, api, addr.network, hst, sel, home = rval.get( 'home', False ), standby = False, static = rval.get( 'static', False ), rval = rval )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for item in ipv6_address:
 | 
					        for item in ipv6_address:
 | 
				
			||||||
            if item[ 'interface' ].startswith( "loop" ):
 | 
					            if item[ 'interface' ].startswith( "loop" ):
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
@ -177,6 +185,66 @@ def monty_fixup( config, args, routers ):
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    print( name, ":", item[ 'interface' ], new_comment )
 | 
					                    print( name, ":", item[ 'interface' ], new_comment )
 | 
				
			||||||
                    ipv6_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } )
 | 
					                    ipv6_address.update( **{ 'comment': new_comment, '.id': item[ '.id' ] } )
 | 
				
			||||||
 | 
					            addr = ipaddress.ip_interface( item[ 'address' ] )
 | 
				
			||||||
 | 
					            _adjust_filter( config, api, addr.network, hst, sel, home = rval.get( 'home', False ), standby = False, static = rval.get( 'static', False ), rval = rval )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _adjust_filter( config, api, network, hostname, selector = None, home = None, standby = None, static = None, delete = False, rval = None, disabled = False ):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _make_filter_attrs( comment, disabled, home, static, standby ):
 | 
				
			||||||
 | 
					        attrs = { 'action': 'accept',
 | 
				
			||||||
 | 
					                  'comment': comment,
 | 
				
			||||||
 | 
					                  'disabled': 'yes' if disabled else 'no',
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					        if home or static:
 | 
				
			||||||
 | 
					            attrs[ '!set-bgp-prepend' ] = ''
 | 
				
			||||||
 | 
					            attrs[ 'set-bgp-local-pref' ] = 980
 | 
				
			||||||
 | 
					        elif standby:
 | 
				
			||||||
 | 
					            attrs[ 'set-bgp-prepend' ] = 1
 | 
				
			||||||
 | 
					            attrs[ 'set-bgp-local-pref' ] = 970
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            attrs[ 'set-bgp-prepend' ] = 2
 | 
				
			||||||
 | 
					            attrs[ 'set-bgp-local-pref' ] = 960
 | 
				
			||||||
 | 
					        return attrs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if isinstance( network, ( ipaddress.IPv4Interface, ipaddress.IPv6Interface ) ):
 | 
				
			||||||
 | 
					        network = network.network
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    filters = api.path( 'routing', 'filter' )
 | 
				
			||||||
 | 
					    found = False
 | 
				
			||||||
 | 
					    if rval is None:
 | 
				
			||||||
 | 
					        rval = {}
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        _rval = rval
 | 
				
			||||||
 | 
					        rval = {}
 | 
				
			||||||
 | 
					        rval.update( _rval )
 | 
				
			||||||
 | 
					    if home is not None:
 | 
				
			||||||
 | 
					        rval[ 'home' ] = home
 | 
				
			||||||
 | 
					    if standby is not None:
 | 
				
			||||||
 | 
					        rval[ 'standby' ] = standby
 | 
				
			||||||
 | 
					    if static is not None:
 | 
				
			||||||
 | 
					        rval[ 'static' ] = static
 | 
				
			||||||
 | 
					    comment = make_comment( selector, rval, hostname )
 | 
				
			||||||
 | 
					    for f in filters:
 | 
				
			||||||
 | 
					        if f[ 'chain' ] == config[ 'routing_filter_chain' ]:
 | 
				
			||||||
 | 
					            match = str( network )
 | 
				
			||||||
 | 
					            if isinstance( network, ipaddress.IPv4Network ) and network.prefixlen == 32:
 | 
				
			||||||
 | 
					                match = match.split( "/", 1 )[ 0 ]
 | 
				
			||||||
 | 
					            elif isinstance( network, ipaddress.IPv6Network ) and network.prefixlen == 128:
 | 
				
			||||||
 | 
					                match = match.split( "/", 1 )[ 0 ]
 | 
				
			||||||
 | 
					            if f[ 'prefix' ] == match:
 | 
				
			||||||
 | 
					                if delete:
 | 
				
			||||||
 | 
					                    filters.delete( f[ '.id' ] )
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    update = _make_filter_attrs( comment, disabled, home, static, standby )
 | 
				
			||||||
 | 
					                    update[ '.id' ] = f[ '.id' ]
 | 
				
			||||||
 | 
					                    filters.update( **update )
 | 
				
			||||||
 | 
					                    found = True
 | 
				
			||||||
 | 
					    if not found and not delete:
 | 
				
			||||||
 | 
					        create = _make_filter_attrs( comment, disabled, home, static, standby )
 | 
				
			||||||
 | 
					        create[ 'chain' ] = config[ 'routing_filter_chain' ]
 | 
				
			||||||
 | 
					        create[ 'prefix' ] = str( network )
 | 
				
			||||||
 | 
					        filters.add( **create )
 | 
				
			||||||
 | 
					    return rval
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def monty_provision( config, args, routers ):
 | 
					def monty_provision( config, args, routers ):
 | 
				
			||||||
    reverse = {}
 | 
					    reverse = {}
 | 
				
			||||||
@ -200,6 +268,9 @@ def monty_provision( config, args, routers ):
 | 
				
			|||||||
                elif name in args.home:
 | 
					                elif name in args.home:
 | 
				
			||||||
                    rval[ 'home' ] = True
 | 
					                    rval[ 'home' ] = True
 | 
				
			||||||
                    disabled = 'no'
 | 
					                    disabled = 'no'
 | 
				
			||||||
 | 
					                elif name in args.standby:
 | 
				
			||||||
 | 
					                    rval[ 'standby' ] = True
 | 
				
			||||||
 | 
					                    disabled = 'no'
 | 
				
			||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    disabled = 'yes'
 | 
					                    disabled = 'yes'
 | 
				
			||||||
                comment = make_comment( args.selector, rval, args.hostname )
 | 
					                comment = make_comment( args.selector, rval, args.hostname )
 | 
				
			||||||
@ -218,6 +289,11 @@ def monty_provision( config, args, routers ):
 | 
				
			|||||||
                                print( '/ipv6 address add interface="%s" address="%s" disabled=%s comment="%s" eui-64=yes advertise=yes' % ( vlan[ 'name' ], addr.network, disabled, comment ) )
 | 
					                                print( '/ipv6 address add interface="%s" address="%s" disabled=%s comment="%s" eui-64=yes advertise=yes' % ( vlan[ 'name' ], addr.network, disabled, comment ) )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
 | 
					                        prefix = _extract_bgp_announcement( addr[ 'address' ], addr.get( 'network', None ) )
 | 
				
			||||||
 | 
					                        _adjust_filter( config, api, prefix, args.hostname,
 | 
				
			||||||
 | 
					                                        home = ( name in args.home ),
 | 
				
			||||||
 | 
					                                        standby = ( name not in args.home ) and ( name in args.standby ),
 | 
				
			||||||
 | 
					                                        selector = args.selector, rval = rval )
 | 
				
			||||||
                        if isinstance( addr, ipaddress.IPv4Interface ):
 | 
					                        if isinstance( addr, ipaddress.IPv4Interface ):
 | 
				
			||||||
                            v4addr = { 'interface': vlan[ 'name' ],
 | 
					                            v4addr = { 'interface': vlan[ 'name' ],
 | 
				
			||||||
                                       'disabled': disabled,
 | 
					                                       'disabled': disabled,
 | 
				
			||||||
@ -311,6 +387,158 @@ def monty_teardown( config, args, routers ):
 | 
				
			|||||||
        if args.dry_run:
 | 
					        if args.dry_run:
 | 
				
			||||||
            print()
 | 
					            print()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _extract_bgp_announcement( address, network = None ):
 | 
				
			||||||
 | 
					    addr = ipaddress.ip_interface( address )
 | 
				
			||||||
 | 
					    if isinstance( addr, ipaddress.IPv4Interface ):
 | 
				
			||||||
 | 
					        if addr.network.prefixlen == 32:
 | 
				
			||||||
 | 
					            return ipaddress.ip_interface( network )
 | 
				
			||||||
 | 
					        return addr.network
 | 
				
			||||||
 | 
					    elif isinstance( addr, ipaddress.IPv6Interface ):
 | 
				
			||||||
 | 
					        return addr.network
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def monty_promote( config, args, routers ):
 | 
				
			||||||
 | 
					    for new_home in args.new_home:
 | 
				
			||||||
 | 
					        if new_home not in routers:
 | 
				
			||||||
 | 
					            raise ValueError( 'cannot find new home "%s" in routers' % new_home )
 | 
				
			||||||
 | 
					    for standby in args.standby:
 | 
				
			||||||
 | 
					        if standby not in routers:
 | 
				
			||||||
 | 
					            raise ValueError( 'cannot find new standby "%s" in routers' % standby )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    done_work = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for ( name, api ) in routers.items():
 | 
				
			||||||
 | 
					        vlans = api.path( 'interface', 'vlan' )
 | 
				
			||||||
 | 
					        ip_address = api.path( 'ip', 'address' )
 | 
				
			||||||
 | 
					        ipv6_address = api.path( 'ipv6', 'address' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        spare_vlans = {}
 | 
				
			||||||
 | 
					        for vlan in vlans:
 | 
				
			||||||
 | 
					            if vlan[ 'vlan-id' ] == args.vlan:
 | 
				
			||||||
 | 
					                spare_vlans[ vlan[ 'name' ] ] = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for af in ( ip_address, ipv6_address ):
 | 
				
			||||||
 | 
					            for addr in af:
 | 
				
			||||||
 | 
					                ( sel, rval, hst ) = parse_comment( addr.get( 'comment', '' ) )
 | 
				
			||||||
 | 
					                if sel == args.hostname or hst == args.hostname:
 | 
				
			||||||
 | 
					                    if addr.get( 'disabled', False ):
 | 
				
			||||||
 | 
					                        if ( name in args.standby ) or ( name in args.new_home ):
 | 
				
			||||||
 | 
					                            address = _extract_bgp_announcement( addr[ 'address' ], addr.get( 'network', None ) )
 | 
				
			||||||
 | 
					                            rval = _adjust_filter( config, api, address, hst, selector = sel,
 | 
				
			||||||
 | 
					                                                   home = ( name in args.new_home ),
 | 
				
			||||||
 | 
					                                                   standby = ( name not in args.new_home ) and ( name in args.standby ),
 | 
				
			||||||
 | 
					                                                   static = args.static,
 | 
				
			||||||
 | 
					                                                   rval = rval,
 | 
				
			||||||
 | 
					                                                   )
 | 
				
			||||||
 | 
					                            new_comment = make_comment( sel, rval, hst )
 | 
				
			||||||
 | 
					                            af.update( **{ '.id': addr[ '.id' ],
 | 
				
			||||||
 | 
					                                           'disabled': False,
 | 
				
			||||||
 | 
					                                           'comment': new_comment,
 | 
				
			||||||
 | 
					                                           } )
 | 
				
			||||||
 | 
					                            done_work = True
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        if ( name in args.new_home ):
 | 
				
			||||||
 | 
					                            address = _extract_bgp_announcement( addr[ 'address' ], addr.get( 'network', None ) )
 | 
				
			||||||
 | 
					                            rval = _adjust_filter( config, api, address, hst, selector = sel,
 | 
				
			||||||
 | 
					                                                   home = ( name in args.new_home ),
 | 
				
			||||||
 | 
					                                                   standby = False,
 | 
				
			||||||
 | 
					                                                   static = args.static,
 | 
				
			||||||
 | 
					                                                   rval = rval,
 | 
				
			||||||
 | 
					                                                   )
 | 
				
			||||||
 | 
					                            new_comment = make_comment( sel, rval, hst )
 | 
				
			||||||
 | 
					                            af.update( **{ '.id': addr[ '.id' ],
 | 
				
			||||||
 | 
					                                           'disabled': False,
 | 
				
			||||||
 | 
					                                           'comment': new_comment,
 | 
				
			||||||
 | 
					                                           } )
 | 
				
			||||||
 | 
					                            done_work = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    spare_vlans.pop( addr[ 'interface' ], None )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for vlan in spare_vlans:
 | 
				
			||||||
 | 
					            spare.append( ( name, ip_address, ipv6_address, vlan ) )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if args.create:
 | 
				
			||||||
 | 
					        for ( name, ip_address, ipv6_address, vlan ) in spare:
 | 
				
			||||||
 | 
					            rval = {}
 | 
				
			||||||
 | 
					            disabled = 'yes'
 | 
				
			||||||
 | 
					            if name in args.new_home:
 | 
				
			||||||
 | 
					                rval[ 'home' ] = True
 | 
				
			||||||
 | 
					                disabled = 'no'
 | 
				
			||||||
 | 
					            elif name in args.standby:
 | 
				
			||||||
 | 
					                disabled = 'no'
 | 
				
			||||||
 | 
					            new_comment = make_comment( args.selector, rval, args.hostname )
 | 
				
			||||||
 | 
					            for addr in args.create:
 | 
				
			||||||
 | 
					                rval = _adjust_filter( config, api, addr.network, args.hostname, selector = args.selector,
 | 
				
			||||||
 | 
					                                       home = ( name in args.new_home ),
 | 
				
			||||||
 | 
					                                       standby = ( name not in args.new_home ) and ( name in args.standby ),
 | 
				
			||||||
 | 
					                                       static = args.static,
 | 
				
			||||||
 | 
					                                       rval = rval,
 | 
				
			||||||
 | 
					                                       )
 | 
				
			||||||
 | 
					                if isinstance( addr, ipnetwork.IPv4Interface ):
 | 
				
			||||||
 | 
					                    print( "creating address on interface" )
 | 
				
			||||||
 | 
					                    v4addr = { 'interface': vlan,
 | 
				
			||||||
 | 
					                               'disabled': disabled,
 | 
				
			||||||
 | 
					                               'comment': new_comment,
 | 
				
			||||||
 | 
					                               }
 | 
				
			||||||
 | 
					                    if addr.network.prefixlen == 32:
 | 
				
			||||||
 | 
					                        v4addr[ 'address' ] = config[ 'default_ipv4_loopback' ]
 | 
				
			||||||
 | 
					                        v4addr[ 'network' ] = str( addr.network.network_address )
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        v4addr[ 'address' ] = str( addr )
 | 
				
			||||||
 | 
					                    ip_address.create( **v4addr )
 | 
				
			||||||
 | 
					                    done_work = True
 | 
				
			||||||
 | 
					                elif isinstance( addr, ipnetwork.IPv6Interface ):
 | 
				
			||||||
 | 
					                    print( "creating address on interface" )
 | 
				
			||||||
 | 
					                    v6addr = { 'interface': vlan,
 | 
				
			||||||
 | 
					                               'disabled': disabled,
 | 
				
			||||||
 | 
					                               'comment': comment,
 | 
				
			||||||
 | 
					                               }
 | 
				
			||||||
 | 
					                    if args.static:
 | 
				
			||||||
 | 
					                        v6addr[ 'address' ] = str( addr )
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        v6addr[ 'address' ] = str( addr.network )
 | 
				
			||||||
 | 
					                        v6addr[ 'eui-64' ] = 'yes'
 | 
				
			||||||
 | 
					                        v6addr[ 'advertise' ] = 'yes'
 | 
				
			||||||
 | 
					                    ipv6_address.create( **v6addr )
 | 
				
			||||||
 | 
					                    done_work = True
 | 
				
			||||||
 | 
					    return done_work
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def monty_demote( config, args, routers ):
 | 
				
			||||||
 | 
					    for disable in args.disable:
 | 
				
			||||||
 | 
					        if disable not in routers:
 | 
				
			||||||
 | 
					            raise ValueError( 'cannot find disable "%s" in routers' % disable )
 | 
				
			||||||
 | 
					    for standby in args.standby:
 | 
				
			||||||
 | 
					        if standby not in routers:
 | 
				
			||||||
 | 
					            raise ValueError( 'cannot find standby "%s" in routers' % standby )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    done_work = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for ( name, api ) in routers.items():
 | 
				
			||||||
 | 
					        vlans = api.path( 'interface', 'vlan' )
 | 
				
			||||||
 | 
					        ip_address = api.path( 'ip', 'address' )
 | 
				
			||||||
 | 
					        ipv6_address = api.path( 'ipv6', 'address' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for af in ( ip_address, ipv6_address ):
 | 
				
			||||||
 | 
					            for addr in af:
 | 
				
			||||||
 | 
					                ( sel, rval, hst ) = parse_comment( addr.get( 'comment', '' ) )
 | 
				
			||||||
 | 
					                if sel == args.hostname or hst == args.hostname:
 | 
				
			||||||
 | 
					                    if ( name in args.standby ) or ( name in args.disable ):
 | 
				
			||||||
 | 
					                        address = _extract_bgp_announcement( addr[ 'address' ], addr.get( 'network', None ) )
 | 
				
			||||||
 | 
					                        rval = _adjust_filter( config, api, address, hst, selector = sel,
 | 
				
			||||||
 | 
					                                               home = False,
 | 
				
			||||||
 | 
					                                               standby = ( name in args.standby ),
 | 
				
			||||||
 | 
					                                               rval = rval,
 | 
				
			||||||
 | 
					                                               )
 | 
				
			||||||
 | 
					                        new_comment = make_comment( sel, rval, hst )
 | 
				
			||||||
 | 
					                        af.update( **{ '.id': addr[ '.id' ],
 | 
				
			||||||
 | 
					                                       'disabled': ( name in args.disable ),
 | 
				
			||||||
 | 
					                                       'comment': new_comment,
 | 
				
			||||||
 | 
					                                       } )
 | 
				
			||||||
 | 
					                        done_work = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def monty_migrate( config, args, routers ):
 | 
				
			||||||
 | 
					    if monty_promote( config, args, routers ):
 | 
				
			||||||
 | 
					        monty_demote( config, args, routers )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def load_configuration():
 | 
					def load_configuration():
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        config = open( os.path.expanduser( '~/.automonty.yaml' ), 'r' )
 | 
					        config = open( os.path.expanduser( '~/.automonty.yaml' ), 'r' )
 | 
				
			||||||
@ -339,6 +567,7 @@ def main():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    parser_provision = subparsers.add_parser( 'provision' )
 | 
					    parser_provision = subparsers.add_parser( 'provision' )
 | 
				
			||||||
    parser_provision.add_argument( '--home', action = 'append', default = [] )
 | 
					    parser_provision.add_argument( '--home', action = 'append', default = [] )
 | 
				
			||||||
 | 
					    parser_provision.add_argument( '--standby', action = 'append', default = [] )
 | 
				
			||||||
    parser_provision.add_argument( '-s', '--static', action = 'store_true', default = False )
 | 
					    parser_provision.add_argument( '-s', '--static', action = 'store_true', default = False )
 | 
				
			||||||
    parser_provision.add_argument( '--selector', type = str, default = None )
 | 
					    parser_provision.add_argument( '--selector', type = str, default = None )
 | 
				
			||||||
    parser_provision.add_argument( 'hostname' )
 | 
					    parser_provision.add_argument( 'hostname' )
 | 
				
			||||||
@ -346,6 +575,36 @@ def main():
 | 
				
			|||||||
    parser_provision.add_argument( 'address', type = ipaddress.ip_interface, nargs = "+" )
 | 
					    parser_provision.add_argument( 'address', type = ipaddress.ip_interface, nargs = "+" )
 | 
				
			||||||
    parser_provision.set_defaults( func = monty_provision )
 | 
					    parser_provision.set_defaults( func = monty_provision )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parser_promote = subparsers.add_parser( 'promote' )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( '-e', '--enable', action = 'store_true', default = False )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( '-c', '--create', type = ipaddress.ip_interface, default = [], action = 'append' )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( '-s', '--static', action = 'store_true', default = False )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( '--standby', action = 'append', default = [] )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( '--selector', type = str, default = None )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( 'hostname' )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( 'vlan', type = int )
 | 
				
			||||||
 | 
					    parser_promote.add_argument( 'new_home', nargs = "*" )
 | 
				
			||||||
 | 
					    parser_promote.set_defaults( func = monty_promote )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parser_demote = subparsers.add_parser( 'demote' )
 | 
				
			||||||
 | 
					    parser_demote.add_argument( '--standby', action = 'append', default = [] )
 | 
				
			||||||
 | 
					    parser_demote.add_argument( 'hostname' )
 | 
				
			||||||
 | 
					    parser_demote.add_argument( 'vlan', type = int )
 | 
				
			||||||
 | 
					    parser_demote.add_argument( 'disable', nargs = "*" )
 | 
				
			||||||
 | 
					    parser_demote.set_defaults( func = monty_demote )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parser_migrate = subparsers.add_parser( 'migrate' )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '-e', '--enable', action = 'store_true', default = False )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '-c', '--create', type = ipaddress.ip_interface, default = [], action = 'append' )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '-s', '--static', action = 'store_true', default = False )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '--selector', type = str, default = None )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '--standby', action = 'append', default = [] )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( '--disable', action = 'append', default = [] )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( 'hostname' )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( 'vlan', type = int )
 | 
				
			||||||
 | 
					    parser_migrate.add_argument( 'new_home', nargs = "*" )
 | 
				
			||||||
 | 
					    parser_migrate.set_defaults( func = monty_migrate )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    parser_teardown = subparsers.add_parser( 'teardown' )
 | 
					    parser_teardown = subparsers.add_parser( 'teardown' )
 | 
				
			||||||
    parser_teardown.add_argument( '--delete', action = 'store_true', default = False )
 | 
					    parser_teardown.add_argument( '--delete', action = 'store_true', default = False )
 | 
				
			||||||
    parser_teardown.add_argument( 'hostname' )
 | 
					    parser_teardown.add_argument( 'hostname' )
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user