Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Resolved issues in vLAN module #277

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion plugins/module_utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,10 @@ def run(self, ib_obj_type, ib_spec):
if 'default_value' in obj:
obj['default_value'] = str(obj['default_value'])

if (ib_obj_type == NIOS_VLAN):
if 'parent' in current_object:
current_object['parent'] = current_object['parent']['_ref']

# checks if the 'text' field has to be updated for the TXT Record
if (ib_obj_type == NIOS_TXT_RECORD):
text_obj = proposed_object["text"]
Expand Down Expand Up @@ -696,7 +700,7 @@ def compare_objects(self, current_object, proposed_object):
# If the lists are of a different length, the objects cannot be
# equal, and False will be returned before comparing the list items
# this code part will work for members' assignment
if (key in ('members', 'options', 'delegate_to', 'forwarding_servers', 'stub_members')
if (key in ('members', 'options', 'delegate_to', 'forwarding_servers', 'stub_members', 'vlans')
and (len(proposed_item) != len(current_item))):
return False

Expand Down
14 changes: 8 additions & 6 deletions plugins/modules/nios_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
of values (see suboptions). When configuring suboptions at
least one of C(name) or C(id) must be specified.
type: list
default: []
elements: dict
suboptions:
name:
Expand All @@ -102,6 +103,7 @@
description:
- The name of the parent vlanview or vlanrange.
type: str
default: default
extattrs:
description:
- Allows for the configuration of Extensible Attributes on the
Expand Down Expand Up @@ -393,13 +395,13 @@ def vlans(module):
if 'parent' in vlan_filtered:
obj_vlanview = wapi.get_object('vlanview', {'name': vlan_filtered['parent']})
obj_vlanrange = wapi.get_object('vlanrange', {'name': vlan_filtered['parent']})
if obj_vlanview and not obj_vlanrange:
vlan_filtered['parent'] = obj_vlanview[0]['_ref']
elif not obj_vlanview and obj_vlanrange:
if obj_vlanrange:
vlan_filtered['parent'] = obj_vlanrange[0]['_ref']
elif obj_vlanview:
vlan_filtered['parent'] = obj_vlanview[0]['_ref']
else:
module.fail_json(msg='VLAN View/Range \'%s\' cannot be found.' % vlan_filtered['parent'])

obj_vlan = wapi.get_object('vlan', vlan_filtered)

if obj_vlan:
Expand All @@ -408,7 +410,7 @@ def vlans(module):
module.fail_json(msg='VLAN `%s` cannot be found.' % vlan['name'])

return vlans_list

option_spec = dict(
# one of name or num is required; enforced by the function options()
name=dict(),
Expand All @@ -430,7 +432,7 @@ def vlans(module):
network=dict(required=True, aliases=['name', 'cidr'], ib_req=True),
network_view=dict(default='default', ib_req=True),
options=dict(type='list', elements='dict', options=option_spec, transform=options, default=[]),
vlans=dict(type='list', elements='dict', options=vlans_spec, transform=vlans),
vlans=dict(type='list', elements='dict', options=vlans_spec, transform=vlans, default=[]),
template=dict(type='str'),
extattrs=dict(type='dict'),
comment=dict(),
Expand Down
11 changes: 5 additions & 6 deletions plugins/modules/nios_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
module: nios_vlan
author: "Christoph Spatt (@edeka-spatt)"
short_description: Configure Infoblox NIOS VLANs
version_added: "1.4.3"
version_added: "1.8.0"
description:
- Adds and/or removes instances of vlan objects from
Infoblox NIOS servers. This module manages NIOS C(vlan) objects
Expand Down Expand Up @@ -39,11 +39,10 @@
description:
- Specifies the vlan parent to add or remove from
the system. Can be either a C(vlanview) or C(vlanrange)
name. Feteches the required _ref object automatically.
name. Fetches the required _ref object automatically.
If not specified defaults to vlan view C(default).
type: str
default: default
required: true
comment:
description:
- Configures a text string comment to be associated with the instance
Expand Down Expand Up @@ -151,10 +150,10 @@ def parent_transform(module):
if module.params['parent']:
parent_obj_vlanview = wapi.get_object('vlanview', {'name': module.params['parent']})
parent_obj_vlanrange = wapi.get_object('vlanrange', {'name': module.params['parent']})
if parent_obj_vlanview and not parent_obj_vlanrange:
parent_ref = parent_obj_vlanview[0]['_ref']
elif not parent_obj_vlanview and parent_obj_vlanrange:
if parent_obj_vlanrange:
parent_ref = parent_obj_vlanrange[0]['_ref']
elif parent_obj_vlanview:
parent_ref = parent_obj_vlanview[0]['_ref']
else:
module.fail_json(msg='VLAN View/Range \'%s\' cannot be found.' % module.params['parent'])
return parent_ref
Expand Down
90 changes: 90 additions & 0 deletions tests/unit/plugins/modules/test_nios_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,93 @@ def test_nios_network_ipv4_update_with_use_logic_filter_rules(self):
'use_logic_filter_rules': True,
'logic_filter_rules': []}
)

def test_nios_network_ipv4_create_with_vlan(self):
self.module.params = {'provider': None, 'state': 'present', 'network': '192.168.10.0/24',
'comment': None, 'extattrs': None, 'vlans': [{'name':'ansible_vlan',
'parent': 'default' ,'id': '10'}]}

test_object = None
test_spec = {
"network": {"ib_req": True},
"comment": {},
"extattrs": {},
"vlans": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_IPV4_NETWORK', test_spec)

self.assertTrue(res['changed'])
wapi.create_object.assert_called_once_with('NIOS_IPV4_NETWORK', {'network': '192.168.10.0/24',
'vlans': [{'name':'ansible_vlan',
'parent': 'default' ,'id': '10'}]
}
)

def test_nios_network_ipv4_update_vlan(self):
self.module.params = {'provider': None, 'state': 'present', 'network': '192.168.10.0/24',
'comment': None, 'extattrs': None, 'vlans': [{'name':'ansible_vlan1',
'parent': 'default' ,'id': '10'},
{'name':'ansible_vlan2',
'parent': 'default' ,'id': '20'}]}
ref = "network/ZG5zLm5ldHdvcmtfdmlldyQw:default/true"

test_object = [
{
"comment": "test comment",
"_ref": ref,
"network": "192.168.10.0/24",
"vlans": [{'name':'ansible_vlan1', 'parent': 'default' ,'id': '10'}]
}
]
test_spec = {
"network": {"ib_req": True},
"comment": {},
"extattrs": {},
"vlans": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_IPV4_NETWORK', test_spec)

self.assertTrue(res['changed'])

wapi.update_object.assert_called_once_with(ref, {'network': '192.168.10.0/24',
'vlans': [{'name':'ansible_vlan1',
'parent': 'default' ,'id': '10'},
{'name':'ansible_vlan2',
'parent': 'default' ,'id': '20'}]
}
)

def test_nios_network_ipv4_remove_vlan(self):
self.module.params = {'provider': None, 'state': 'present', 'network': '192.168.10.0/24',
'comment': None, 'extattrs': None, 'vlans': []}
ref = "network/ZG5zLm5ldHdvcmtfdmlldyQw:default/true"

test_object = [
{
"comment": "test comment",
"_ref": ref,
"network": "192.168.10.0/24",
"vlans": [{'name':'ansible_vlan1', 'parent': 'default' ,'id': '10'},
{'name':'ansible_vlan2', 'parent': 'default' ,'id': '20'}
]
}
]
test_spec = {
"network": {"ib_req": True},
"comment": {},
"extattrs": {},
"vlans": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_IPV4_NETWORK', test_spec)

self.assertTrue(res['changed'])
wapi.update_object.assert_called_once_with(ref, {'network': '192.168.10.0/24',
'vlans': []
}
)
180 changes: 180 additions & 0 deletions tests/unit/plugins/modules/test_nios_vlan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.

# Make coding more python3-ish


from __future__ import (absolute_import, division, print_function)
__metaclass__ = type


from ansible_collections.infoblox.nios_modules.plugins.modules import nios_vlan
from ansible_collections.infoblox.nios_modules.plugins.module_utils import api
from ansible_collections.infoblox.nios_modules.tests.unit.compat.mock import patch, MagicMock, Mock
from .test_nios_module import TestNiosModule, load_fixture


class TestNiosVlanModule(TestNiosModule):

module = nios_vlan

def setUp(self):
super(TestNiosVlanModule, self).setUp()
self.module = MagicMock(name='ansible_collections.infoblox.nios_modules.plugins.modules.nios_vlan.WapiModule')
self.module.check_mode = False
self.module.params = {'provider': None}
self.mock_wapi = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_vlan.WapiModule')
self.exec_command = self.mock_wapi.start()
self.mock_wapi_run = patch('ansible_collections.infoblox.nios_modules.plugins.modules.nios_vlan.WapiModule.run')
self.mock_wapi_run.start()
self.load_config = self.mock_wapi_run.start()
self.mock_check_type_dict = patch('ansible.module_utils.common.validation.check_type_dict')
self.mock_check_type_dict_obj = self.mock_check_type_dict.start()

def tearDown(self):
super(TestNiosVlanModule, self).tearDown()
self.mock_wapi.stop()
self.mock_wapi_run.stop()
self.mock_check_type_dict.stop()

def _get_wapi(self, test_object):
wapi = api.WapiModule(self.module)
wapi.get_object = Mock(name='get_object', return_value=test_object)
wapi.create_object = Mock(name='create_object')
wapi.update_object = Mock(name='update_object')
wapi.delete_object = Mock(name='delete_object')
return wapi

def load_fixtures(self, commands=None):
self.exec_command.return_value = (0, load_fixture('nios_result.txt').strip(), None)
self.load_config.return_value = dict(diff=None, session='session')

def test_nios_vlan_create(self):
self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible_vlan',
'parent': 'default', 'id': '10', 'comment': None, 'extattrs': None}

test_object = None

test_spec = {
"name": {"ib_req": True},
"parent": {"ib_req": True},
"id": {"ib_req": True},
"comment": {},
"extattrs": {}
}

wapi = self._get_wapi(test_object)
print("WAPI: ", wapi.__dict__)
res = wapi.run('NIOS_VLAN', test_spec)

self.assertTrue(res['changed'])
wapi.create_object.assert_called_once_with('NIOS_VLAN', {'name': 'ansible_vlan',
'parent': 'default', 'id': '10'})

def test_nios_vlan_update_comment(self):
self.module.params = {'provider': None, 'state': 'present', 'name': 'ansible_vlan',
'parent': 'default', 'id': '10', 'comment': 'updated comment',
'contact': '[email protected]', 'department': 'IT', 'description': 'test',
'reserved': True,'extattrs': None}

ref = "vlan/ZG5zLm5ldHdvcmtfdmlldyQw:ansible_vlan"
test_object = [
{
"comment": "test comment",
"_ref": ref,
"name": "ansible_vlan",
"parent": "default",
"id": "10",
"extattrs": {}
}
]

test_spec = {
"name": {"ib_req": True},
"parent": {"ib_req": True},
"id": {"ib_req": True},
"comment": {},
"contact": {},
"department": {},
"description": {},
"reserved": {},
"extattrs": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_VLAN', test_spec)
self.assertTrue(res['changed'])
wapi.update_object.assert_called_once_with(
ref, {'comment': 'updated comment', 'parent': 'default', 'id': '10', 'name': 'ansible_vlan',
'contact': '[email protected]', 'department': 'IT', 'description': 'test', 'reserved': True}
)

def test_nios_vlan_remove(self):
self.module.params = {'provider': None, 'state': 'absent', 'name': 'ansible_vlan',
'parent': 'default', 'id': '10', 'comment': None, 'extattrs': None}

ref = "vlan/ZG5zLm5ldHdvcmtfdmlldyQw:ansible_vlan"

test_object = [{
"comment": "test comment",
"_ref": ref,
"name": "ansible_vlan",
"parent": "default",
"id": "10",
"extattrs": {'Site': {'value': 'test'}}
}]

test_spec = {
"name": {"ib_req": True},
"parent": {"ib_req": True},
"id": {"ib_req": True},
"comment": {},
"extattrs": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_VLAN', test_spec)

self.assertTrue(res['changed'])
wapi.delete_object.assert_called_once_with(ref)

def test_nios_vlan_update_record_name(self):
self.module.params = {'provider': None, 'state': 'present', 'name': {'new_name': 'ansible_new_vlan', 'old_name': 'ansible_vlan'},
'parent': 'default', 'id': '10', 'comment': 'comment', 'extattrs': None}

ref = "vlan/ZG5zLm5ldHdvcmtfdmlldyQw:ansible_new_vlan"
test_object = [
{
"comment": "test comment",
"_ref": ref,
"name": "ansible_vlan",
"extattrs": {}
}
]

test_spec = {
"name": {"ib_req": True},
"parent": {"ib_req": True},
"id": {"ib_req": True},
"comment": {},
"extattrs": {}
}

wapi = self._get_wapi(test_object)
res = wapi.run('NIOS_VLAN', test_spec)

self.assertTrue(res['changed'])
wapi.update_object.assert_called_once_with(ref, {'name': 'ansible_new_vlan', 'parent': 'default', 'id': '10',
'comment': 'comment'})
Loading