2

I have the following playbook that is trying to assert that a user prompt variable of NX-OS image equals the ansible_net_image captured from a Nexus switch. This is driving me crazy as to the correct format for the test condition.

---
- name: Upgrade NX-OS on switch with pre-checks to load image as required
  hosts:  nexus-7000
  gather_facts: no
  vars_prompt:
    - name: NX_OS_Upgrade_Version
      prompt: "Please enter NX-OS version to upgrade too - ensure that the filename is as used by boot variable"
      private: no
  ##############################################################################
  ## Start of task execution
  ##############################################################################
  tasks:
  - name: Gather IOS configuration and software facts from switches
    nxos_facts:
      gather_subset: "!hardware"
################################################################################
## Display running image version to terminal
################################################################################
  - debug:
      msg: "{{ NX_OS_Upgrade_Version }}"
  - assert:
      that:
        - "ansible_net_image | regex:/^bootflash:\\/\\/\\/(.*) ==  NX_OS_Upgrade_Version"

Upon execution this error is displayed.

fatal: [switcha]: FAILED! => {"msg": "The conditional check 'ansible_net_image | regex:/^bootflash:\/\/\/(.) == NX_OS_Upgrade_Version' failed. The error was: template error while templating string: expected token 'end of statement block', got '/'. String: {% if ansible_net_image | regex:/^bootflash:\/\/\/(.) == NX_OS_Upgrade_Version %} True {% else %} False {% endif %}"} fatal: [switchb]: FAILED! => {"msg": "The conditional check 'ansible_net_image | regex:/^bootflash:\/\/\/(.) == NX_OS_Upgrade_Version' failed. The error was: template error while templating string: expected token 'end of statement block', got '/'. String: {% if ansible_net_image | regex:/^bootflash:\/\/\/(.) == NX_OS_Upgrade_Version %} True {% else %} False {% endif %}"}

The regex has been tested, but I am struggling to get the correct syntax for the Ansible play.

It would be great if someone could show me what I have got wrong.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
MikefNZ
  • 21
  • 1
  • 2

1 Answers1

2

Update

Q: "Check the version, copy a new image, and upgrade if required."

A: You can test the version. See Comparing versions. For example, given the current image for testing

  ansible_net_image: bootflash:///n5000-uk9-kickstart.5.1.3.N2.1b.bin

Get the version. Declare the variable

  ani_version: "{{ ansible_net_image|
                   splitext|first|
                   split('.', 1)|last }}"

gives

  ani_version: 5.1.3.N2.1b

Then test the version. In your question, you try to find out whether the versions are equal or not. This can be achieved by the comparison '==' below

    - assert:
        that: ani_version is version(NX_OS_Upgrade_Version, '==')
        success_msg: "Image is version {{ NX_OS_Upgrade_Version }}"
        fail_msg: "Image is NOT version {{ NX_OS_Upgrade_Version }}"

But, to check whether the image is newer or not you might want to use the comparison '<'

    - assert:
        that: ani_version is version(NX_OS_Upgrade_Version, '<')
        success_msg: "Image is newer version {{ NX_OS_Upgrade_Version }}"
        fail_msg: "Image is not newer version {{ NX_OS_Upgrade_Version }}"

Example of a complete playbook for testing

shell> cat pb.yml
- hosts: localhost

  vars:

    ani_version: "{{ ansible_net_image|
                     splitext|first|
                     split('.', 1)|last }}"

  vars_prompt:
    - name: NX_OS_Upgrade_Version
      prompt: Please enter NX-OS version to upgrade to
      private: no

  tasks:

    - name: Gather IOS configuration and software facts from switches
      # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      # For testing use *set_fact* instead of *nxos_facts*
      # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      # nxos_facts:
      #   gather_subset: "!hardware"
      set_fact:
        ansible_net_image: bootflash:///n5000-uk9-kickstart.5.1.3.N2.1b.bin

    - debug:
        msg: |
          ani_version: {{ ani_version }}
          NX_OS_Upgrade_Version: {{ NX_OS_Upgrade_Version }}

    - assert:
        # that: ani_version is version(NX_OS_Upgrade_Version, '==')
        # success_msg: "Image is version {{ NX_OS_Upgrade_Version }}"
        # fail_msg: "Image is NOT version {{ NX_OS_Upgrade_Version }}"
        that: ani_version is version(NX_OS_Upgrade_Version, '<')
        success_msg: "Image is newer version {{ NX_OS_Upgrade_Version }}"
        fail_msg: "Image is not newer version {{ NX_OS_Upgrade_Version }}"

    - debug:
        msg: Copy and upgrade new image.

Copy and upgrade the new image

shell> ansible-playbook pb.yml
Please enter NX-OS version to upgrade to: 5.1.3.N2.1c

PLAY [localhost] ******************************************************************************

TASK [Gather IOS configuration and software facts from switches] ******************************
ok: [localhost]

TASK [debug] **********************************************************************************
ok: [localhost] => 
  msg: |-
    ani_version: 5.1.3.N2.1b
    NX_OS_Upgrade_Version: 5.1.3.N2.1c

TASK [assert] *********************************************************************************
ok: [localhost] => changed=false 
  msg: Image is newer version 5.1.3.N2.1c

TASK [debug] **********************************************************************************
ok: [localhost] => 
  msg: Copy and upgrade new image.

PLAY RECAP ************************************************************************************
localhost: ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Fails if the image is not newer

shell> ansible-playbook pb.yml
Please enter NX-OS version to upgrade to: 5.1.3.N2.1b

PLAY [localhost] ******************************************************************************

TASK [Gather IOS configuration and software facts from switches] ******************************
ok: [localhost]

TASK [debug] **********************************************************************************
ok: [localhost] => 
  msg: |-
    ani_version: 5.1.3.N2.1b
    NX_OS_Upgrade_Version: 5.1.3.N2.1b

TASK [assert] *********************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  assertion: ani_version is version(NX_OS_Upgrade_Version, '<')
  evaluated_to: false
  msg: Image is not newer version 5.1.3.N2.1b

PLAY RECAP ************************************************************************************
localhost: ok=2    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Origin

For example,

- hosts: localhost

  vars:

    ansible_net_image: 'bootflash:///n5000-uk9-kickstart.5.1.3.N2.1b.bin'
    NX_OS_Upgrade_Version1: 'n5000-uk9-kickstart.5.1.3.N2.1b'
    my_regex1: '^bootflash:///{{ NX_OS_Upgrade_Version1 }}.bin'
    NX_OS_Upgrade_Version2: 'n5000-uk9-kickstart.5.1.4.N2.1b'
    my_regex2: '^bootflash:///{{ NX_OS_Upgrade_Version2 }}.bin'

  tasks:

    - assert:
        that: ansible_net_image is match(my_regex1)
        success_msg: "Image is version {{ NX_OS_Upgrade_Version1 }}"
        fail_msg: "Image is NOT version {{ NX_OS_Upgrade_Version1 }}"

    - assert:
        that: ansible_net_image is match(my_regex2)
        success_msg: "Image is version {{ NX_OS_Upgrade_Version2 }}"
        fail_msg: "Image is NOT version {{ NX_OS_Upgrade_Version2 }}"

gives (abridged)

TASK [assert] *************************************************************
ok: [localhost] => changed=false 
  msg: Image is version n5000-uk9-kickstart.5.1.3.N2.1b

TASK [assert] *************************************************************
fatal: [localhost]: FAILED! => changed=false 
  assertion: ansible_net_image is match(my_regex2)
  evaluated_to: false
  msg: Image is NOT version n5000-uk9-kickstart.5.1.4.N2.1b
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • Hi Vladimir for your response. This works but is there a way to achieve the same using the vars_prompt for user input and the nxos_facts: ansible_net_image variable? I don't want to hard code the variables every time the play is run against switches with different versions. The intent is to check the version and copy a new image and upgrade if required. – MikefNZ Dec 19 '19 at 00:53