1818from ansible .module_utils .basic import json
1919from ansible .module_utils .basic import env_fallback
2020from ansible .module_utils .six import PY3
21- from ansible .module_utils .six .moves import filterfalse
2221from ansible .module_utils .six .moves .urllib .parse import urlencode
2322from ansible .module_utils ._text import to_native , to_text
2423from ansible .module_utils .connection import Connection
@@ -73,53 +72,27 @@ def cmp(a, b):
7372
7473
7574def issubset (subset , superset ):
76- """Recurse through nested dictionary and compare entries """
75+ """Recurse through a nested dictionary and check if it is a subset of another. """
7776
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 ):
77+ if type (subset ) is not type (superset ):
8878 return False
8979
80+ if not isinstance (subset , dict ):
81+ if isinstance (subset , list ):
82+ return all (item in superset for item in subset )
83+ return subset == superset
84+
9085 for key , value in subset .items ():
91- # Ignore empty values
9286 if value is None :
93- return True
87+ continue
9488
95- # Item from subset is missing from superset
9689 if key not in superset :
9790 return False
9891
99- # Item has different types in subset and superset
100- if isinstance (superset .get (key )) is not isinstance (value ):
101- return False
92+ superset_value = superset .get (key )
10293
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
94+ if not issubset (value , superset_value ):
95+ return False
12396
12497 return True
12598
@@ -210,6 +183,9 @@ def __init__(self, module):
210183
211184 # info output
212185 self .previous = dict ()
186+ self .before = []
187+ self .commands = []
188+ self .after = []
213189 self .proposed = dict ()
214190 self .sent = dict ()
215191 self .stdout = None
@@ -433,6 +409,7 @@ def exit_json(self, **kwargs):
433409 if self .params .get ("state" ) in ALLOWED_STATES_TO_APPEND_SENT_AND_PROPOSED :
434410 if self .params .get ("output_level" ) in ("debug" , "info" ):
435411 self .result ["previous" ] = self .previous
412+ self .result ["before" ] = self .before
436413 # FIXME: Modified header only works for PATCH
437414 if not self .has_modified and self .previous != self .existing :
438415 self .result ["changed" ] = True
@@ -450,8 +427,10 @@ def exit_json(self, **kwargs):
450427 if self .params .get ("state" ) in ALLOWED_STATES_TO_APPEND_SENT_AND_PROPOSED :
451428 self .result ["sent" ] = self .sent
452429 self .result ["proposed" ] = self .proposed
430+ self .result ["commands" ] = self .commands
453431
454432 self .result ["current" ] = self .existing
433+ self .result ["after" ] = self .after
455434
456435 if self .module ._diff and self .result .get ("changed" ) is True :
457436 self .result ["diff" ] = dict (
@@ -468,6 +447,7 @@ def fail_json(self, msg, **kwargs):
468447 if self .params .get ("state" ) in ALLOWED_STATES_TO_APPEND_SENT_AND_PROPOSED :
469448 if self .params .get ("output_level" ) in ("debug" , "info" ):
470449 self .result ["previous" ] = self .previous
450+ self .result ["before" ] = self .before
471451 # FIXME: Modified header only works for PATCH
472452 if not self .has_modified and self .previous != self .existing :
473453 self .result ["changed" ] = True
@@ -486,8 +466,10 @@ def fail_json(self, msg, **kwargs):
486466 if self .params .get ("state" ) in ALLOWED_STATES_TO_APPEND_SENT_AND_PROPOSED :
487467 self .result ["sent" ] = self .sent
488468 self .result ["proposed" ] = self .proposed
469+ self .result ["commands" ] = self .commands
489470
490471 self .result ["current" ] = self .existing
472+ self .result ["after" ] = self .after
491473
492474 self .result .update (** kwargs )
493475 self .module .fail_json (msg = msg , ** self .result )
@@ -499,23 +481,30 @@ def check_changed(self):
499481 existing ["password" ] = self .sent .get ("password" )
500482 return not issubset (self .sent , existing )
501483
502- def get_diff (self , unwanted = None ):
484+ def get_diff (self , unwanted = None , previous = None , payload = None ):
503485 """Check if existing payload and sent payload and removing keys that are not required"""
504486 if unwanted is None :
505487 unwanted = []
506- if not self .existing and self .sent :
507- return True
488+
489+ if previous is None and payload is None :
490+ if not self .existing and self .sent :
491+ return True
508492
509493 existing = self .existing
510494 sent = self .sent
511495
496+ if previous and payload :
497+ existing = previous
498+ sent = payload
499+
512500 for key in unwanted :
513501 if isinstance (key , str ):
514502 if key in existing :
515503 try :
516504 del existing [key ]
517505 except KeyError :
518506 pass
507+ if key in sent :
519508 try :
520509 del sent [key ]
521510 except KeyError :
@@ -524,12 +513,14 @@ def get_diff(self, unwanted=None):
524513 key_path , last = key [:- 1 ], key [- 1 ]
525514 try :
526515 existing_parent = reduce (dict .get , key_path , existing )
527- del existing_parent [last ]
516+ if existing_parent is not None :
517+ del existing_parent [last ]
528518 except KeyError :
529519 pass
530520 try :
531521 sent_parent = reduce (dict .get , key_path , sent )
532- del sent_parent [last ]
522+ if sent_parent is not None :
523+ del sent_parent [last ]
533524 except KeyError :
534525 pass
535526 return not issubset (sent , existing )
@@ -567,3 +558,8 @@ def get_object_by_nested_key_value(self, path, nested_key_path, value, data_key=
567558 return obj
568559
569560 return None
561+
562+ def delete (self , check_mode , path ):
563+ if not check_mode :
564+ self .request (path , method = "DELETE" )
565+ return {"path" : path , "method" : "DELETE" }
0 commit comments