@ -48,17 +48,22 @@ class TestNxosL3InterfacesModule(TestNxosModule):
self . mock_edit_config = patch ( ' ansible.module_utils.network.nxos.config.l3_interfaces.l3_interfaces.L3_interfaces.edit_config ' )
self . edit_config = self . mock_edit_config . start ( )
self . mock_get_platform_type = patch ( ' ansible.module_utils.network.nxos.config.l3_interfaces.l3_interfaces.L3_interfaces.get_platform_type ' )
self . get_platform_type = self . mock_get_platform_type . start ( )
def tearDown ( self ) :
super ( TestNxosL3InterfacesModule , self ) . tearDown ( )
self . mock_FACT_LEGACY_SUBSETS . stop ( )
self . mock_get_resource_connection_config . stop ( )
self . mock_get_resource_connection_facts . stop ( )
self . mock_edit_config . stop ( )
self . mock_get_platform_type . stop ( )
def load_fixtures ( self , commands = None , device = ' ') :
def load_fixtures ( self , commands = None , device = ' N9K ') :
self . mock_FACT_LEGACY_SUBSETS . return_value = dict ( )
self . get_resource_connection_config . return_value = None
self . edit_config . return_value = None
self . get_platform_type . return_value = device
# ---------------------------
# L3_interfaces Test Cases
@ -85,7 +90,7 @@ class TestNxosL3InterfacesModule(TestNxosModule):
self . execute_module ( { ' failed ' : True , ' msg ' : " The ' mgmt0 ' interface is not allowed to be managed by this module " } )
def test_2 ( self ) :
# Change existing config state s
# basic test s
existing = dedent ( ''' \
interface mgmt0
ip address 10.0 .0 .254 / 24
@ -109,12 +114,336 @@ class TestNxosL3InterfacesModule(TestNxosModule):
merged = [ ' interface Ethernet1/1 ' , ' ip address 192.168.1.1/24 ' ]
deleted = [ ' interface Ethernet1/1 ' , ' no ip address ' ,
' interface Ethernet1/2 ' , ' no ip address ' ]
overridden = [ ' interface Ethernet1/1 ' , ' no ip address ' ,
' interface Ethernet1/2 ' , ' no ip address ' ,
' interface Ethernet1/3 ' , ' no ip address ' ,
' interface Ethernet1/1 ' , ' ip address 192.168.1.1/24 ' ]
replaced = [ ' interface Ethernet1/1 ' , ' no ip address ' , ' ip address 192.168.1.1/24 ' ,
replaced = [ ' interface Ethernet1/1 ' , ' ip address 192.168.1.1/24 ' ,
' interface Ethernet1/2 ' , ' no ip address ' ]
overridden = [ ' interface Ethernet1/1 ' , ' ip address 192.168.1.1/24 ' ,
' interface Ethernet1/2 ' , ' no ip address ' ,
' interface Ethernet1/3 ' , ' no ip address ' ]
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = merged )
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden )
def test_3 ( self ) :
# encap testing
existing = dedent ( ''' \
interface mgmt0
ip address 10.0 .0 .254 / 24
interface Ethernet1 / 1.41
encapsulation dot1q 4100
ip address 10.1 .1 .1 / 24
interface Ethernet1 / 1.42
encapsulation dot1q 42
interface Ethernet1 / 1.44
encapsulation dot1q 44
interface Ethernet1 / 1.45
encapsulation dot1q 45
ip address 10.5 .5 .5 / 24
ipv6 address 10 : : 5 / 128
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/1.41 ' , dot1q = 41 , ipv4 = [ { ' address ' : ' 10.2.2.2/24 ' } ] ) ,
dict ( name = ' Ethernet1/1.42 ' , dot1q = 42 ) ,
dict ( name = ' Ethernet1/1.43 ' , dot1q = 43 , ipv6 = [ { ' address ' : ' 10::2/128 ' } ] ) ,
dict ( name = ' Ethernet1/1.44 ' )
] )
# Expected result commands for each 'state'
merged = [
' interface Ethernet1/1.41 ' , ' encapsulation dot1q 41 ' , ' ip address 10.2.2.2/24 ' ,
' interface Ethernet1/1.43 ' , ' encapsulation dot1q 43 ' , ' ipv6 address 10::2/128 ' ,
]
deleted = [
' interface Ethernet1/1.41 ' , ' no encapsulation dot1q ' , ' no ip address ' ,
' interface Ethernet1/1.42 ' , ' no encapsulation dot1q ' ,
' interface Ethernet1/1.44 ' , ' no encapsulation dot1q '
]
replaced = [
' interface Ethernet1/1.41 ' , ' encapsulation dot1q 41 ' , ' ip address 10.2.2.2/24 ' ,
# 42 no chg
' interface Ethernet1/1.43 ' , ' encapsulation dot1q 43 ' , ' ipv6 address 10::2/128 ' ,
' interface Ethernet1/1.44 ' , ' no encapsulation dot1q '
]
overridden = [
' interface Ethernet1/1.41 ' , ' encapsulation dot1q 41 ' , ' ip address 10.2.2.2/24 ' ,
# 42 no chg
' interface Ethernet1/1.44 ' , ' no encapsulation dot1q ' ,
' interface Ethernet1/1.45 ' , ' no encapsulation dot1q ' , ' no ip address ' , ' no ipv6 address ' ,
' interface Ethernet1/1.43 ' , ' encapsulation dot1q 43 ' , ' ipv6 address 10::2/128 '
]
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = merged )
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden )
def test_4 ( self ) :
# IPv4-centric testing
existing = dedent ( ''' \
interface mgmt0
ip address 10.0 .0 .254 / 24
interface Ethernet1 / 1
no ip redirects
ip address 10.1 .1 .1 / 24 tag 11
ip address 10.2 .2 .2 / 24 secondary tag 12
ip address 10.3 .3 .3 / 24 secondary
ip address 10.4 .4 .4 / 24 secondary tag 14
ip address 10.5 .5 .5 / 24 secondary tag 15
ip address 10.6 .6 .6 / 24 secondary tag 16
interface Ethernet1 / 2
ip address 10.12 .12 .12 / 24
interface Ethernet1 / 3
ip address 10.13 .13 .13 / 24
interface Ethernet1 / 5
no ip redirects
ip address 10.15 .15 .15 / 24
ip address 10.25 .25 .25 / 24 secondary
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/1 ' ,
ipv4 = [ { ' address ' : ' 10.1.1.1/24 ' , ' secondary ' : True } , # prim->sec
{ ' address ' : ' 10.2.2.2/24 ' , ' secondary ' : True } , # rmv tag
{ ' address ' : ' 10.3.3.3/24 ' , ' tag ' : 3 } , # become prim
{ ' address ' : ' 10.4.4.4/24 ' , ' secondary ' : True , ' tag ' : 14 } , # no chg
{ ' address ' : ' 10.5.5.5/24 ' , ' secondary ' : True , ' tag ' : 55 } , # chg tag
{ ' address ' : ' 10.7.7.7/24 ' , ' secondary ' : True , ' tag ' : 77 } ] ) , # new ip
dict ( name = ' Ethernet1/2 ' ) ,
dict ( name = ' Ethernet1/4 ' ,
ipv4 = [ { ' address ' : ' 10.40.40.40/24 ' } ,
{ ' address ' : ' 10.41.41.41/24 ' , ' secondary ' : True } ] ) ,
dict ( name = ' Ethernet1/5 ' ) ,
] )
# Expected result commands for each 'state'
merged = [
' interface Ethernet1/1 ' ,
' no ip address 10.5.5.5/24 secondary ' ,
' no ip address 10.2.2.2/24 secondary ' ,
' no ip address 10.3.3.3/24 secondary ' ,
' ip address 10.3.3.3/24 tag 3 ' , # Changes primary
' ip address 10.1.1.1/24 secondary ' ,
' ip address 10.2.2.2/24 secondary ' ,
' ip address 10.7.7.7/24 secondary tag 77 ' ,
' ip address 10.5.5.5/24 secondary tag 55 ' ,
' interface Ethernet1/4 ' ,
' ip address 10.40.40.40/24 ' ,
' ip address 10.41.41.41/24 secondary '
]
deleted = [
' interface Ethernet1/1 ' , ' no ip address ' ,
' interface Ethernet1/2 ' , ' no ip address ' ,
' interface Ethernet1/5 ' , ' no ip address '
]
replaced = [
' interface Ethernet1/1 ' ,
' no ip address 10.5.5.5/24 secondary ' ,
' no ip address 10.2.2.2/24 secondary ' ,
' no ip address 10.3.3.3/24 secondary ' ,
' ip address 10.3.3.3/24 tag 3 ' , # Changes primary
' ip address 10.1.1.1/24 secondary ' ,
' ip address 10.2.2.2/24 secondary ' ,
' ip address 10.7.7.7/24 secondary tag 77 ' ,
' ip address 10.5.5.5/24 secondary tag 55 ' ,
' interface Ethernet1/2 ' ,
' no ip address ' ,
' interface Ethernet1/4 ' ,
' ip address 10.40.40.40/24 ' ,
' ip address 10.41.41.41/24 secondary ' ,
' interface Ethernet1/5 ' ,
' no ip address '
]
overridden = [
' interface Ethernet1/1 ' ,
' no ip address 10.6.6.6/24 secondary ' ,
' no ip address 10.5.5.5/24 secondary ' ,
' no ip address 10.2.2.2/24 secondary ' ,
' no ip address 10.3.3.3/24 secondary ' ,
' ip address 10.3.3.3/24 tag 3 ' , # Changes primary
' ip address 10.1.1.1/24 secondary ' ,
' ip address 10.2.2.2/24 secondary ' ,
' ip address 10.7.7.7/24 secondary tag 77 ' ,
' ip address 10.5.5.5/24 secondary tag 55 ' ,
' interface Ethernet1/2 ' ,
' no ip address ' ,
' interface Ethernet1/3 ' ,
' no ip address ' ,
' interface Ethernet1/4 ' ,
' ip address 10.40.40.40/24 ' ,
' ip address 10.41.41.41/24 secondary ' ,
' interface Ethernet1/5 ' ,
' no ip address ' ,
]
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = merged )
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden )
def test_5 ( self ) :
# IPv6-centric testing
existing = dedent ( ''' \
interface Ethernet1 / 1
ipv6 address 10 : : 1 / 128
ipv6 address 10 : : 2 / 128 tag 12
ipv6 address 10 : : 3 / 128 tag 13
ipv6 address 10 : : 4 / 128 tag 14
interface Ethernet1 / 2
ipv6 address 10 : : 12 / 128
interface Ethernet1 / 3
ipv6 address 10 : : 13 / 128
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/1 ' ,
ipv6 = [ { ' address ' : ' 10::1/128 ' } , # no chg
{ ' address ' : ' 10::3/128 ' } , # tag rmv
{ ' address ' : ' 10::4/128 ' , ' tag ' : 44 } , # tag chg
{ ' address ' : ' 10::5/128 ' } , # new addr
{ ' address ' : ' 10::6/128 ' , ' tag ' : 66 } ] ) , # new addr+tag
dict ( name = ' Ethernet1/2 ' ) ,
] )
# Expected result commands for each 'state'
merged = [
' interface Ethernet1/1 ' ,
' ipv6 address 10::4/128 tag 44 ' ,
' ipv6 address 10::5/128 ' ,
' ipv6 address 10::6/128 tag 66 ' ,
]
deleted = [
' interface Ethernet1/1 ' , ' no ipv6 address ' ,
' interface Ethernet1/2 ' , ' no ipv6 address ' ,
]
replaced = [
' interface Ethernet1/1 ' ,
' no ipv6 address 10::3/128 ' ,
' no ipv6 address 10::2/128 ' ,
' ipv6 address 10::4/128 tag 44 ' ,
' ipv6 address 10::3/128 ' ,
' ipv6 address 10::5/128 ' ,
' ipv6 address 10::6/128 tag 66 ' ,
' interface Ethernet1/2 ' ,
' no ipv6 address 10::12/128 '
]
overridden = [
' interface Ethernet1/1 ' ,
' no ipv6 address 10::3/128 ' ,
' no ipv6 address 10::2/128 ' ,
' ipv6 address 10::4/128 tag 44 ' ,
' ipv6 address 10::3/128 ' ,
' ipv6 address 10::5/128 ' ,
' ipv6 address 10::6/128 tag 66 ' ,
' interface Ethernet1/2 ' ,
' no ipv6 address 10::12/128 ' ,
' interface Ethernet1/3 ' ,
' no ipv6 address '
]
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = merged )
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
#
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced )
#
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden )
def test_6 ( self ) :
# misc tests
existing = dedent ( ''' \
interface Ethernet1 / 1
ip address 10.1 .1 .1 / 24
no ip redirects
ip unreachables
interface Ethernet1 / 2
interface Ethernet1 / 3
interface Ethernet1 / 4
interface Ethernet1 / 5
no ip redirects
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/1 ' , redirects = True , unreachables = False ,
ipv4 = [ { ' address ' : ' 192.168.1.1/24 ' } ] ) ,
dict ( name = ' Ethernet1/2 ' ) ,
dict ( name = ' Ethernet1/3 ' , redirects = True , unreachables = False ) , # defaults
dict ( name = ' Ethernet1/4 ' , redirects = False , unreachables = True ) ,
] )
merged = [
' interface Ethernet1/1 ' ,
' ip redirects ' ,
' no ip unreachables ' ,
' ip address 192.168.1.1/24 ' ,
' interface Ethernet1/4 ' ,
' no ip redirects ' ,
' ip unreachables '
]
deleted = [
' interface Ethernet1/1 ' ,
' ip redirects ' ,
' no ip unreachables ' ,
' no ip address '
]
replaced = [
' interface Ethernet1/1 ' ,
' ip redirects ' ,
' no ip unreachables ' ,
' ip address 192.168.1.1/24 ' ,
' interface Ethernet1/4 ' ,
' no ip redirects ' ,
' ip unreachables '
]
overridden = [
' interface Ethernet1/1 ' ,
' ip redirects ' ,
' no ip unreachables ' ,
' ip address 192.168.1.1/24 ' ,
' interface Ethernet1/5 ' ,
' ip redirects ' ,
' interface Ethernet1/4 ' ,
' no ip redirects ' ,
' ip unreachables '
]
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
@ -124,13 +453,128 @@ class TestNxosL3InterfacesModule(TestNxosModule):
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden )
# TBD: 'REPLACED' BEHAVIOR IS INCORRECT,
# IT IS WRONGLY IGNORING ETHERNET1/2.
# ****************** SKIP TEST FOR NOW *****************
# playbook['state'] = 'replaced'
# set_module_args(playbook, ignore_provider_arg)
# self.execute_module(changed=True, commands=replaced)
def test_7 ( self ) :
# idempotence
existing = dedent ( ''' \
interface Ethernet1 / 1
ip address 10.1 .1 .1 / 24
ip address 10.2 .2 .2 / 24 secondary tag 2
ip address 10.3 .3 .3 / 24 secondary tag 3
ip address 10.4 .4 .4 / 24 secondary
ipv6 address 10 : : 1 / 128
ipv6 address 10 : : 2 / 128 tag 2
no ip redirects
ip unreachables
interface Ethernet1 / 2
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/1 ' , redirects = False , unreachables = True ,
ipv4 = [ { ' address ' : ' 10.1.1.1/24 ' } ,
{ ' address ' : ' 10.2.2.2/24 ' , ' secondary ' : True , ' tag ' : 2 } ,
{ ' address ' : ' 10.3.3.3/24 ' , ' secondary ' : True , ' tag ' : 3 } ,
{ ' address ' : ' 10.4.4.4/24 ' , ' secondary ' : True } ] ,
ipv6 = [ { ' address ' : ' 10::1/128 ' } ,
{ ' address ' : ' 10::2/128 ' , ' tag ' : 2 } ] ) ,
dict ( name = ' Ethernet1/2 ' )
] )
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = False )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = False )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = False )
# Modify output for deleted idempotence test
existing = dedent ( ''' \
interface Ethernet1 / 1
interface Ethernet1 / 2
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = False )
def test_8 ( self ) :
# no 'config' key in playbook
existing = dedent ( ''' \
interface Ethernet1 / 1
ip address 10.1 .1 .1 / 24
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( )
for i in [ ' merged ' , ' replaced ' , ' overridden ' ] :
playbook [ ' state ' ] = i
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( failed = True )
deleted = [
' interface Ethernet1/1 ' ,
' no ip address ' ,
]
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted )
def test_9 ( self ) :
# Platform specific checks
# 'ip redirects' has platform-specific behaviors
existing = dedent ( ''' \
interface mgmt0
ip address 10.0 .0 .254 / 24
interface Ethernet1 / 3
ip address 10.13 .13 .13 / 24
interface Ethernet1 / 5
no ip redirects
ip address 10.15 .15 .15 / 24
ip address 10.25 .25 .25 / 24 secondary
''' )
self . get_resource_connection_facts . return_value = { self . SHOW_CMD : existing }
playbook = dict ( config = [
dict ( name = ' Ethernet1/3 ' ) ,
dict ( name = ' Ethernet1/5 ' ) ,
] )
# Expected result commands for each 'state'
deleted = [
' interface Ethernet1/3 ' , ' no ip address ' ,
' interface Ethernet1/5 ' , ' no ip address ' , ' ip redirects '
]
replaced = [
' interface Ethernet1/3 ' , ' no ip address ' ,
' interface Ethernet1/5 ' , ' no ip address ' , ' ip redirects '
]
overridden = [
' interface Ethernet1/3 ' , ' no ip address ' ,
' interface Ethernet1/5 ' , ' no ip address ' , ' ip redirects '
]
platform = ' N3K '
playbook [ ' state ' ] = ' merged '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = False , device = platform )
playbook [ ' state ' ] = ' deleted '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = deleted , device = platform )
playbook [ ' state ' ] = ' replaced '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = replaced , device = platform )
playbook [ ' state ' ] = ' overridden '
set_module_args ( playbook , ignore_provider_arg )
self . execute_module ( changed = True , commands = overridden , device = platform )