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 opx_cps module to handle minor issues #51952

Merged
merged 1 commit into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
159 changes: 80 additions & 79 deletions lib/ansible/modules/network/opx/opx_cps.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
RETURN = """
response:
description: Output from the CPS transaction.
Output of CPS Get operation if CPS set/create/delete not done.
returned: when a CPS transaction is successfully performed.
type: list
sample:
Expand All @@ -124,44 +125,41 @@
},
"key": "target/dell-base-if-cmn/if/interfaces/interface"
}]
candidate:
description: CPS input attribute data used to compare with
running configuration
returned: all CPS operations other than "get"
type: dict
sample:
{
"base-if-vlan/if/interfaces/interface/id": 230,
"if/interfaces/interface/name": "br230",
"if/interfaces/interface/type": "ianaift:l2vlan"
}
config:
cps_curr_config:
description: Returns the CPS Get output i.e. the running configuration
before performing the CPS transaction
before CPS operation of set/delete is performed
returned: when CPS operations set, delete
type: dict
sample:
{
"base-if-vlan/if/interfaces/interface/id": 230,
"dell-base-if-cmn/if/interfaces/interface/if-index": 46,
"dell-if/if/interfaces/interface/learning-mode": 1,
"dell-if/if/interfaces/interface/mtu": 1532,
"dell-if/if/interfaces/interface/phys-address": "",
"dell-if/if/interfaces/interface/vlan-type": 1,
"if/interfaces/interface/enabled": 0,
"if/interfaces/interface/name": "br230",
"if/interfaces/interface/type": "ianaift:l2vlan"
}
[{
"data": {
"base-if-vlan/if/interfaces/interface/id": 230,
"cps/key_data": {
"if/interfaces/interface/name": "br230"
},
"dell-base-if-cmn/if/interfaces/interface/if-index": 44,
"dell-if/if/interfaces/interface/learning-mode": 1,
"dell-if/if/interfaces/interface/mtu": 1532,
"dell-if/if/interfaces/interface/phys-address": "",
"dell-if/if/interfaces/interface/vlan-type": 1,
"if/interfaces/interface/enabled": 0,
"if/interfaces/interface/type": "ianaift:l2vlan"
},
"key": "target/dell-base-if-cmn/if/interfaces/interface"
}]
diff:
description: The actual configuration that will be pushed comparing
the running configuration and input attributes
returned: all CPS operations other than "get"
returned: when CPS operations set, delete
type: dict
sample:
{
"base-if-vlan/if/interfaces/interface/id": 230,
"if/interfaces/interface/name": "br230",
"if/interfaces/interface/type": "ianaift:l2vlan"
"cps/key_data": {
"if/interfaces/interface/name": "br230"
},
"dell-if/if/interfaces/interface/untagged-ports": [
"e101-007-0"
]
}
db:
description: Denotes if CPS DB transaction was performed
Expand All @@ -188,31 +186,6 @@
HAS_CPS = False


def get_config(module):

qualifier = module.params['qualifier']
module_name = module.params['module_name']
attr_type = module.params["attr_type"]
attr_data = module.params["attr_data"]
db = module.params["db"]
commit_event = module.params["commit_event"]
config = dict()

configobj = parse_cps_parameters(module_name, qualifier,
attr_type, attr_data, "get",
db, commit_event)
cpsconfig = cps_get(configobj)

if cpsconfig['response']:
for key, val in iteritems(cpsconfig['response'][0]['data']):
if key == 'cps/key_data':
config.update(val)
else:
config[key] = val

return config


def convert_cps_raw_list(raw_list):
resp_list = []
if raw_list:
Expand Down Expand Up @@ -289,7 +262,6 @@ def cps_get(obj):
resp_list = convert_cps_raw_list(l)

RESULT["response"] = resp_list
RESULT["changed"] = False
return RESULT


Expand All @@ -306,6 +278,17 @@ def cps_transaction(obj):
return RESULT


def parse_key_data(attrs):

res = dict()
for key, val in iteritems(attrs):
if key == 'cps/key_data':
res.update(val)
else:
res[key] = val
return res


def main():
"""
main entry point for module execution
Expand Down Expand Up @@ -341,47 +324,65 @@ def main():
db = module.params["db"]
commit_event = module.params["commit_event"]
RESULT = dict(changed=False, db=False, commit_event=False)
obj = parse_cps_parameters(module_name, qualifier, attr_type,
attr_data, operation, db, commit_event)

if db:
RESULT['db'] = True
if commit_event:
RESULT['commit_event'] = True

try:
# First do a CPS get operation
get_obj = parse_cps_parameters(module_name, qualifier, attr_type,
attr_data, 'get', db, commit_event)
curr_config = cps_get(get_obj)

if operation == 'get':
RESULT.update(cps_get(obj))
RESULT.update(curr_config)
else:
config = get_config(module)
diff = attr_data

if config:
candidate = dict()
for key, val in iteritems(attr_data):
if key == 'cps/key_data':
candidate.update(val)
# Evaluate the changes in the attributes
cfg = dict()
if curr_config and curr_config['response']:
cfg = curr_config['response'][0]['data']
key_d = 'cps/key_data'

# diff computation is not needed for delete
if operation != 'delete':
configs = parse_key_data(cfg)
attributes = parse_key_data(attr_data)
diff = dict_diff(configs, attributes)
# Append diff with any 'cps/key_data' from attr_data
if diff and key_d in attr_data:
diff[key_d] = attr_data[key_d]

# Append diff with any 'cps/key_data' from curr_config
# Needed for all operations including delete
if diff and key_d in cfg:
if key_d in diff:
diff[key_d].update(cfg[key_d])
else:
candidate[key] = val
diff = dict_diff(config, candidate)
diff[key_d] = cfg[key_d]

RESULT.update({"diff": diff})

# Create object for cps operation
obj = parse_cps_parameters(module_name, qualifier, attr_type,
diff, operation, db, commit_event)

res = dict()
if operation == "delete":
if config:
RESULT.update({"config": config,
"candidate": attr_data,
"diff": diff})
RESULT.update(cps_transaction(obj))
if cfg:
res = cps_transaction(obj)
else:
if diff:
if 'cps/key_data' in attr_data:
diff.update(attr_data['cps/key_data'])
obj = parse_cps_parameters(module_name, qualifier,
attr_type, diff, operation,
db, commit_event)
RESULT.update({"config": config,
"candidate": attr_data,
"diff": diff})
RESULT.update(cps_transaction(obj))
res = cps_transaction(obj)

if not res and cfg:
res.update({"response": curr_config['response']})
else:
res.update({"cps_curr_config": curr_config['response']})
RESULT.update(res)

except Exception as e:
module.fail_json(msg=str(type(e).__name__) + ": " + str(e))
Expand Down
8 changes: 4 additions & 4 deletions test/units/modules/network/opx/test_opx_cps.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def setUp(self):
self.mock_parse_cps_parameters = patch('ansible.modules.network.opx.opx_cps.parse_cps_parameters')
self.parse_cps_parameters = self.mock_parse_cps_parameters.start()

self.mock_get_config = patch('ansible.modules.network.opx.opx_cps.get_config')
self.mock_get_config = patch('ansible.modules.network.opx.opx_cps.cps_get.parse_cps_parameters')
self.get_config = self.mock_get_config.start()

def tearDown(self):
Expand Down Expand Up @@ -108,7 +108,7 @@ def test_opx_operation_delete(self):
self.get_config.return_value = config_data
self.cps_transaction.return_value = dict(changed=True, response=resp)
self.execute_module(changed=True, response=resp)
self.assertEqual(self.parse_cps_parameters.call_count, 1)
self.assertEqual(self.parse_cps_parameters.call_count, 2)
self.assertEqual(self.cps_transaction.call_count, 1)

def test_opx_operation_delete_fail(self):
Expand All @@ -118,8 +118,8 @@ def test_opx_operation_delete_fail(self):
set_module_args(dict(module_name=module_name, operation="delete", attr_data=attr_data))
self.get_config.return_value = dict()
self.execute_module(changed=False)
self.assertEqual(self.parse_cps_parameters.call_count, 1)
self.assertEqual(self.cps_transaction.call_count, 0)
self.assertEqual(self.parse_cps_parameters.call_count, 2)
self.assertEqual(self.cps_transaction.call_count, 1)

def test_opx_operation_get(self):
resp = load_fixture('opx_operation_get.cfg')
Expand Down