Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible search for a substring in stdout output

Team, I am trying to match a version and that fails when whole string does not match. so I just want to match first two octects. I tried several combons but no luck.

      - name: "Validate k8s version"
        shell: "kubectl version --short"
        register: k8s_version_live
        failed_when: k8s_version_live.stdout_lines is not search("{{ k8s_server_version }}")
        #failed_when: "'{{ k8s_server_version }}' not in k8s_version_live.stdout_lines"
        ignore_errors: yes
      - debug:
          var: k8s_version_live.stdout_lines

output:


[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: k8s_version_live.stdout_lines is not search("{{
k8s_server_version }}")

fatal: [localhost]: FAILED! => {"changed": true, "cmd": "kubectl version --short", "delta": "0:00:00.418128", "end": "2019-12-05 02:13:15.108997", "failed_when_result": true, "rc": 0, "start": "2019-12-05 02:13:14.690869", "stderr": "", "stderr_lines": [], "stdout": "Client Version: v1.13.3\nServer Version: v1.13.10", "stdout_lines": ["Client Version: v1.13.3", "Server Version: v1.13.10"]}
...ignoring

TASK [team-services-pre-install-checks : debug] *************************************************************************************************************************
Thursday 05 December 2019  02:13:15 +0000 (0:00:00.902)       0:00:01.039 *****
ok: [localhost] => {
    "k8s_version_live.stdout_lines": [
        "Client Version: v1.13.3",
        "Server Version: v1.13.10"
    ]
}```
like image 648
AhmFM Avatar asked Dec 18 '25 16:12

AhmFM


2 Answers

As the error says:

conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}.

In a conditional statement, you are already inside a Jinja template context. You can just refer to variables by name:

- name: "Validate k8s version"
  shell: "kubectl version --short"
  register: k8s_version_live
  failed_when: k8s_version_live.stdout_lines is not search(k8s_server_version)
  ignore_errors: yes

Although you probably want k8s_version_live.stdout instead of k8s_version_live.stdout_lines.

I would probably write the task as:

- name: "Validate k8s version"
  command: "kubectl version --short"
  register: k8s_version_live
  failed_when: k8s_server_version not in k8s_version_live.stdout
  ignore_errors: true
like image 111
larsks Avatar answered Dec 20 '25 04:12

larsks


Update

Given the command output

k8s_version_live:
  stdout_lines:
    - "Client Version: v1.13.3"
    - "Server Version: v1.13.10"

Create the dictionary

versions: "{{ k8s_version_live.stdout_lines | map('from_yaml')
                                            | combine }}"

gives

versions:
  Client Version: v1.13.3
  Server Version: v1.13.10

Now, the comparision is trivial. Put the version into a variable

k8s_server_version: v1.13.10

and compare the versions. The below task is skipped

- fail:
    msg: "{{ versions['Server Version'] }} does not match {{ k8s_server_version }}"
  when: versions['Server Version'] is not version(k8s_server_version, '==')

Use the dictionary to test the output of a command. For example,

- command: 'printf "Client Version: v1.13.3\nServer Version: v1.13.10"'
  register: k8s_version_live
  failed_when: versions['Server Version'] is not version(k8s_server_version, '==')

- debug:
    var: k8s_version_live.stdout_lines

gives

TASK [command] *********************************************************************
changed: [localhost]

TASK [debug] *********************************************************************
ok: [localhost] => 
    k8s_version_live.stdout_lines:
    - 'Client Version: v1.13.3'
    - 'Server Version: v1.13.10'

Example of a complete playbok for testing

- hosts: localhost

  vars:

    k8s_server_version: v1.13.10
    k8s_version_live:
      stdout_lines:
        - "Client Version: v1.13.3"
        - "Server Version: v1.13.10"
    versions: "{{ k8s_version_live.stdout_lines | map('from_yaml') | combine }}"
    
  tasks:

    - debug:
        var: versions

    - fail:
        msg: "{{ versions['Server Version'] }} does not match {{ k8s_server_version }}"
      when: versions['Server Version'] is not version(k8s_server_version, '==')

    - command: 'printf "Client Version: v1.13.3\nServer Version: v1.13.10"'
      register: k8s_version_live
      failed_when: versions['Server Version'] is not version(k8s_server_version, '==')

    - debug:
        var: k8s_version_live.stdout_lines

Q: "Match a version ... match first two octets"

A: Use Version Comparison. For example, create the variable k8s_server_version from the registred output

- set_fact:
    k8s_server_version: "{{ k8s_version_live.stdout_lines.1.split(':').1[2:] }}"

Compare the first two numbers of the version

- debug:
    msg: "{{ k8s_server_version }} match 1.13"
  when:
    - k8s_server_version is version('1.13', '>=')
    - k8s_server_version is version('1.14', '<')

gives

    }
    localhost | SUCCESS => {
        "msg": "1.13.10 match 1.13"
    }

Fail when the version does not match

- fail:
    msg: "{{ k8s_server_version }} does not match 1.12"
  when: not (k8s_server_version is version('1.12', '>=') and
             k8s_server_version is version('1.13', '<'))

gives

    localhost | FAILED! => {
        "changed": false, 
        "msg": "1.13.10 does not match 1.12"
    }
like image 25
Vladimir Botka Avatar answered Dec 20 '25 06:12

Vladimir Botka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!