@ -16,10 +16,11 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
#
ANSIBLE_METADATA = { ' metadata_version ' : ' 1.0 ' ,
ANSIBLE_METADATA = {
' status ' : [ ' preview ' ] ,
' metadata_version ' : ' 1.0 ' ,
' supported_by ' : ' community ' }
' status ' : [ ' preview ' ] ,
' supported_by ' : ' community '
}
DOCUMENTATION = '''
DOCUMENTATION = '''
- - -
- - -
@ -28,81 +29,60 @@ extends_documentation_fragment: nxos
version_added : " 2.2 "
version_added : " 2.2 "
short_description : Manages VRF AF .
short_description : Manages VRF AF .
description :
description :
- Manages VRF AF
- Manages VRF AF
author : Gabriele Gerbino ( @GGabriele )
author : Gabriele Gerbino ( @GGabriele )
notes :
notes :
- Default , where supported , restores params default value .
- Default , where supported , restores params default value .
options :
options :
vrf :
vrf :
description :
description :
- Name of the VRF .
- Name of the VRF .
required : true
required : true
afi :
afi :
description :
description :
- Address - Family Identifier ( AFI ) .
- Address - Family Identifier ( AFI ) .
required : true
required : true
choices : [ ' ipv4 ' , ' ipv6 ' ]
choices : [ ' ipv4 ' , ' ipv6 ' ]
default : null
default : null
safi :
safi :
description :
description :
- Sub Address - Family Identifier ( SAFI ) .
- Sub Address - Family Identifier ( SAFI ) .
required : true
required : true
choices : [ ' unicast ' , ' multicast ' ]
choices : [ ' unicast ' , ' multicast ' ]
default : null
default : null
route_target_both_auto_evpn :
route_target_both_auto_evpn :
description :
description :
- Enable / Disable the EVPN route - target ' auto ' setting for both
- Enable / Disable the EVPN route - target ' auto ' setting for both
import and export target communities .
import and export target communities .
required : false
required : false
choices : [ ' true ' , ' false ' ]
choices : [ ' true ' , ' false ' ]
default : null
default : null
state :
state :
description :
description :
- Determines whether the config should be present or
- Determines whether the config should be present or
not on the device .
not on the device .
required : false
required : false
default : present
default : present
choices : [ ' present ' , ' absent ' ]
choices : [ ' present ' , ' absent ' ]
'''
'''
EXAMPLES = '''
EXAMPLES = '''
- nxos_vrf_af :
- nxos_vrf_af :
interface : nve1
vrf : ntc
vni : 6000
afi : ipv4
ingress_replication : true
safi : unicast
username : " {{ un }} "
route_target_both_auto_evpn : True
password : " {{ pwd }} "
state : present
host : " {{ inventory_hostname }} "
'''
'''
RETURN = '''
RETURN = '''
proposed :
commands :
description : k / v pairs of parameters passed into module
returned : verbose mode
type : dict
sample : { " afi " : " ipv4 " , " route_target_both_auto_evpn " : true ,
" safi " : " unicast " , " vrf " : " test " }
existing :
description : k / v pairs of existing configuration
returned : verbose mode
type : dict
sample : { " afi " : " ipv4 " , " route_target_both_auto_evpn " : false ,
" safi " : " unicast " , " vrf " : " test " }
end_state :
description : k / v pairs of configuration after module execution
returned : verbose mode
type : dict
sample : { " afi " : " ipv4 " , " route_target_both_auto_evpn " : true ,
" safi " : " unicast " , " vrf " : " test " }
updates :
description : commands sent to the device
description : commands sent to the device
returned : always
returned : always
type : list
type : list
sample : [ " vrf context test " , " address-family ipv4 unicast " ,
sample : [ " vrf context ntc " , " address-family ipv4 unicast " ,
" route-target both auto evpn " ]
" afi ipv4 " , " route-target both auto evpn " , " vrf ntc " ,
changed :
" safi unicast " ]
description : check to see if a change was made on the device
returned : always
type : boolean
sample : true
'''
'''
import re
import re
@ -112,33 +92,32 @@ from ansible.module_utils.nxos import nxos_argument_spec, check_args
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . basic import AnsibleModule
from ansible . module_utils . netcfg import CustomNetworkConfig
from ansible . module_utils . netcfg import CustomNetworkConfig
BOOL_PARAMS = [ ' route_target_both_auto_evpn ' ]
BOOL_PARAMS = [ ' route_target_both_auto_evpn ' ]
PARAM_TO_COMMAND_KEYMAP = {
PARAM_TO_COMMAND_KEYMAP = {
' route_target_both_auto_evpn ' : ' route-target both auto evpn ' ,
' vrf ' : ' vrf ' ,
' safi ' : ' safi ' ,
' afi ' : ' afi ' ,
' route_target_both_auto_evpn ' : ' route-target both auto evpn '
}
}
PARAM_TO_DEFAULT_KEYMAP = { }
PARAM_TO_DEFAULT_KEYMAP = { }
WARNINGS = [ ]
def invoke ( name , * args , * * kwargs ) :
func = globals ( ) . get ( name )
if func :
return func ( * args , * * kwargs )
def get_value ( arg , config , module ) :
def get_value ( arg , config , module ) :
command = PARAM_TO_COMMAND_KEYMAP . get ( arg )
if arg in BOOL_PARAMS :
if arg in BOOL_PARAMS :
REGEX = re . compile ( r ' \ s+ {0} \ s*$ ' . format ( PARAM_TO_COMMAND_KEYMAP[ arg ] ) , re . M )
command_re = re . compile ( r ' \ s+ {0} \ s*$ ' . format ( command ) , re . M )
value = False
value = False
try :
try :
if REGEX . search ( config ) :
if command_re . search ( config ) :
value = True
value = True
except TypeError :
except TypeError :
value = False
value = False
else :
else :
REGEX = re . compile ( r ' (?: {0} \ s)(?P<value>.*)$ ' . format ( PARAM_TO_COMMAND_KEYMAP[ arg ] ) , re . M )
command_re = re . compile ( r ' (?: {0} \ s)(?P<value>.*)$ ' . format ( command ) , re . M )
value = ' '
value = ' '
if PARAM_TO_COMMAND_KEYMAP[ arg ] in config :
if command in config :
value = REGEX . search ( config ) . group ( ' value ' )
value = command_re . search ( config ) . group ( ' value ' )
return value
return value
@ -148,7 +127,7 @@ def get_existing(module, args):
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
parents . append ( ' address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
parents . append ( ' address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
module . params [ ' safi ' ] ) )
module . params [ ' safi ' ] ) )
config = netcfg . get_section ( parents )
config = netcfg . get_section ( parents )
if config :
if config :
splitted_config = config . splitlines ( )
splitted_config = config . splitlines ( )
@ -173,14 +152,10 @@ def get_existing(module, args):
def apply_key_map ( key_map , table ) :
def apply_key_map ( key_map , table ) :
new_dict = { }
new_dict = { }
for key , value in table . items ( ) :
for key in table :
new_key = key_map . get ( key )
new_key = key_map . get ( key )
if new_key :
if new_key :
value = table . get ( key )
new_dict [ new_key ] = table . get ( key )
if value :
new_dict [ new_key ] = value
else :
new_dict [ new_key ] = value
return new_dict
return new_dict
@ -207,7 +182,7 @@ def state_present(module, existing, proposed, candidate):
if commands :
if commands :
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
parents . append ( ' address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
parents . append ( ' address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
module . params [ ' safi ' ] ) )
module . params [ ' safi ' ] ) )
candidate . add ( commands , parents = parents )
candidate . add ( commands , parents = parents )
@ -215,19 +190,18 @@ def state_absent(module, existing, proposed, candidate):
commands = [ ]
commands = [ ]
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
parents = [ ' vrf context {0} ' . format ( module . params [ ' vrf ' ] ) ]
commands . append ( ' no address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
commands . append ( ' no address-family {0} {1} ' . format ( module . params [ ' afi ' ] ,
module . params [ ' safi ' ] ) )
module . params [ ' safi ' ] ) )
candidate . add ( commands , parents = parents )
candidate . add ( commands , parents = parents )
def main ( ) :
def main ( ) :
argument_spec = dict (
argument_spec = dict (
vrf = dict ( required = True , type = ' str ' ) ,
vrf = dict ( required = True , type = ' str ' ) ,
safi = dict ( required = True , type = ' str ' , choices = [ ' unicast ' , ' multicast ' ] ) ,
safi = dict ( required = True , type = ' str ' , choices = [ ' unicast ' , ' multicast ' ] ) ,
afi = dict ( required = True , type = ' str ' , choices = [ ' ipv4 ' , ' ipv6 ' ] ) ,
afi = dict ( required = True , type = ' str ' , choices = [ ' ipv4 ' , ' ipv6 ' ] ) ,
route_target_both_auto_evpn = dict ( required = False , type = ' bool ' ) ,
route_target_both_auto_evpn = dict ( required = False , type = ' bool ' ) ,
m_facts = dict ( required = False , default = False , type = ' bool ' ) ,
m_facts = dict ( required = False , default = False , type = ' bool ' ) ,
state = dict ( choices = [ ' present ' , ' absent ' ] , default = ' present ' ,
state = dict ( choices = [ ' present ' , ' absent ' ] , default = ' present ' , required = False ) ,
required = False ) ,
include_defaults = dict ( default = False ) ,
include_defaults = dict ( default = False ) ,
config = dict ( ) ,
config = dict ( ) ,
save = dict ( type = ' bool ' , default = False )
save = dict ( type = ' bool ' , default = False )
@ -235,26 +209,17 @@ def main():
argument_spec . update ( nxos_argument_spec )
argument_spec . update ( nxos_argument_spec )
module = AnsibleModule ( argument_spec = argument_spec ,
module = AnsibleModule ( argument_spec = argument_spec , supports_check_mode = True )
supports_check_mode = True )
warnings = list ( )
warnings = list ( )
check_args ( module , warnings )
check_args ( module , warnings )
result = dict ( changed = False , warnings = warnings )
state = module . params [ ' state ' ]
state = module . params [ ' state ' ]
args = PARAM_TO_COMMAND_KEYMAP . keys ( )
args = [
existing = get_existing ( module , args )
' vrf ' ,
' safi ' ,
' afi ' ,
' route_target_both_auto_evpn '
]
existing = invoke ( ' get_existing ' , module , args )
end_state = existing
proposed_args = dict ( ( k , v ) for k , v in module . params . items ( )
proposed_args = dict ( ( k , v ) for k , v in module . params . items ( )
if v is not None and k in args )
if v is not None and k in args )
proposed = { }
proposed = { }
for key , value in proposed_args . items ( ) :
for key , value in proposed_args . items ( ) :
@ -263,31 +228,24 @@ def main():
value = PARAM_TO_DEFAULT_KEYMAP . get ( key )
value = PARAM_TO_DEFAULT_KEYMAP . get ( key )
if value is None :
if value is None :
value = ' default '
value = ' default '
if existing . get ( key ) or ( not existing . get ( key ) and value ) :
if existing . get ( key ) != value :
proposed [ key ] = value
proposed [ key ] = value
result = { }
candidate = CustomNetworkConfig ( indent = 3 )
if state == ' present ' or ( state == ' absent ' and existing ) :
if state == ' present ' :
candidate = CustomNetworkConfig ( indent = 3 )
state_present ( module , existing , proposed , candidate )
invoke ( ' state_ %s ' % state , module , existing , proposed , candidate )
elif state == ' absent ' and existing :
response = load_config ( module , candidate )
state_absent ( module , existing , proposed , candidate )
result . update ( response )
else :
result [ ' updates ' ] = [ ]
if module . _verbosity > 0 :
if candidate :
end_state = invoke ( ' get_existing ' , module , args )
load_config ( module , candidate )
result [ ' end_state ' ] = end_state
result [ ' changed ' ] = True
result [ ' existing ' ] = existing
result [ ' commands ' ] = candidate . items_text ( )
result [ ' proposed ' ] = proposed_args
if WARNINGS :
result [ ' warnings ' ] = WARNINGS
else :
result [ ' commands ' ] = [ ]
module . exit_json ( * * result )
module . exit_json ( * * result )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
main ( )
main ( )