Skip to content

Commit ad9fdb1

Browse files
committed
[minor_change] Addition of nd_multi_cluster_connectivity module and its test file
1 parent 4642162 commit ad9fdb1

File tree

4 files changed

+507
-43
lines changed

4 files changed

+507
-43
lines changed

plugins/module_utils/nd.py

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Copyright: (c) 2021, Lionel Hercot (@lhercot) <[email protected]>
44
# Copyright: (c) 2022, Cindy Zhao (@cizhao) <[email protected]>
55
# Copyright: (c) 2022, Akini Ross (@akinross) <[email protected]>
6+
# Copyright: (c) 2025, Shreyas Srish (@shrsr) <[email protected]>
67

78
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
89

@@ -18,7 +19,6 @@
1819
from ansible.module_utils.basic import json
1920
from ansible.module_utils.basic import env_fallback
2021
from ansible.module_utils.six import PY3
21-
from ansible.module_utils.six.moves import filterfalse
2222
from ansible.module_utils.six.moves.urllib.parse import urlencode
2323
from ansible.module_utils._text import to_native, to_text
2424
from ansible.module_utils.connection import Connection
@@ -73,53 +73,27 @@ def cmp(a, b):
7373

7474

7575
def issubset(subset, superset):
76-
"""Recurse through nested dictionary and compare entries"""
76+
"""Recurse through a nested dictionary and check if it is a subset of another."""
7777

78-
# Both objects are the same object
79-
if subset is superset:
80-
return True
81-
82-
# Both objects are identical
83-
if subset == superset:
84-
return True
85-
86-
# Both objects have a different type
87-
if isinstance(subset) is not isinstance(superset):
78+
if type(subset) is not type(superset):
8879
return False
8980

81+
if not isinstance(subset, dict):
82+
if isinstance(subset, list):
83+
return all(item in superset for item in subset)
84+
return subset == superset
85+
9086
for key, value in subset.items():
91-
# Ignore empty values
9287
if value is None:
93-
return True
88+
continue
9489

95-
# Item from subset is missing from superset
9690
if key not in superset:
9791
return False
9892

99-
# Item has different types in subset and superset
100-
if isinstance(superset.get(key)) is not isinstance(value):
101-
return False
93+
superset_value = superset.get(key)
10294

103-
# Compare if item values are subset
104-
if isinstance(value, dict):
105-
if not issubset(superset.get(key), value):
106-
return False
107-
elif isinstance(value, list):
108-
try:
109-
# NOTE: Fails for lists of dicts
110-
if not set(value) <= set(superset.get(key)):
111-
return False
112-
except TypeError:
113-
# Fall back to exact comparison for lists of dicts
114-
diff = list(filterfalse(lambda i: i in value, superset.get(key))) + list(filterfalse(lambda j: j in superset.get(key), value))
115-
if diff:
116-
return False
117-
elif isinstance(value, set):
118-
if not value <= superset.get(key):
119-
return False
120-
else:
121-
if not value == superset.get(key):
122-
return False
95+
if not issubset(value, superset_value):
96+
return False
12397

12498
return True
12599

@@ -252,7 +226,7 @@ def request(
252226
if file is not None:
253227
info = conn.send_file_request(method, uri, file, data, None, file_key, file_ext)
254228
else:
255-
if data:
229+
if data is not None:
256230
info = conn.send_request(method, uri, json.dumps(data))
257231
else:
258232
info = conn.send_request(method, uri)
@@ -310,6 +284,8 @@ def request(
310284
self.fail_json(msg="ND Error: {0}".format(self.error.get("message")), data=data, info=info)
311285
self.error = payload
312286
if "code" in payload:
287+
if self.status == 404 and ignore_not_found_error:
288+
return {}
313289
self.fail_json(msg="ND Error {code}: {message}".format(**payload), data=data, info=info, payload=payload)
314290
elif "messages" in payload and len(payload.get("messages")) > 0:
315291
self.fail_json(msg="ND Error {code} ({severity}): {message}".format(**payload["messages"][0]), data=data, info=info, payload=payload)
@@ -375,6 +351,37 @@ def get_obj(self, path, **kwargs):
375351
self.fail_json(msg="More than one object matches unique filter: {0}".format(kwargs))
376352
return objs[0]
377353

354+
def get_object_by_nested_key_value(self, path, nested_key_path, value, data_key=None):
355+
356+
response_data = self.request(path, method="GET")
357+
358+
if not response_data:
359+
return None
360+
361+
object_list = []
362+
if isinstance(response_data, list):
363+
object_list = response_data
364+
elif data_key and data_key in response_data:
365+
object_list = response_data.get(data_key)
366+
else:
367+
return None
368+
369+
keys = nested_key_path.split(".")
370+
371+
for obj in object_list:
372+
current_level = obj
373+
for key in keys:
374+
if isinstance(current_level, dict):
375+
current_level = current_level.get(key)
376+
else:
377+
current_level = None
378+
break
379+
380+
if current_level == value:
381+
return obj
382+
383+
return None
384+
378385
def sanitize(self, updates, collate=False, required=None, unwanted=None):
379386
"""Clean up unset keys from a request payload"""
380387
if required is None:
@@ -506,8 +513,8 @@ def get_diff(self, unwanted=None):
506513
if not self.existing and self.sent:
507514
return True
508515

509-
existing = self.existing
510-
sent = self.sent
516+
existing = deepcopy(self.existing)
517+
sent = deepcopy(self.sent)
511518

512519
for key in unwanted:
513520
if isinstance(key, str):
@@ -516,6 +523,7 @@ def get_diff(self, unwanted=None):
516523
del existing[key]
517524
except KeyError:
518525
pass
526+
if key in sent:
519527
try:
520528
del sent[key]
521529
except KeyError:
@@ -524,12 +532,14 @@ def get_diff(self, unwanted=None):
524532
key_path, last = key[:-1], key[-1]
525533
try:
526534
existing_parent = reduce(dict.get, key_path, existing)
527-
del existing_parent[last]
535+
if existing_parent is not None:
536+
del existing_parent[last]
528537
except KeyError:
529538
pass
530539
try:
531540
sent_parent = reduce(dict.get, key_path, sent)
532-
del sent_parent[last]
541+
if sent_parent is not None:
542+
del sent_parent[last]
533543
except KeyError:
534544
pass
535545
return not issubset(sent, existing)

0 commit comments

Comments
 (0)