Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Commit

Permalink
Ansible - Remove output only from response
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
rambleraptor authored and modular-magician committed Mar 18, 2019
1 parent 37a0865 commit 477c31e
Show file tree
Hide file tree
Showing 15 changed files with 119 additions and 183 deletions.
119 changes: 80 additions & 39 deletions lib/ansible/module_utils/gcp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,12 +237,16 @@ def _merge_dictionaries(self, a, b):
return new


# This class takes in two dictionaries `a` and `b`.
# These are dictionaries of arbitrary depth, but made up of standard Python
# types only.
# This differ will compare all values in `a` to those in `b`.
# Note: Only keys in `a` will be compared. Extra keys in `b` will be ignored.
# Note: On all lists, order does matter.
# This class does difference checking according to a set of GCP-specific rules.
# This will be primarily used for checking dictionaries.
# In an equivalence check, the left-hand dictionary will be the request and
# the right-hand side will be the response.

# Rules:
# Extra keys in response will be ignored.
# Ordering of lists does not matter.
# - exception: lists of dictionaries are
# assumed to be in sorted order.
class GcpRequest(object):
def __init__(self, request):
self.request = request
Expand All @@ -253,31 +257,48 @@ def __eq__(self, other):
def __ne__(self, other):
return not self.__eq__(other)

# Returns the difference between `self.request` and `b`
def difference(self, b):
return self._compare_dicts(self.request, b.request)
# Returns the difference between a request + response.
# While this is used under the hood for __eq__ and __ne__,
# it is useful for debugging.
def difference(self, response):
return self._compare_value(self.request, response.request)

def _compare_dicts(self, dict1, dict2):
def _compare_dicts(self, req_dict, resp_dict):
difference = {}
for key in dict1:
difference[key] = self._compare_value(dict1.get(key), dict2.get(key))
for key in req_dict:
if resp_dict.get(key):
difference[key] = self._compare_value(req_dict.get(key), resp_dict.get(key))

# Remove all empty values from difference.
difference2 = {}
sanitized_difference = {}
for key in difference:
if difference[key]:
difference2[key] = difference[key]
sanitized_difference[key] = difference[key]

return difference2
return sanitized_difference

# Takes in two lists and compares them.
def _compare_lists(self, list1, list2):
# All things in the list should be identical (even if a dictionary)
def _compare_lists(self, req_list, resp_list):
# Have to convert each thing over to unicode.
# Python doesn't handle equality checks between unicode + non-unicode well.
difference = []
for index in range(len(list1)):
value1 = list1[index]
if index < len(list2):
value2 = list2[index]
difference.append(self._compare_value(value1, value2))
new_req_list = self._convert_value(req_list)
new_resp_list = self._convert_value(resp_list)

# We have to compare each thing in the request to every other thing
# in the response.
# This is because the request value will be a subset of the response value.
# The assumption is that these lists will be small enough that it won't
# be a performance burden.
for req_item in new_req_list:
found_item = False
for resp_item in new_resp_list:
# Looking for a None value here.
if not self._compare_value(req_item, resp_item):
found_item = True
if not found_item:
difference.append(req_item)

difference2 = []
for value in difference:
Expand All @@ -286,49 +307,69 @@ def _compare_lists(self, list1, list2):

return difference2

def _compare_value(self, value1, value2):
# Compare two values of arbitrary types.
def _compare_value(self, req_value, resp_value):
diff = None
# If a None is found, a difference does not exist.
# Only differing values matter.
if not value2:
if not resp_value:
return None

# Can assume non-None types at this point.
try:
if isinstance(value1, list):
diff = self._compare_lists(value1, value2)
elif isinstance(value2, dict):
diff = self._compare_dicts(value1, value2)
elif isinstance(value1, bool):
diff = self._compare_boolean(value1, value2)
if isinstance(req_value, list):
diff = self._compare_lists(req_value, resp_value)
elif isinstance(req_value, dict):
diff = self._compare_dicts(req_value, resp_value)
elif isinstance(req_value, bool):
diff = self._compare_boolean(req_value, resp_value)
# Always use to_text values to avoid unicode issues.
elif to_text(value1) != to_text(value2):
diff = value1
elif to_text(req_value) != to_text(resp_value):
diff = req_value
# to_text may throw UnicodeErrors.
# These errors shouldn't crash Ansible and should be hidden.
except UnicodeError:
pass

return diff

def _compare_boolean(self, value1, value2):
# Compare two boolean values.
def _compare_boolean(self, req_value, resp_value):
try:
# Both True
if value1 and isinstance(value2, bool) and value2:
if req_value and isinstance(resp_value, bool) and resp_value:
return None
# Value1 True, value2 'true'
elif value1 and to_text(value2) == 'true':
# Value1 True, resp_value 'true'
elif req_value and to_text(resp_value) == 'true':
return None
# Both False
elif not value1 and isinstance(value2, bool) and not value2:
elif not req_value and isinstance(resp_value, bool) and not resp_value:
return None
# Value1 False, value2 'false'
elif not value1 and to_text(value2) == 'false':
# Value1 False, resp_value 'false'
elif not req_value and to_text(resp_value) == 'false':
return None
else:
return value2
return resp_value

# to_text may throw UnicodeErrors.
# These errors shouldn't crash Ansible and should be hidden.
except UnicodeError:
return None

# Python (2 esp.) doesn't do comparisons between unicode + non-unicode well.
# This leads to a lot of false positives when diffing values.
# The Ansible to_text() function is meant to get all strings
# into a standard format.
def _convert_value(self, value):
if isinstance(value, list):
new_list = []
for item in value:
new_list.append(self._convert_value(item))
return new_list
elif isinstance(value, dict):
new_dict = {}
for key in value:
new_dict[key] = self._convert_value(value[key])
return new_dict
else:
return to_text(value)
16 changes: 2 additions & 14 deletions lib/ansible/modules/cloud/google/gcp_bigquery_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -1254,22 +1254,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{
u'estimatedBytes': self.request.get('estimated_bytes'),
u'estimatedRows': self.request.get('estimated_rows'),
u'oldestEntryTime': self.request.get('oldest_entry_time'),
}
)
return remove_nones_from_dict({})

def from_response(self):
return remove_nones_from_dict(
{
u'estimatedBytes': self.request.get(u'estimatedBytes'),
u'estimatedRows': self.request.get(u'estimatedRows'),
u'oldestEntryTime': self.request.get(u'oldestEntryTime'),
}
)
return remove_nones_from_dict({})


class TableSchema(object):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,6 @@ def to_request(self):
u'enabled': self.request.get('enabled'),
u'oauth2ClientId': self.request.get('oauth2_client_id'),
u'oauth2ClientSecret': self.request.get('oauth2_client_secret'),
u'oauth2ClientSecretSha256': self.request.get('oauth2_client_secret_sha256'),
}
)

Expand All @@ -991,7 +990,6 @@ def from_response(self):
u'enabled': self.request.get(u'enabled'),
u'oauth2ClientId': self.request.get(u'oauth2ClientId'),
u'oauth2ClientSecret': self.request.get(u'oauth2ClientSecret'),
u'oauth2ClientSecretSha256': self.request.get(u'oauth2ClientSecretSha256'),
}
)

Expand Down
24 changes: 6 additions & 18 deletions lib/ansible/modules/cloud/google/gcp_compute_disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,14 +664,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get('raw_key'), u'sha256': self.request.get('sha256'), u'kmsKeyName': self.request.get('kms_key_name')}
)
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'kmsKeyName': self.request.get('kms_key_name')})

def from_response(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get(u'rawKey'), u'sha256': self.request.get(u'sha256'), u'kmsKeyName': self.request.get(u'kmsKeyName')}
)
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'kmsKeyName': self.request.get(u'kmsKeyName')})


class DiskDiskencryptionkey(object):
Expand All @@ -683,14 +679,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get('raw_key'), u'sha256': self.request.get('sha256'), u'kmsKeyName': self.request.get('kms_key_name')}
)
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'kmsKeyName': self.request.get('kms_key_name')})

def from_response(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get(u'rawKey'), u'sha256': self.request.get(u'sha256'), u'kmsKeyName': self.request.get(u'kmsKeyName')}
)
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'kmsKeyName': self.request.get(u'kmsKeyName')})


class DiskSourcesnapshotencryptionkey(object):
Expand All @@ -702,14 +694,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get('raw_key'), u'kmsKeyName': self.request.get('kms_key_name'), u'sha256': self.request.get('sha256')}
)
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'kmsKeyName': self.request.get('kms_key_name')})

def from_response(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get(u'rawKey'), u'kmsKeyName': self.request.get(u'kmsKeyName'), u'sha256': self.request.get(u'sha256')}
)
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'kmsKeyName': self.request.get(u'kmsKeyName')})


if __name__ == '__main__':
Expand Down
8 changes: 4 additions & 4 deletions lib/ansible/modules/cloud/google/gcp_compute_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,10 +730,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'sha256': self.request.get('sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key')})

def from_response(self):
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'sha256': self.request.get(u'sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey')})


class ImageRawdisk(object):
Expand Down Expand Up @@ -764,10 +764,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'sha256': self.request.get('sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key')})

def from_response(self):
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'sha256': self.request.get(u'sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey')})


if __name__ == '__main__':
Expand Down
14 changes: 4 additions & 10 deletions lib/ansible/modules/cloud/google/gcp_compute_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -1298,14 +1298,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get('raw_key'), u'rsaEncryptedKey': self.request.get('rsa_encrypted_key'), u'sha256': self.request.get('sha256')}
)
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'rsaEncryptedKey': self.request.get('rsa_encrypted_key')})

def from_response(self):
return remove_nones_from_dict(
{u'rawKey': self.request.get(u'rawKey'), u'rsaEncryptedKey': self.request.get(u'rsaEncryptedKey'), u'sha256': self.request.get(u'sha256')}
)
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'rsaEncryptedKey': self.request.get(u'rsaEncryptedKey')})


class InstanceInitializeparams(object):
Expand Down Expand Up @@ -1348,10 +1344,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key'), u'sha256': self.request.get('sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get('raw_key')})

def from_response(self):
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey'), u'sha256': self.request.get(u'sha256')})
return remove_nones_from_dict({u'rawKey': self.request.get(u'rawKey')})


class InstanceGuestacceleratorsArray(object):
Expand Down Expand Up @@ -1406,7 +1402,6 @@ def _request_for_item(self, item):
{
u'accessConfigs': InstanceAccessconfigsArray(item.get('access_configs', []), self.module).to_request(),
u'aliasIpRanges': InstanceAliasiprangesArray(item.get('alias_ip_ranges', []), self.module).to_request(),
u'name': item.get('name'),
u'network': replace_resource_dict(item.get(u'network', {}), 'selfLink'),
u'networkIP': item.get('network_ip'),
u'subnetwork': replace_resource_dict(item.get(u'subnetwork', {}), 'selfLink'),
Expand All @@ -1418,7 +1413,6 @@ def _response_from_item(self, item):
{
u'accessConfigs': InstanceAccessconfigsArray(item.get(u'accessConfigs', []), self.module).from_response(),
u'aliasIpRanges': InstanceAliasiprangesArray(item.get(u'aliasIpRanges', []), self.module).from_response(),
u'name': item.get(u'name'),
u'network': item.get(u'network'),
u'networkIP': item.get(u'networkIP'),
u'subnetwork': item.get(u'subnetwork'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,32 +537,10 @@ def __init__(self, request, module):
self.request = {}

def to_request(self):
return remove_nones_from_dict(
{
u'abandoning': self.request.get('abandoning'),
u'creating': self.request.get('creating'),
u'creatingWithoutRetries': self.request.get('creating_without_retries'),
u'deleting': self.request.get('deleting'),
u'none': self.request.get('none'),
u'recreating': self.request.get('recreating'),
u'refreshing': self.request.get('refreshing'),
u'restarting': self.request.get('restarting'),
}
)
return remove_nones_from_dict({})

def from_response(self):
return remove_nones_from_dict(
{
u'abandoning': self.request.get(u'abandoning'),
u'creating': self.request.get(u'creating'),
u'creatingWithoutRetries': self.request.get(u'creatingWithoutRetries'),
u'deleting': self.request.get(u'deleting'),
u'none': self.request.get(u'none'),
u'recreating': self.request.get(u'recreating'),
u'refreshing': self.request.get(u'refreshing'),
u'restarting': self.request.get(u'restarting'),
}
)
return remove_nones_from_dict({})


class InstanceGroupManagerNamedportsArray(object):
Expand Down
Loading

0 comments on commit 477c31e

Please sign in to comment.