0

Team, I have output and am trying to fail/pass based on existence of a string in the json response that am getting. any hint?

      - name: "Fetch all gpu/dgx nodes from clusters using K8s facts"
        k8s_facts:
          kubeconfig: $WORKSPACE
          kind: Node
          label_selectors:
          - nodeType=gpu
          verify_ssl: no
        register: node_list

      - debug:
          var: node_list
      - debug:
          var: node_list | json_query(query)
        vars:
          query: 'resources[].{node_name: metadata.name, nodeType: metadata.labels.nodeType}'
        failed_when: '"gpu" not in query.results'
TASK [2_k8s_validations : debug] ******************************************************************************************************************************************************************
ok: [target1] => {
    "node_list | json_query(query)": [
        {
            "nodeType": "gpu",
            "node_name": "dgx"
        },
        {
            "nodeType": "gpu",
            "node_name": "dgx"
        }
    ]
}```

TASK [2_k8s_validations : debug] ****************************************************************************************************************************************************************** fatal: [target1]: FAILED! => {"msg": "The conditional check '\"gpu\" not in query.results' failed. The error was: error while evaluating conditional (\"gpu\" not in query.results): Unable to look up a name or access an attribute in template string ({% if \"gpu\" not in query.results %} True {% else %} False {% endif %}).\nMake sure your variable name does not contain invalid characters like '-': argument of type 'AnsibleUndefined' is not iterable"}

PLAY RECAP ************************************************** target1 : ok=10 changed=5 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0


AhmFM
  • 1,552
  • 3
  • 23
  • 53
  • Separately, `debug: var:` is for **variables** but `node_list | json_query(query)` is not a _variable_ it's an _expression_; it's a damn miracle that ansible more-or-less did what you asked, but I wouldn't get into the habit of counting on that, since it is likely undefined behavior – mdaniel Oct 23 '19 at 02:55

1 Answers1

2

You have a misunderstanding; vars: only declares "local" variables for the current task. Since you just declared a variable named query, and that variable is not a dict, then it has no such child property .results

Very likely you want to use set_fact: to assert a new ansible fact into the hostvars structure, so you can then use it like you attempted to do:

  - set_fact:
      nodes_with_node_type: '{{ node_list | json_query(query) }}'
    vars:
      query: 'resources[].{node_name: metadata.name, nodeType: metadata.labels.nodeType}'

  - fail:
      msg: Expected to find at least one GPU node type
    vars:
      node_types: '{{ nodes_with_node_type | map(attribute="nodeType") | list }}'
    when: '"gpu" not in node_types'

Separate from your specific question, the actual task you are trying to accomplish is utter nonsense, given that your selector on the k8s_facts: explicitly asks for nodeType=gpu -- there will not be any other kinds of Nodes that are returned and thus the when: will never be true

mdaniel
  • 31,240
  • 5
  • 55
  • 58
  • thanks, the reason to check for when: was in terms of response [success/failure] and also, that gpu nodes exists, coz sometimes they are just lost so not literally only for a string compare am using when:. do you suggest any other way if i made sense now? – AhmFM Oct 23 '19 at 04:31
  • Also: am learning this, but can you possible post a looping solution to this where I can loop over only the values of the keys and then ssh them? below is my question. `https://stackoverflow.com/questions/58498378/ansible-ssh-to-json-query-response-values-in-loop/58501003#58501003` – AhmFM Oct 23 '19 at 04:47