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

block/always on ansible tests #233

Open
wants to merge 159 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
159 commits
Select commit Hold shift + click to select a range
8d286d7
Initial MM commit
rambleraptor May 2, 2018
4d233d5
Ansible support on the Magician. (#7)
modular-magician May 29, 2018
c389004
Bringing Ansible to HEAD (#9)
modular-magician May 29, 2018
59d2b2f
Generates DefaultObjectACL and ObjectAccessControl resources.
nat-henderson Jun 1, 2018
c403181
SQL Databases (#12)
modular-magician Jun 1, 2018
d07f2ac
Ansible: SQL Users (#16)
modular-magician Jun 5, 2018
d09a4be
Added autogenerated header check (#18)
modular-magician Jun 5, 2018
43627db
Magic Modules changes.
rosbo Jun 5, 2018
1884c7e
Add description field to Route resource, make non-updateable.
nat-henderson Jun 14, 2018
a8232a0
Ansible doesn't need save_api_results
rambleraptor Jun 13, 2018
09a67bc
Magic Modules changes.
rambleraptor Jun 18, 2018
7c52a15
removing integration folders for deleted storage
rambleraptor Jun 18, 2018
1d509b2
Adding fetch back on certain places.
rambleraptor Jun 18, 2018
7976cf0
Spanner Instances + Databases
rambleraptor Jun 26, 2018
651edb5
Example refactor
modular-magician Jul 20, 2018
802d3ad
Adding Compute Facts (#60)
modular-magician Aug 6, 2018
9256c2f
Object.input should == noneditable (#62)
modular-magician Aug 15, 2018
3d115c2
add RegionDiskType
danawillow Aug 16, 2018
3a2805f
Partial updates (#63)
modular-magician Aug 20, 2018
3a57677
Add a few new fields to firewalls, and use PATCH instead of PUT for u…
danawillow Aug 20, 2018
57bd543
Magic Modules changes. (#79)
modular-magician Aug 27, 2018
2e06037
Minor updates to HealthCheck description, default values. (#78)
modular-magician Aug 28, 2018
c92e418
removed kind checks (#76)
modular-magician Aug 28, 2018
9fcb94b
BackendService LoadBalancingScheme + IAP support
modular-magician Aug 28, 2018
0c5df16
InstanceGroup should add/remove instances (#82)
modular-magician Aug 30, 2018
6f80bb4
Add settingsVersion property to Cloud SQL instance settings (#84)
modular-magician Sep 5, 2018
e724a08
make vpnTunnel.router into a ResourceRef
danawillow Sep 7, 2018
0df5fc4
examples showing an improper auth value (#87)
modular-magician Sep 7, 2018
e3b3514
Adding ability to override classes (#92)
modular-magician Sep 12, 2018
e834048
Minor schema/docs update to SslCertificate. (#89)
modular-magician Sep 12, 2018
e826a4b
Magic Modules changes. (#91)
modular-magician Sep 12, 2018
16124a5
Express project name in env variable (#94)
modular-magician Sep 20, 2018
aed81a8
Pubsub + DNS Facts (#75)
modular-magician Sep 21, 2018
6c32e1f
return_if_object should only allow 404 on certain situations (#93)
modular-magician Sep 21, 2018
cbffb78
Return values should be camelcase instead of underscored (#95)
modular-magician Sep 21, 2018
8e73ec0
2.8 changes (#98)
modular-magician Sep 21, 2018
84ff815
Magic Modules changes. (#97)
modular-magician Sep 24, 2018
3bd384f
Better documentation for how a resourceref works (#96)
modular-magician Sep 24, 2018
fb5ed3a
Add additional properties to VPC Network.
rileykarson Sep 25, 2018
ddd7347
Metadata encoder/decoder should allow empty values
modular-magician Sep 28, 2018
d139fa7
Reverting template change (#104)
modular-magician Sep 28, 2018
d77223f
Update urlMap properties
rileykarson Sep 28, 2018
7192f73
Merge pull request #102 from modular-magician/codegen-pr-475
rileykarson Oct 1, 2018
f13fc0a
remove min_version from a bunch of fields that are in GA now
danawillow Oct 4, 2018
3952f86
Merge pull request #107 from modular-magician/codegen-pr-524
danawillow Oct 4, 2018
5df6e5b
Merge pull request #106 from modular-magician/codegen-pr-514
rileykarson Oct 8, 2018
f8c46d6
labelfingerprint is beta for resources where labels are beta
danawillow Oct 9, 2018
9d250b6
Removing the <|extra|> marker because it's only used in DNS custom co…
modular-magician Oct 11, 2018
30caf7f
Magic Modules changes. (#101)
modular-magician Oct 11, 2018
8da785e
WIP: Add interconnect attachments.
nat-henderson Oct 11, 2018
b3f1256
Merge pull request #109 from modular-magician/codegen-pr-540
danawillow Oct 11, 2018
a7ab778
Merge pull request #13 from modular-magician/codegen-pr-210
nat-henderson Oct 11, 2018
d6c8fca
Minor docs changes for UrlMap
rileykarson Oct 12, 2018
9720967
Merge pull request #111 from modular-magician/codegen-pr-545
rileykarson Oct 15, 2018
f83c565
The Last of the Facts Modules
modular-magician Oct 16, 2018
6de55cb
Improve schema and docs for Google Cloud Storage ObjectAccessControl
rileykarson Oct 17, 2018
e50c3ed
Merge pull request #112 from modular-magician/codegen-pr-562
rileykarson Oct 17, 2018
d7ae9f0
Documentation Refactor
modular-magician Oct 23, 2018
624266e
Empty commit with no code changes
chrisst Oct 24, 2018
e42eba0
Merge pull request #121 from modular-magician/codegen-pr-616
chrisst Oct 24, 2018
f62665e
Changed scopes defaults on Facts modules
modular-magician Nov 2, 2018
c8c031f
Adding minCpuPlatform to InstanceTemplate
modular-magician Nov 2, 2018
4c814ba
Creating Service Accounts (#125)
modular-magician Nov 5, 2018
adf6ec9
Ansible Projects (#116)
modular-magician Nov 6, 2018
16447d0
Add labels and updates to DNS managed zone
drebes Nov 13, 2018
55324dc
Merge pull request #128 from modular-magician/codegen-pr-697
danawillow Nov 16, 2018
4d4db52
Splitting out a small typo fix unrelated from #697 (#130)
modular-magician Nov 19, 2018
20af191
Remove bad network update calls on Ansible
modular-magician Nov 26, 2018
d33f9be
Ansible: Instance On/Off
modular-magician Nov 27, 2018
074b753
Ansible Storage Upload/Download
modular-magician Nov 27, 2018
c0cb734
Add sslPolicy to a few resources.
danawillow Nov 28, 2018
5cbc78f
Fix bad type for Network routing_config.routing_mode (#136)
modular-magician Nov 29, 2018
7c0cd26
Ansible: Service Account Keys (#135)
modular-magician Nov 29, 2018
c77d5cb
Add support for content-based load balancing to HealthCheck (#138)
modular-magician Nov 30, 2018
54a2ed7
Fixing firewall issues on Ansible (#137)
modular-magician Dec 3, 2018
2260ac5
Conflicts-with (#133)
modular-magician Dec 4, 2018
29020a2
Ansible: Auth fix for scopes (#140)
modular-magician Dec 5, 2018
6d759b2
Ansible: `false`s being lost in network requests (#141)
modular-magician Dec 5, 2018
aa2beb8
Fixing integration tests on SQL + DNS (#139)
modular-magician Dec 5, 2018
9988260
Not Suppressing values accidentally (#143)
modular-magician Dec 6, 2018
2ee8c7b
removing interconnect tests
rambleraptor Dec 6, 2018
42abba7
Bigquery (#127)
modular-magician Dec 6, 2018
415ad93
Integration test fixes (#142)
modular-magician Dec 6, 2018
3395f14
Removing unused puppet code (#144)
modular-magician Dec 7, 2018
807b879
Merge pull request #134 from modular-magician/codegen-pr-952
danawillow Dec 7, 2018
eacb799
Allowing address to be settable
chrisst Dec 8, 2018
659fbbb
Merge pull request #146 from modular-magician/codegen-pr-1014
chrisst Dec 11, 2018
7d0eb7b
Ansible integration test fixes - pt 2 (#147)
modular-magician Dec 14, 2018
07425f6
Better resourceref flexibility (#149)
modular-magician Dec 14, 2018
8aff6fc
Misc. typo fixes (#150)
modular-magician Dec 19, 2018
9c530e9
add vpntunnel resourcerefs
danawillow Dec 29, 2018
8263c82
Initial addition of generated Image to Terraform. (#151)
modular-magician Jan 3, 2019
6c80682
fixing module utils (#153)
modular-magician Jan 3, 2019
d980c99
Add ResourceRefs for Compute Route. (#155)
modular-magician Jan 4, 2019
6fd209f
Merge pull request #152 from modular-magician/codegen-pr-1123
danawillow Jan 4, 2019
c4cdbe7
No-op docs tweak. (#161)
modular-magician Jan 10, 2019
7392400
Remove old gcompute wording (#163)
modular-magician Jan 10, 2019
56c372d
Formatting changes related to upstream code generator cleanup. (#162)
modular-magician Jan 15, 2019
7a4d90d
Using Native Ruby Types on AnsibleModule (#164)
modular-magician Jan 15, 2019
f745716
spelling correction (#167)
modular-magician Jan 16, 2019
80f7d61
Make Disk KMS features GA
chrisst Jan 16, 2019
99db919
Merge pull request #168 from modular-magician/codegen-pr-1259
chrisst Jan 16, 2019
2688e3b
Initial addition of generated spanner database to terraform. (#159)
modular-magician Jan 16, 2019
0bfdf12
Ansible async errors + printing formatter issues (#170)
modular-magician Jan 16, 2019
b635141
Ansible Cloud Source Repositories (#165)
modular-magician Jan 17, 2019
439dcc2
Fixing method name (#172)
modular-magician Jan 18, 2019
8eb9167
Description / doc changes related to spanner instances in Terraform. …
modular-magician Jan 22, 2019
015e4aa
Add vlan tag and subnet candidates to Interconnect Attachments. (#166)
modular-magician Jan 22, 2019
e78303e
Adding exception type on Ansible Service Account Keys (#174)
modular-magician Jan 23, 2019
c26f617
Ansible Redis (#173)
modular-magician Jan 28, 2019
e62380f
Upstream PR that fixed gcp_utils bug (#177)
modular-magician Jan 29, 2019
7081caa
Fix URL in documentation (#178)
modular-magician Jan 29, 2019
54175cc
Native Update Mask support (#176)
modular-magician Jan 30, 2019
bc6e339
Inspec regional cluster
slevenick Jan 30, 2019
09adc7d
Merge pull request #179 from modular-magician/codegen-pr-1295
slevenick Jan 30, 2019
b4170c2
response_to_hash should use api_name (#181)
modular-magician Jan 30, 2019
27e1dad
Fixing Ansible Integration tests (#175)
modular-magician Jan 30, 2019
57afbc7
Changing NodePool from Zone to Location (#182)
modular-magician Jan 31, 2019
d490275
Add fields to InterconnectAttachment to allow for PARTNER interconnec…
modular-magician Feb 2, 2019
ba323e9
Ansible CloudBuild Triggers (#184)
modular-magician Feb 6, 2019
49381c2
Ansible: better field names on gcp_compute_instance (#185)
modular-magician Feb 6, 2019
2a909a6
Changed Image.licenses to an array of resourcerefs instead of strings…
modular-magician Feb 8, 2019
a2791c4
Add sql settings for (#189)
modular-magician Feb 12, 2019
1703c66
Clarify Private Google Access docs on Subnetwork. (#187)
modular-magician Feb 14, 2019
ff41d93
Add TLSA to the list of allowed DNS record types (#192)
modular-magician Feb 15, 2019
80de604
Retrieve SOA record using DNS zone instead of building it from record…
modular-magician Feb 15, 2019
39f72ad
Add labels, update to Pubsub Subscription/Topic (#191)
modular-magician Feb 19, 2019
851964d
Ansible IAM Role (#195)
modular-magician Feb 25, 2019
c015cf9
Ansible - Unit test fix on diffing (#198)
modular-magician Feb 27, 2019
2c4cf3e
Use Ruby YAML library to serialize Ansible examples (#196)
modular-magician Feb 27, 2019
8e5608f
Improve docs for Cloud Build (#197)
modular-magician Mar 1, 2019
8e959e0
Add managed SSL cert to beta. (#194)
modular-magician Mar 1, 2019
c6b4fd0
Add retention duraction, retain acked message to pubsub (#202)
modular-magician Mar 6, 2019
117c0a6
Ansible - allowing for creds to be passed in as string/env var (#200)
modular-magician Mar 6, 2019
27ae9b3
Fix Network updating, improve docs. (#204)
modular-magician Mar 8, 2019
5db3c04
private clustering for container clusters (#205)
modular-magician Mar 11, 2019
66f0f18
Nested output: only properties shouldn't be fields (#207)
modular-magician Mar 11, 2019
6bdd379
Node Pool versioning (#206)
modular-magician Mar 11, 2019
5e07039
Update URLs in api.yml (#208)
modular-magician Mar 13, 2019
295a10a
boolean checks on difference checker (#210)
modular-magician Mar 13, 2019
e980df8
Add import support for organization_policies
chrisst Mar 13, 2019
382b07a
Terraform: Support for (Regional)Disk physicalBlockSizeBytes (#211)
modular-magician Mar 13, 2019
34c64fd
Merge pull request #212 from modular-magician/codegen-pr-1497
chrisst Mar 14, 2019
37a0865
Error in managed zone api (#213)
modular-magician Mar 14, 2019
9bf0215
Add post-create for VpnTunnels Labels (#218)
modular-magician Mar 20, 2019
4b3972b
Ansible - Remove output only from response (#216)
modular-magician Mar 20, 2019
1d315b1
Mark Forwarding Rule allPorts as GA (#219)
modular-magician Mar 25, 2019
dc4593d
Make forwarding rule service_label and service_name GA (#221)
modular-magician Mar 28, 2019
da4dd45
Add backend bucket signed URL key (for CDN) support (#209)
modular-magician Apr 1, 2019
d16dd13
Terraform: Make private Cloud DNS GA (#224)
modular-magician Apr 1, 2019
e7b1ec4
More Cloudbuild Trigger Step support (#223)
modular-magician Apr 2, 2019
b5d8af0
Add fingerprint, securityPolicy to BackendService (#222)
modular-magician Apr 2, 2019
ee1bd63
Reverting some ResourceRef changes (#226)
modular-magician Apr 3, 2019
aaf3bca
Update global address docs now that they are settable + ip ranges som…
modular-magician Apr 4, 2019
40dd93c
Cleanup BackendService after generation, add omitted fields. (#227)
modular-magician Apr 4, 2019
6e67c9a
Make cloudbuild trigger disabled field a bool (#230)
modular-magician Apr 8, 2019
4b488dc
Adding proper vars to tests (#225)
modular-magician Apr 15, 2019
5efccb6
Ansible - non-updatable resources should be deleted/created (#231)
modular-magician Apr 15, 2019
9fa4661
block/always on ansible tests
rambleraptor Apr 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 143 additions & 43 deletions lib/ansible/module_utils/gcp_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
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 ast
import os
import json


def navigate_hash(source, path, default=None):
Expand Down Expand Up @@ -60,10 +62,11 @@ def replace_resource_dict(item, value):
else:
if not item:
return item
return item.get(value)
else:
return item.get(value)


# Handles all authentation and HTTP sessions for GCP API calls.
# Handles all authentication and HTTP sessions for GCP API calls.
class GcpSession(object):
def __init__(self, module, product):
self.module = module
Expand All @@ -77,9 +80,25 @@ def get(self, url, body=None, **kwargs):
except getattr(requests.exceptions, 'RequestException') as inst:
self.module.fail_json(msg=inst.message)

def post(self, url, body=None):
def post(self, url, body=None, headers=None, **kwargs):
if headers:
headers = self.merge_dictionaries(headers, self._headers())
else:
headers = self._headers()

try:
return self.session().post(url, json=body, headers=headers)
except getattr(requests.exceptions, 'RequestException') as inst:
self.module.fail_json(msg=inst.message)

def post_contents(self, url, file_contents=None, headers=None, **kwargs):
if headers:
headers = self.merge_dictionaries(headers, self._headers())
else:
headers = self._headers()

try:
return self.session().post(url, json=body, headers=self._headers())
return self.session().post(url, data=file_contents, headers=headers)
except getattr(requests.exceptions, 'RequestException') as inst:
self.module.fail_json(msg=inst.message)

Expand All @@ -104,7 +123,7 @@ def patch(self, url, body=None, **kwargs):

def session(self):
return AuthorizedSession(
self._credentials().with_scopes(self.module.params['scopes']))
self._credentials())

def _validate(self):
if not HAS_REQUESTS:
Expand All @@ -115,33 +134,42 @@ def _validate(self):

if self.module.params.get('service_account_email') is not None and self.module.params['auth_kind'] != 'machineaccount':
self.module.fail_json(
msg="Service Acccount Email only works with Machine Account-based authentication"
msg="Service Account Email only works with Machine Account-based authentication"
)

if self.module.params.get('service_account_file') is not None and self.module.params['auth_kind'] != 'serviceaccount':
if (self.module.params.get('service_account_file') is not None or
self.module.params.get('service_account_contents') is not None) and self.module.params['auth_kind'] != 'serviceaccount':
self.module.fail_json(
msg="Service Acccount File only works with Service Account-based authentication"
msg="Service Account File only works with Service Account-based authentication"
)

def _credentials(self):
cred_type = self.module.params['auth_kind']
if cred_type == 'application':
credentials, project_id = google.auth.default()
credentials, project_id = google.auth.default(scopes=self.module.params['scopes'])
return credentials
elif cred_type == 'serviceaccount':
elif cred_type == 'serviceaccount' and self.module.params.get('service_account_file'):
path = os.path.realpath(os.path.expanduser(self.module.params['service_account_file']))
return service_account.Credentials.from_service_account_file(path)
return service_account.Credentials.from_service_account_file(path).with_scopes(self.module.params['scopes'])
elif cred_type == 'serviceaccount' and self.module.params.get('service_account_contents'):
cred = json.loads(self.module.params.get('service_account_contents'))
return service_account.Credentials.from_service_account_info(cred).with_scopes(self.module.params['scopes'])
elif cred_type == 'machineaccount':
return google.auth.compute_engine.Credentials(
self.module.params['service_account_email'])
else:
self.module.fail_json(msg="Credential type '%s' not implmented" % cred_type)
self.module.fail_json(msg="Credential type '%s' not implemented" % cred_type)

def _headers(self):
return {
'User-Agent': "Google-Ansible-MM-{0}".format(self.product)
}

def _merge_dictionaries(self, a, b):
new = a.copy()
new.update(b)
return new


class GcpModule(AnsibleModule):
def __init__(self, *args, **kwargs):
Expand All @@ -152,7 +180,10 @@ def __init__(self, *args, **kwargs):
kwargs['argument_spec'] = self._merge_dictionaries(
arg_spec,
dict(
project=dict(required=True, type='str'),
project=dict(
required=False,
type='str',
fallback=(env_fallback, ['GCP_PROJECT'])),
auth_kind=dict(
required=False,
fallback=(env_fallback, ['GCP_AUTH_KIND']),
Expand All @@ -166,6 +197,10 @@ def __init__(self, *args, **kwargs):
required=False,
fallback=(env_fallback, ['GCP_SERVICE_ACCOUNT_FILE']),
type='path'),
service_account_contents=dict(
required=False,
fallback=(env_fallback, ['GCP_SERVICE_ACCOUNT_CONTENTS']),
type='str'),
scopes=dict(
required=False,
fallback=(env_fallback, ['GCP_SCOPES']),
Expand All @@ -178,7 +213,7 @@ def __init__(self, *args, **kwargs):
mutual = kwargs['mutually_exclusive']

kwargs['mutually_exclusive'] = mutual.append(
['service_account_email', 'service_account_file']
['service_account_email', 'service_account_file', 'service_account_contents']
)

AnsibleModule.__init__(self, *args, **kwargs)
Expand All @@ -195,12 +230,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 @@ -211,31 +250,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 @@ -244,25 +300,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)
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

# Compare two boolean values.
def _compare_boolean(self, req_value, resp_value):
try:
# Both True
if req_value and isinstance(resp_value, bool) and resp_value:
return None
# Value1 True, resp_value 'true'
elif req_value and to_text(resp_value) == 'true':
return None
# Both False
elif not req_value and isinstance(resp_value, bool) and not resp_value:
return None
# Value1 False, resp_value 'false'
elif not req_value and to_text(resp_value) == 'false':
return None
else:
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)
Loading