diff --git a/plugins/action/query_graphql.py b/plugins/action/query_graphql.py index 7258a534..7478883b 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") + update_hostvars = args.get("update_hostvars", False) + Display().vv("Update hostvars is set to: %s" % update_hostvars) # nosec + + # Verify SSL Verify is of 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") Display().v("Query String: %s" % query) @@ -90,7 +97,12 @@ 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 + # 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("update_hostvars"): + results["ansible_facts"] = 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 9320e669..7f6a02ae 100644 --- a/plugins/modules/query_graphql.py +++ b/plugins/modules/query_graphql.py @@ -50,6 +50,14 @@ required: False default: True type: bool + 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 + will overwrite any root keys already present, leverage the GraphQL alias feature to avoid issues. + required: False + default: False + type: bool """ EXAMPLES = """ @@ -82,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 }}" + update_hostvars: "yes" """ RETURN = """ @@ -145,6 +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), + 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 118a568c..2b9db051 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_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) == "update_hostvars 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..41af97e9 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": {}, + "update_hostvars": False, }