From 995cda7ec43f06456d0c93d7c7449913fa272113 Mon Sep 17 00:00:00 2001 From: itdependsnetworks Date: Sat, 11 Sep 2021 00:49:23 -0400 Subject: [PATCH 1/6] fixes #67 --- plugins/action/query_graphql.py | 17 +++++++++++++++-- plugins/modules/query_graphql.py | 9 +++++++++ tests/unit/action/test_graphql_query.py | 8 ++++++++ tests/unit/conftest.py | 1 + 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index 7258a534..2341e96f 100644 --- a/plugins/action/query_graphql.py +++ b/plugins/action/query_graphql.py @@ -45,6 +45,13 @@ def nautobot_action_graphql(args): if not isinstance(ssl_verify, bool): raise AnsibleError("validate_certs must be a boolean") + populate_root = args.get("populate_root", False) + Display().vv("Populate root is set to: %s" % populate_root) + + # Verify SSL Verify is of boolean + if not isinstance(populate_root, bool): + raise AnsibleError("populate_root must be a boolean") + nautobot_api = NautobotApiBase(token=token, url=url, ssl_verify=ssl_verify) query = args.get("query") Display().v("Query String: %s" % query) @@ -90,8 +97,14 @@ def nautobot_action_graphql(args): # Good result, return it if isinstance(nautobot_response, pynautobot.core.graphql.GraphQLRecord): - # Assign the data of a good result to the response - results["data"] = nautobot_response.json.get("data") + # If populate_root is set, add to ansible_facts which will set to the root of + # the data structure, e.g. hostvars[inventory_hostname] + if args.get("populate_root"): + results["ansible_facts"] = nautobot_response.json.get("data") + else: + # Assign the data of a good result to the response to the data key + # otherwise, e.g. hostvars[inventory_hostname]['data'] + results["data"] = nautobot_response.json.get("data") return results diff --git a/plugins/modules/query_graphql.py b/plugins/modules/query_graphql.py index 9320e669..5880967c 100644 --- a/plugins/modules/query_graphql.py +++ b/plugins/modules/query_graphql.py @@ -50,6 +50,14 @@ required: False default: True type: bool + populate_root: + description: + - Whether or not to populate data in the in the root (e.g. hostvars[inventory_hostname]) or within the + 'data' key (e.g. hostvars[inventory_hostname]['data']). Beware, that the root keys provided by the query + will overwrite any root keys already present, leverage the GraphQL alias feature to avoid issues. + required: False + default: False + type: bool """ EXAMPLES = """ @@ -145,6 +153,7 @@ def main(): token=dict(required=False, type="str", no_log=True, default=None), url=dict(required=False, type="str", default=None), validate_certs=dict(required=False, type="bool", default=True), + populate_root=dict(required=False, type="bool", default=False), ), # Set to true as this is a read only API, this may need to change or have significant changes when Mutations are # added to the GraphQL endpoint of Nautobot diff --git a/tests/unit/action/test_graphql_query.py b/tests/unit/action/test_graphql_query.py index 118a568c..6dd8c593 100644 --- a/tests/unit/action/test_graphql_query.py +++ b/tests/unit/action/test_graphql_query.py @@ -30,6 +30,14 @@ def test_setup_api_error_incorrect_validate_certs(nautobot_valid_args): assert str(exc.value) == "validate_certs must be a boolean" +def test_setup_api_error_incorrect_populate_root(nautobot_valid_args): + nautobot_valid_args["populate_root"] = "Hi" + with pytest.raises(AnsibleError) as exc: + test_class = nautobot_action_graphql(args=nautobot_valid_args) + + assert str(exc.value) == "populate_root must be a boolean" + + def test_query_api_query_error_none(nautobot_valid_args): nautobot_valid_args["query"] = None with pytest.raises(AnsibleError) as exc: diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index c2be026a..67786aae 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -58,4 +58,5 @@ def nautobot_valid_args(graphql_test_query): "validate_certs": False, "query": graphql_test_query, "graph_variables": {}, + "populate_root": False, } From 8b9815849e8306580ac88204bd77b1bd94698590 Mon Sep 17 00:00:00 2001 From: itdependsnetworks Date: Mon, 13 Sep 2021 22:56:29 -0400 Subject: [PATCH 2/6] update example --- plugins/modules/query_graphql.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/modules/query_graphql.py b/plugins/modules/query_graphql.py index 5880967c..39a5b859 100644 --- a/plugins/modules/query_graphql.py +++ b/plugins/modules/query_graphql.py @@ -90,22 +90,23 @@ site_name: den query_string: | query ($site_name:String!) { - sites (name: $site_name) { + sites (name: $site_name) { id name region { name } - } + } } - # Get Response with variables + # Get Response with variables and set to root keys - name: Obtain list of devices at site in variables from Nautobot networktocode.nautobot.query_graphql: url: http://nautobot.local token: thisIsMyToken query: "{{ query_string }}" variables: "{{ variables }}" + populate_root: "yes" """ RETURN = """ From 6553a0cec4fbe0bfd2dadb96ab47629cd00808fe Mon Sep 17 00:00:00 2001 From: itdependsnetworks Date: Thu, 16 Sep 2021 11:12:31 -0400 Subject: [PATCH 3/6] change configure option name --- plugins/action/query_graphql.py | 19 +++++++++---------- plugins/modules/query_graphql.py | 6 +++--- tests/unit/action/test_graphql_query.py | 6 +++--- tests/unit/conftest.py | 2 +- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index 2341e96f..440732bf 100644 --- a/plugins/action/query_graphql.py +++ b/plugins/action/query_graphql.py @@ -45,12 +45,12 @@ def nautobot_action_graphql(args): if not isinstance(ssl_verify, bool): raise AnsibleError("validate_certs must be a boolean") - populate_root = args.get("populate_root", False) - Display().vv("Populate root is set to: %s" % populate_root) + update_hostvars = args.get("update_hostvars", False) + Display().vv("Populate root is set to: %s" % update_hostvars) # Verify SSL Verify is of boolean - if not isinstance(populate_root, bool): - raise AnsibleError("populate_root must be a boolean") + if not isinstance(update_hostvars, bool): + raise AnsibleError("update_hostvars must be a boolean") nautobot_api = NautobotApiBase(token=token, url=url, ssl_verify=ssl_verify) query = args.get("query") @@ -97,14 +97,13 @@ def nautobot_action_graphql(args): # Good result, return it if isinstance(nautobot_response, pynautobot.core.graphql.GraphQLRecord): - # If populate_root is set, add to ansible_facts which will set to the root of + # If update_hostvars is set, add to ansible_facts which will set to the root of # the data structure, e.g. hostvars[inventory_hostname] - if args.get("populate_root"): + if args.get("update_hostvars"): results["ansible_facts"] = nautobot_response.json.get("data") - else: - # Assign the data of a good result to the response to the data key - # otherwise, e.g. hostvars[inventory_hostname]['data'] - results["data"] = nautobot_response.json.get("data") + # Assign to data regardless a good result to the response to the data key + # e.g. hostvars[inventory_hostname]['data'] + results["data"] = nautobot_response.json.get("data") return results diff --git a/plugins/modules/query_graphql.py b/plugins/modules/query_graphql.py index 39a5b859..7f6a02ae 100644 --- a/plugins/modules/query_graphql.py +++ b/plugins/modules/query_graphql.py @@ -50,7 +50,7 @@ required: False default: True type: bool - populate_root: + update_hostvars: description: - Whether or not to populate data in the in the root (e.g. hostvars[inventory_hostname]) or within the 'data' key (e.g. hostvars[inventory_hostname]['data']). Beware, that the root keys provided by the query @@ -106,7 +106,7 @@ token: thisIsMyToken query: "{{ query_string }}" variables: "{{ variables }}" - populate_root: "yes" + update_hostvars: "yes" """ RETURN = """ @@ -154,7 +154,7 @@ def main(): token=dict(required=False, type="str", no_log=True, default=None), url=dict(required=False, type="str", default=None), validate_certs=dict(required=False, type="bool", default=True), - populate_root=dict(required=False, type="bool", default=False), + update_hostvars=dict(required=False, type="bool", default=False), ), # Set to true as this is a read only API, this may need to change or have significant changes when Mutations are # added to the GraphQL endpoint of Nautobot diff --git a/tests/unit/action/test_graphql_query.py b/tests/unit/action/test_graphql_query.py index 6dd8c593..2b9db051 100644 --- a/tests/unit/action/test_graphql_query.py +++ b/tests/unit/action/test_graphql_query.py @@ -30,12 +30,12 @@ def test_setup_api_error_incorrect_validate_certs(nautobot_valid_args): assert str(exc.value) == "validate_certs must be a boolean" -def test_setup_api_error_incorrect_populate_root(nautobot_valid_args): - nautobot_valid_args["populate_root"] = "Hi" +def test_setup_api_error_incorrect_update_hostvars(nautobot_valid_args): + nautobot_valid_args["update_hostvars"] = "Hi" with pytest.raises(AnsibleError) as exc: test_class = nautobot_action_graphql(args=nautobot_valid_args) - assert str(exc.value) == "populate_root must be a boolean" + assert str(exc.value) == "update_hostvars must be a boolean" def test_query_api_query_error_none(nautobot_valid_args): diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 67786aae..41af97e9 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -58,5 +58,5 @@ def nautobot_valid_args(graphql_test_query): "validate_certs": False, "query": graphql_test_query, "graph_variables": {}, - "populate_root": False, + "update_hostvars": False, } From 45796927c10a1a99556aa740650dd4354773e12e Mon Sep 17 00:00:00 2001 From: Ken Celenza Date: Thu, 16 Sep 2021 11:31:40 -0400 Subject: [PATCH 4/6] Update plugins/action/query_graphql.py Co-authored-by: Josh VanDeraa --- plugins/action/query_graphql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index 440732bf..78225737 100644 --- a/plugins/action/query_graphql.py +++ b/plugins/action/query_graphql.py @@ -46,7 +46,7 @@ def nautobot_action_graphql(args): raise AnsibleError("validate_certs must be a boolean") update_hostvars = args.get("update_hostvars", False) - Display().vv("Populate root is set to: %s" % update_hostvars) + Display().vv("Update hostvars is set to: %s" % update_hostvars) # Verify SSL Verify is of boolean if not isinstance(update_hostvars, bool): From c2da247d55f17fefceb3a4f6a4ffa6c9d671af1e Mon Sep 17 00:00:00 2001 From: Josh VanDeraa Date: Thu, 16 Sep 2021 11:08:04 -0500 Subject: [PATCH 5/6] Update query_graphql.py Removes display from bandit. --- plugins/action/query_graphql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index 78225737..d867788b 100644 --- a/plugins/action/query_graphql.py +++ b/plugins/action/query_graphql.py @@ -46,7 +46,7 @@ def nautobot_action_graphql(args): raise AnsibleError("validate_certs must be a boolean") update_hostvars = args.get("update_hostvars", False) - Display().vv("Update hostvars is set to: %s" % update_hostvars) + Display().vv("Update hostvars is set to: %s" % update_hostvars) # nosec # Verify SSL Verify is of boolean if not isinstance(update_hostvars, bool): From c0e37fbeef5014121ae3d2831d3306afd7ebb5a2 Mon Sep 17 00:00:00 2001 From: Josh VanDeraa Date: Thu, 16 Sep 2021 11:22:44 -0500 Subject: [PATCH 6/6] Update query_graphql.py --- plugins/action/query_graphql.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index d867788b..7478883b 100644 --- a/plugins/action/query_graphql.py +++ b/plugins/action/query_graphql.py @@ -46,7 +46,7 @@ def nautobot_action_graphql(args): raise AnsibleError("validate_certs must be a boolean") update_hostvars = args.get("update_hostvars", False) - Display().vv("Update hostvars is set to: %s" % update_hostvars) # nosec + Display().vv("Update hostvars is set to: %s" % update_hostvars) # nosec # Verify SSL Verify is of boolean if not isinstance(update_hostvars, bool):