I've been getting started with the CICS collection on Ansible Galaxy. I've been using it to do things like request individual resources, but I can't see a way of traversing relationships like you would do in CICS' CMCI GraphQL API.
Does the collection have that ability?
No, the CICS collection doesn't have the ability to use the CMCI GraphQL API. It purely uses the CMCI REST API which just deals with one resource type at a type.
However, that doesn't mean you can't use the CMCI GraphQL API to CICS from Ansible! That API is generally a bit more understandable and you can build up queries using GraphiQL without needing a special collection. Then, you can use Ansible's built-in uri
module to send GraphQL requests and get information out of the response.
Here, for example, is a simple playbook and accompanying GraphQL query to get the structure of a CICSplex with its CICS regions, and print out the result. The important part is the query
key being added to the body
of the request.
playbook1.yml
:
- hosts: localhost
tasks:
- name: Get data from CICS
register: result
uri:
url: https://my.cicsplex:12345/graphql/
method: POST
body_format: json
body:
query: '{{ lookup("file", "./queries/topology_query.graphql") }}' # GraphQL query is passed here
- name: Print out response
debug:
msg: '{{ result.json }}'
queries/topology_query.graphql
:
{
cicsplexes {
name
regions {
name
}
}
}
Of course, you probably want to parameterise the query. You can do that using Jinja templating in Ansible. Here's a playbook and accompanying GraphQL query to find a particular region name (named MYREGION
, in the vars
) across all connected CICSplexes.
playbook2.yml
:
- hosts: localhost
vars:
regionName: MYREGION
tasks:
- name: Get data from CICS
register: result
uri:
url: https://my.cicsplex:12345/graphql/
method: POST
body_format: json
body:
query: '{{ lookup("template", "./templates/single_region_query.graphql.j2") }}' # template instead of plain file
- name: Print out response
debug:
msg: '{{ result.json }}'
templates/single_region_query.graphql.j2
:
{
cicsplexes {
name
region(name: "{{ regionName }}") { # this variable will be expanded by Ansible
name
}
}
}
However, I get a bit leery about templating. It seems fairly prone to injection problems, be they malicious or just accidental, when vars are coming in from elsewhere! Even writing the example above, I missed getting the quotes right. So I'd prefer to use GraphQL's built-in variable support to sanitise variables better.
In CICS' CMCI GraphQL API, you can supply variables using the variables
key in the body of the request you send to CICS, alongside the existing query
key.
Here you see the regionName
variable being supplied in the body, and then the same variable (referred to as $regionName
) in the GraphQL query.
playbook3.yml
:
- hosts: localhost
vars:
regionName: MYREGION
tasks:
- name: Get data from plex
register: result
uri:
url: https://my.cicsplex:12345/graphql/
method: POST
body_format: json
body:
query: '{{ lookup("file", "./queries/single_region_query.graphql") }}' # plain file, not template
variables:
regionName: "{{ regionName }}" # variables will get passed to CICS
- name: Print out response
debug:
msg: '{{ result.json }}'
queries/single_region_query.graphql
:
query searchForRegion ($regionName: String!) { # query declares used variables
cicsplexes {
name
region(name: $regionName) { # GraphQL expands the variable here at query execution time
name
}
}
}