@ -17,10 +17,11 @@
#
#
ANSIBLE_METADATA = { ' metadata_version ' : ' 1.0 ' ,
ANSIBLE_METADATA = {
' status ' : [ ' preview ' ] ,
' metadata_version ' : ' 1.0 ' ,
' supported_by ' : ' community ' }
' status ' : [ ' preview ' ] ,
' supported_by ' : ' community '
}
DOCUMENTATION = '''
DOCUMENTATION = '''
- - -
- - -
@ -29,60 +30,60 @@ extends_documentation_fragment: nxos
version_added : " 2.2 "
version_added : " 2.2 "
short_description : Manages HSRP configuration on NX - OS switches .
short_description : Manages HSRP configuration on NX - OS switches .
description :
description :
- Manages HSRP configuration on NX - OS switches .
- Manages HSRP configuration on NX - OS switches .
author :
author :
- Jason Edelman ( @jedelman8 )
- Jason Edelman ( @jedelman8 )
- Gabriele Gerbino ( @GGabriele )
- Gabriele Gerbino ( @GGabriele )
notes :
notes :
- HSRP feature needs to be enabled first on the system .
- HSRP feature needs to be enabled first on the system .
- SVIs must exist before using this module .
- SVIs must exist before using this module .
- Interface must be a L3 port before using this module .
- Interface must be a L3 port before using this module .
- HSRP cannot be configured on loopback interfaces .
- HSRP cannot be configured on loopback interfaces .
- MD5 authentication is only possible with HSRPv2 while it is ignored if
- MD5 authentication is only possible with HSRPv2 while it is ignored if
HSRPv1 is used instead , while it will not raise any error . Here we allow
HSRPv1 is used instead , while it will not raise any error . Here we allow
MD5 authentication only with HSRPv2 in order to enforce better practice .
MD5 authentication only with HSRPv2 in order to enforce better practice .
options :
options :
group :
group :
description :
description :
- HSRP group number .
- HSRP group number .
required : true
required : true
interface :
interface :
description :
description :
- Full name of interface that is being managed for HSRP .
- Full name of interface that is being managed for HSRP .
required : true
required : true
version :
version :
description :
description :
- HSRP version .
- HSRP version .
required : false
required : false
default : 2
default : 2
choices : [ ' 1 ' , ' 2 ' ]
choices : [ ' 1 ' , ' 2 ' ]
priority :
priority :
description :
description :
- HSRP priority .
- HSRP priority .
required : false
required : false
default : null
default : null
vip :
vip :
description :
description :
- HSRP virtual IP address .
- HSRP virtual IP address .
required : false
required : false
default : null
default : null
auth_string :
auth_string :
description :
description :
- Authentication string .
- Authentication string .
required : false
required : false
default : null
default : null
auth_type :
auth_type :
description :
description :
- Authentication type .
- Authentication type .
required : false
required : false
default : null
default : null
choices : [ ' text ' , ' md5 ' ]
choices : [ ' text ' , ' md5 ' ]
state :
state :
description :
description :
- Specify desired state of the resource .
- Specify desired state of the resource .
required : false
required : false
choices : [ ' present ' , ' absent ' ]
choices : [ ' present ' , ' absent ' ]
default : ' present '
default : ' present '
'''
'''
EXAMPLES = '''
EXAMPLES = '''
@ -116,42 +117,19 @@ EXAMPLES = '''
'''
'''
RETURN = '''
RETURN = '''
proposed :
commands :
description : k / v pairs of parameters passed into module
returned : always
type : dict
sample : { " group " : " 30 " , " version " : " 2 " , " vip " : " 10.30.1.1 " }
existing :
description : k / v pairs of existing hsrp info on the interface
returned : always
type : dict
sample : { }
end_state :
description : k / v pairs of hsrp after module execution
returned : always
type : dict
sample : { " auth_string " : " cisco " , " auth_type " : " text " ,
" group " : " 30 " , " interface " : " vlan10 " , " preempt " : " disabled " ,
" priority " : " 100 " , " version " : " 2 " , " vip " : " 10.30.1.1 " }
updates :
description : commands sent to the device
description : commands sent to the device
returned : always
returned : always
type : list
type : list
sample : [ " interface vlan10 " , " hsrp version 2 " , " hsrp 30 " , " ip 10.30.1.1 " ]
sample : [ " interface vlan10 " , " hsrp version 2 " , " hsrp 30 " , " ip 10.30.1.1 " ]
changed :
description : check to see if a change was made on the device
returned : always
type : boolean
sample : true
'''
'''
from ansible . module_utils . nxos import get_config, load_config, run_commands
from ansible . module_utils . nxos import load_config , run_commands
from ansible . module_utils . nxos import nxos_argument_spec , check_args
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
def execute_show_command ( command , module ) :
def execute_show_command ( command , module , command_type = ' cli_show ' ) :
if module . params [ ' transport ' ] == ' cli ' :
if module . params [ ' transport ' ] == ' cli ' :
command + = ' | json '
command + = ' | json '
cmds = [ command ]
cmds = [ command ]
@ -165,7 +143,7 @@ def execute_show_command(command, module, command_type='cli_show'):
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 )
value = table . get ( key )
@ -197,9 +175,12 @@ def get_interface_mode(interface, intf_type, module):
command = ' show interface {0} ' . format ( interface )
command = ' show interface {0} ' . format ( interface )
interface = { }
interface = { }
mode = ' unknown '
mode = ' unknown '
try :
body = execute_show_command ( command , module ) [ 0 ]
except IndexError :
return None
if intf_type in [ ' ethernet ' , ' portchannel ' ] :
if intf_type in [ ' ethernet ' , ' portchannel ' ] :
body = execute_show_command ( command , module ) [ 0 ]
interface_table = body [ ' TABLE_interface ' ] [ ' ROW_interface ' ]
interface_table = body [ ' TABLE_interface ' ] [ ' ROW_interface ' ]
mode = str ( interface_table . get ( ' eth_mode ' , ' layer3 ' ) )
mode = str ( interface_table . get ( ' eth_mode ' , ' layer3 ' ) )
if mode == ' access ' or mode == ' trunk ' :
if mode == ' access ' or mode == ' trunk ' :
@ -211,12 +192,12 @@ def get_interface_mode(interface, intf_type, module):
def get_hsrp_groups_on_interfaces ( device , module ) :
def get_hsrp_groups_on_interfaces ( device , module ) :
command = ' show hsrp all '
command = ' show hsrp all '
body = execute_show_command ( command , module )
hsrp = { }
hsrp = { }
try :
try :
get_data = body [ 0 ] [ ' TABLE_grp_detail ' ] [ ' ROW_grp_detail ' ]
body = execute_show_command ( command , module ) [ 0 ]
except ( KeyError , AttributeError ) :
get_data = body [ ' TABLE_grp_detail ' ] [ ' ROW_grp_detail ' ]
except ( IndexError , KeyError , AttributeError ) :
return { }
return { }
for entry in get_data :
for entry in get_data :
@ -232,7 +213,6 @@ def get_hsrp_groups_on_interfaces(device, module):
def get_hsrp_group ( group , interface , module ) :
def get_hsrp_group ( group , interface , module ) :
command = ' show hsrp group {0} ' . format ( group )
command = ' show hsrp group {0} ' . format ( group )
body = execute_show_command ( command , module )
hsrp = { }
hsrp = { }
hsrp_key = {
hsrp_key = {
@ -247,7 +227,8 @@ def get_hsrp_group(group, interface, module):
}
}
try :
try :
hsrp_table = body [ 0 ] [ ' TABLE_grp_detail ' ] [ ' ROW_grp_detail ' ]
body = execute_show_command ( command , module ) [ 0 ]
hsrp_table = body [ ' TABLE_grp_detail ' ] [ ' ROW_grp_detail ' ]
except ( AttributeError , IndexError , TypeError ) :
except ( AttributeError , IndexError , TypeError ) :
return { }
return { }
@ -271,9 +252,7 @@ def get_hsrp_group(group, interface, module):
def get_commands_remove_hsrp ( group , interface ) :
def get_commands_remove_hsrp ( group , interface ) :
commands = [ ]
commands = [ ' interface {0} ' . format ( interface ) , ' no hsrp {0} ' . format ( group ) ]
commands . append ( ' interface {0} ' . format ( interface ) )
commands . append ( ' no hsrp {0} ' . format ( group ) )
return commands
return commands
@ -295,7 +274,7 @@ def get_commands_config_hsrp(delta, interface, args):
elif preempt == ' disabled ' :
elif preempt == ' disabled ' :
delta [ ' preempt ' ] = ' no preempt '
delta [ ' preempt ' ] = ' no preempt '
for key , value in delta . items ( ) :
for key in delta :
command = config_args . get ( key , ' DNE ' ) . format ( * * delta )
command = config_args . get ( key , ' DNE ' ) . format ( * * delta )
if command and command != ' DNE ' :
if command and command != ' DNE ' :
if key == ' group ' :
if key == ' group ' :
@ -391,13 +370,11 @@ def main():
interface = dict ( required = True ) ,
interface = dict ( required = True ) ,
version = dict ( choices = [ ' 1 ' , ' 2 ' ] , default = ' 2 ' , required = False ) ,
version = dict ( choices = [ ' 1 ' , ' 2 ' ] , default = ' 2 ' , required = False ) ,
priority = dict ( type = ' str ' , required = False ) ,
priority = dict ( type = ' str ' , required = False ) ,
preempt = dict ( type = ' str ' , choices = [ ' disabled ' , ' enabled ' ] ,
preempt = dict ( type = ' str ' , choices = [ ' disabled ' , ' enabled ' ] , required = False ) ,
required = False ) ,
vip = dict ( type = ' str ' , required = False ) ,
vip = dict ( type = ' str ' , required = False ) ,
auth_type = dict ( choices = [ ' text ' , ' md5 ' ] , required = False ) ,
auth_type = dict ( choices = [ ' text ' , ' md5 ' ] , required = False ) ,
auth_string = dict ( type = ' str ' , required = False ) ,
auth_string = dict ( type = ' str ' , required = False ) ,
state = dict ( choices = [ ' absent ' , ' present ' ] , required = False ,
state = dict ( choices = [ ' absent ' , ' present ' ] , required = False , default = ' present ' ) ,
default = ' present ' ) ,
include_defaults = dict ( default = True ) ,
include_defaults = dict ( default = True ) ,
config = dict ( ) ,
config = dict ( ) ,
save = dict ( type = ' bool ' , default = False )
save = dict ( type = ' bool ' , default = False )
@ -405,12 +382,11 @@ 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 )
results = dict ( changed = False , warnings = warnings )
interface = module . params [ ' interface ' ] . lower ( )
interface = module . params [ ' interface ' ] . lower ( )
group = module . params [ ' group ' ]
group = module . params [ ' group ' ]
@ -470,8 +446,6 @@ def main():
module . fail_json ( msg = " Existing auth_type is md5. It ' s recommended "
module . fail_json ( msg = " Existing auth_type is md5. It ' s recommended "
" to use HSRP v2 when using md5 " )
" to use HSRP v2 when using md5 " )
changed = False
end_state = existing
commands = [ ]
commands = [ ]
if state == ' present ' :
if state == ' present ' :
delta = dict (
delta = dict (
@ -487,28 +461,20 @@ def main():
if commands :
if commands :
if module . check_mode :
if module . check_mode :
module . exit_json ( changed = True , commands = command s)
module . exit_json ( * * result s)
else :
else :
load_config ( module , commands )
load_config ( module , commands )
if transport == ' cli ' :
if transport == ' cli ' :
body = run_commands ( module , commands )
body = run_commands ( module , commands )
validate_config ( body , vip , module )
validate_config ( body , vip , module )
changed = True
results[ ' changed' ] = True
end_state = get_hsrp_group ( group , interface , module )
end_state = get_hsrp_group ( group , interface , module )
if ' configure ' in commands :
if ' configure ' in commands :
commands . pop ( 0 )
commands . pop ( 0 )
results = { }
results [ ' commands ' ] = commands
results [ ' proposed ' ] = proposed
results [ ' existing ' ] = existing
results [ ' end_state ' ] = end_state
results [ ' updates ' ] = commands
results [ ' changed ' ] = changed
results [ ' warnings ' ] = warnings
module . exit_json ( * * results )
module . exit_json ( * * results )
if __name__ == ' __main__ ' :
if __name__ == ' __main__ ' :
main ( )
main ( )