1---
2#
3# Download firmware to the FI and configure Host Firmware Packages (HFP).
4# Uses remote fileshare and scp for FW download (server, remote_path, etc. provided through variables):
5# Example vars:
6#   [ucs:vars]
7#   remote_ip_address=172.28.224.77
8#   remote_fw_path=/mnt/SHARE/ISOS/UCS_Code/4.1
9#   remote_username=...
10#
11# The fw_bundles variable is a list that can be passed on the command line.
12# Example:
13# ansible-playbook ... -e '{"fw_bundles": ["ucs-k9-bundle-b-series.4.1.2b.B.bin"]}'
14#
15- hosts: ucs
16  connection: local
17  gather_facts: false
18  vars:
19    login_info: &login_info
20      hostname: "{{ inventory_hostname }}"
21      username: "{{ username | default(omit) }}"
22      password: "{{ password }}"
23  tasks:
24    - name: Download FW to FI
25      ucs_managed_objects:
26        <<: *login_info
27        objects:
28          - module: ucsmsdk.mometa.firmware.FirmwareCatalogue
29            class: FirmwareCatalogue
30            properties:
31              parent_mo_or_dn: sys
32            children:
33              - module: ucsmsdk.mometa.firmware.FirmwareDownloader
34                class: FirmwareDownloader
35                properties:
36                  protocol: scp
37                  server: "{{ remote_ip_address }}"
38                  remote_path: "{{ remote_fw_path }}"
39                  file_name: "{{ item }}"
40                  user: "{{ remote_username }}"
41                  pwd: "{{ remote_password }}"
42      loop: "{{ fw_bundles }}"
43      delegate_to: localhost
44      register: download_result
45    - name: Query and wait for download if needed
46      cisco.ucs.ucs_query:
47        <<: *login_info
48        distinguished_names: "{{ fw_download_dn }}"
49      loop: "{{ fw_bundles }}"
50      vars:
51        fw_download_dn: "sys/fw-catalogue/dnld-{{ item }}"
52      delegate_to: localhost
53      register: query_response
54      # works with warnings:
55      # until: query_response['objects']["{{ fw_download_dn }}"]['transfer_state'] == 'downloaded'
56      until: query_response.objects is search('downloaded')
57      # retry every 60 seconds for 20 minutes
58      delay: 60
59      retries: 20
60    # regular escapes in a set variable
61    - set_fact:
62        match_str: 'ucs-.*?\.(?P<rel>\d\.\d)\.(?P<patch>.*)\.'
63    # escape the escapes when used directly in strings
64    - set_fact:
65        blade_version: "{{ item | regex_replace(match_str + 'B\\.bin', '\\g<rel>(\\g<patch>)B') }}"
66      loop: "{{ fw_bundles }}"
67      when: item | regex_search(match_str + 'B\\.bin')
68    - set_fact:
69        rack_version: "{{ item | regex_replace(match_str + 'C\\.bin', '\\g<rel>(\\g<patch>)C') }}"
70      loop: "{{ fw_bundles }}"
71      when: item | regex_search(match_str + 'C\\.bin')
72    - name: Config Host FW Package
73      ucs_managed_objects:
74        <<: *login_info
75        objects:
76          - module: ucsmsdk.mometa.firmware.FirmwareComputeHostPack
77            class: FirmwareComputeHostPack
78            properties:
79              parent_mo_or_dn: org-root
80              name: ansible-latest
81              blade_bundle_version: "{{ blade_version | default(omit) }}"
82              rack_bundle_version: "{{ rack_version | default(omit) }}"
83      delegate_to: localhost
84