mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 11:21:25 -07:00
[GCP] New module GCP DNS Resource Record Set (#35920)
This commit is contained in:
parent
2fc3ac3516
commit
9de9633cac
7 changed files with 895 additions and 4 deletions
|
@ -17,10 +17,15 @@ except ImportError:
|
|||
HAS_GOOGLE_LIBRARIES = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, env_fallback
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_text
|
||||
import os
|
||||
|
||||
|
||||
def navigate_hash(source, path, default=None):
|
||||
if not source:
|
||||
return None
|
||||
|
||||
key = path[0]
|
||||
path = path[1:]
|
||||
if key not in source:
|
||||
|
@ -36,6 +41,28 @@ class GcpRequestException(Exception):
|
|||
pass
|
||||
|
||||
|
||||
def remove_nones_from_dict(obj):
|
||||
new_obj = {}
|
||||
for key in obj:
|
||||
value = obj[key]
|
||||
if value is not None and value != {} and value != []:
|
||||
new_obj[key] = value
|
||||
return new_obj
|
||||
|
||||
|
||||
# Handles the replacement of dicts with values -> the needed value for GCP API
|
||||
def replace_resource_dict(item, value):
|
||||
if isinstance(item, list):
|
||||
items = []
|
||||
for i in item:
|
||||
items.append(replace_resource_dict(i, value))
|
||||
return items
|
||||
else:
|
||||
if not item:
|
||||
return item
|
||||
return item.get(value)
|
||||
|
||||
|
||||
# Handles all authentation and HTTP sessions for GCP API calls.
|
||||
class GcpSession(object):
|
||||
def __init__(self, module, product):
|
||||
|
@ -47,25 +74,25 @@ class GcpSession(object):
|
|||
try:
|
||||
return self.session().get(url, json=body, headers=self._headers())
|
||||
except getattr(requests.exceptions, 'RequestException') as inst:
|
||||
raise GcpRequestException(inst.message)
|
||||
self.module.fail_json(msg=inst.message)
|
||||
|
||||
def post(self, url, body=None):
|
||||
try:
|
||||
return self.session().post(url, json=body, headers=self._headers())
|
||||
except getattr(requests.exceptions, 'RequestException') as inst:
|
||||
raise GcpRequestException(inst.message)
|
||||
self.module.fail_json(msg=inst.message)
|
||||
|
||||
def delete(self, url, body=None):
|
||||
try:
|
||||
return self.session().delete(url, json=body, headers=self._headers())
|
||||
except getattr(requests.exceptions, 'RequestException') as inst:
|
||||
raise GcpRequestException(inst.message)
|
||||
self.module.fail_json(msg=inst.message)
|
||||
|
||||
def put(self, url, body=None):
|
||||
try:
|
||||
return self.session().put(url, json=body, headers=self._headers())
|
||||
except getattr(requests.exceptions, 'RequestException') as inst:
|
||||
raise GcpRequestException(inst.message)
|
||||
self.module.fail_json(msg=inst.message)
|
||||
|
||||
def session(self):
|
||||
return AuthorizedSession(
|
||||
|
@ -148,7 +175,86 @@ class GcpModule(AnsibleModule):
|
|||
|
||||
AnsibleModule.__init__(self, *args, **kwargs)
|
||||
|
||||
def raise_for_status(self, response):
|
||||
try:
|
||||
response.raise_for_status()
|
||||
except getattr(requests.exceptions, 'RequestException') as inst:
|
||||
self.fail_json(msg="GCP returned error: %s" % response.json())
|
||||
|
||||
def _merge_dictionaries(self, a, b):
|
||||
new = a.copy()
|
||||
new.update(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.
|
||||
class GcpRequest(object):
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
|
||||
def __eq__(self, other):
|
||||
return not self.difference(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)
|
||||
|
||||
def _compare_dicts(self, dict1, dict2):
|
||||
difference = {}
|
||||
for key in dict1:
|
||||
difference[key] = self._compare_value(dict1.get(key), dict2.get(key))
|
||||
|
||||
# Remove all empty values from difference.
|
||||
difference2 = {}
|
||||
for key in difference:
|
||||
if difference[key]:
|
||||
difference2[key] = difference[key]
|
||||
|
||||
return difference2
|
||||
|
||||
# Takes in two lists and compares them.
|
||||
def _compare_lists(self, list1, list2):
|
||||
difference = []
|
||||
for index in range(len(list1)):
|
||||
value1 = list1[index]
|
||||
if index < len(list2):
|
||||
value2 = list2[index]
|
||||
difference.append(self._compare_value(value1, value2))
|
||||
|
||||
difference2 = []
|
||||
for value in difference:
|
||||
if value:
|
||||
difference2.append(value)
|
||||
|
||||
return difference2
|
||||
|
||||
def _compare_value(self, value1, value2):
|
||||
diff = None
|
||||
# If a None is found, a difference does not exist.
|
||||
# Only differing values matter.
|
||||
if not value2:
|
||||
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)
|
||||
# Always use to_text values to avoid unicode issues.
|
||||
elif to_text(value1) != to_text(value2):
|
||||
diff = value1
|
||||
# to_text may throw UnicodeErrors.
|
||||
# These errors shouldn't crash Ansible and should be hidden.
|
||||
except UnicodeError:
|
||||
pass
|
||||
|
||||
return diff
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue