Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve Issue #63: Add Support for Token Authentication and User/Pass Authentication in BMC Firmware Update #89

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions .github/workflows/ansible.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,8 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]
python-version: ["3.10", "3.11", "3.12"]
ansible-version: [stable-2.17, stable-2.15, stable-2.16]
exclude:
# Ansible-core 2.16 is supported only from Python 3.10 onwards
- python-version: "3.9"
ansible-version: stable-2.16

steps:
- name: Perform sanity testing
uses: ansible-community/ansible-test-gh-action@release/v1
Expand All @@ -104,13 +99,14 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]
ansible-version: [stable-2.17, stable-2.15, stable-2.16]
exclude:
# Ansible-core 2.16 is supported only from Python 3.10 onwards
glimchb marked this conversation as resolved.
Show resolved Hide resolved
- python-version: "3.9"
ansible-version: stable-2.16

python-version: ["3.9", "3.10", "3.11"]
glimchb marked this conversation as resolved.
Show resolved Hide resolved
ansible-version: [stable-2.15, stable-2.16, stable-2.17]
exclude:
# Ansible-core 2.16 and 2.17 are supported only from Python 3.10 onwards
- python-version: "3.9"
ansible-version: stable-2.16
- python-version: "3.9"
glimchb marked this conversation as resolved.
Show resolved Hide resolved
ansible-version: stable-2.17
steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- name: Checkout the source code
Expand Down
55 changes: 28 additions & 27 deletions roles/bmc_fw_update/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
ansible.builtin.fail:
msg: "{{ bmc_fw_update_mutual_exclusive_msg }}"
when:
- ((dpu_bmc_username is defined or dpu_bmc_password is defined) and dpu_bmc_token is defined)
- (dpu_bmc_username is defined or dpu_bmc_password is defined) and (dpu_bmc_token is defined)

- name: Get Firmware Inventory
ansible.builtin.include_role:
Expand All @@ -23,11 +23,11 @@

- name: Store current fw version
ansible.builtin.set_fact:
bmc_fw_update_cur_fw_version: "{{ vars.get_bmc_facts_all_fw_versions[bmc_fw_update_inventory_name] }}"
bmc_fw_update_cur_fw_version: "{{ get_bmc_facts_before.get_bmc_facts_all_fw_versions[bmc_fw_update_inventory_name] }}"
Copy link
Member

@glimchb glimchb Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't work in my setup for some reason, let's try to understand why?

TASK [get_bmc_facts : Print all Versions] ***************************************************************************************************************************************************
task path: /opt/roles/get_bmc_facts/tasks/main.yml:54
ok: [172.22.4.2] => {
    "msg": {
        "6d53cf4d_bmc_firmware": "bf-24.01-5-0-gdd4a6159ce7.1704982350.6715245",
        "bluefield_fw_erot": "4-15",
        "dpu_atf": "",
        "dpu_board": "",
        "dpu_bsp": "",
        "dpu_nic": "",
        "dpu_node": "",
        "dpu_ofed": "",
        "dpu_os": "",
        "dpu_sys_image": "",
        "dpu_uefi": ""
    }
}

TASK [bmc_fw_update : Store current fw version] *********************************************************************************************************************************************
task path: /opt/roles/bmc_fw_update/tasks/main.yml:24
fatal: [172.22.4.2]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'get_bmc_facts_all_fw_versions'. 'dict object' has no attribute 'get_bmc_facts_all_fw_versions'\n\nThe error appears to be in '/opt/roles/bmc_fw_update/tasks/main.yml': line 24, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Store current fw version\n  ^ here\n"
}


- name: Print BMC Version
ansible.builtin.debug:
msg: "{{ get_bmc_facts_all_fw_versions }}"
msg: "{{ get_bmc_facts_before.get_bmc_facts_all_fw_versions }}"
Copy link
Member

@glimchb glimchb Jul 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't work in my setup for some reason, let's try to understand why?

TASK [bmc_fw_update : Store current fw version] *********************************************************************************************************************************************
task path: /opt/roles/bmc_fw_update/tasks/main.yml:24
ok: [172.22.4.2] => {
    "ansible_facts": {
        "bmc_fw_update_cur_fw_version": "bf-24.01-5-0-gdd4a6159ce7.1704982350.6715245"
    },
    "changed": false
}

TASK [bmc_fw_update : Print BMC Version] ****************************************************************************************************************************************************
task path: /opt/roles/bmc_fw_update/tasks/main.yml:28
fatal: [172.22.4.2]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'get_bmc_facts_all_fw_versions'. 'dict object' has no attribute 'get_bmc_facts_all_fw_versions'\n\nThe error appears to be in '/opt/roles/bmc_fw_update/tasks/main.yml': line 28, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Print BMC Version\n  ^ here\n"
}


- name: Check if firmware image exists locally {{ bmc_fw_update_image_file }}
ansible.builtin.stat:
Expand All @@ -43,61 +43,62 @@
delegate_to: "{{ bmc_fw_update_delegate }}"
when: not bmc_fw_update_local_file_check.stat.exists

# Consider replace with 'GetFirmwareUpdateCapabilities' when available
- name: Check multipart support
ansible.builtin.uri:
url: "https://{{ inventory_hostname }}/redfish/v1/UpdateService"
method: GET
return_content: true
status_code: 200
body_format: json
url_username: "{{ dpu_bmc_username }}"
url_password: "{{ dpu_bmc_password }}"
url_username: "{{ dpu_bmc_username | default(omit) }}"
url_password: "{{ dpu_bmc_password | default(omit) }}"
headers:
X-Auth-Token: "{{ dpu_bmc_token | default(omit) }}"
force_basic_auth: true
validate_certs: false
delegate_to: "{{ bmc_fw_update_delegate }}"
register: bmc_fw_update_multipart_check

# Deprecated method
- name: Update BMC firmware of DPU using deprecated HttpPushUri
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is not defined
ansible.builtin.uri:
url: "https://{{ inventory_hostname }}{{ bmc_fw_update_multipart_check.json.HttpPushUri }}"
method: POST
status_code: [200, 202]
src: "{{ bmc_fw_update_image_file }}"
headers:
Content-Type: application/octet-stream
url_username: "{{ dpu_bmc_username }}"
url_password: "{{ dpu_bmc_password }}"
X-Auth-Token: "{{ dpu_bmc_token | default(omit) }}"
url_username: "{{ dpu_bmc_username | default(omit) }}"
url_password: "{{ dpu_bmc_password | default(omit) }}"
force_basic_auth: true
validate_certs: false
delegate_to: "{{ bmc_fw_update_delegate }}"
register: bmc_fw_update_depecated_http_push
register: bmc_fw_update_deprecated_http_push
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is not defined

- name: Extract task id from update task
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is not defined
ansible.builtin.set_fact:
bmc_firmware_update_taskid: '{{ bmc_fw_update_depecated_http_push.location | urlsplit("path") }}'
bmc_firmware_update_taskid: '{{ bmc_fw_update_deprecated_http_push.location | urlsplit("path") }}'
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is not defined

- name: Update BMC firmware of DPU
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is defined
community.general.redfish_command:
category: Update
command: MultipartHTTPPushUpdate
baseuri: "{{ inventory_hostname }}"
username: "{{ dpu_bmc_username }}"
password: "{{ dpu_bmc_password }}"
# auth_token: "{{ dpu_bmc_token }}"
auth_token: "{{ dpu_bmc_token | default(omit) }}"
glimchb marked this conversation as resolved.
Show resolved Hide resolved
username: "{{ dpu_bmc_username | default(omit) }}"
password: "{{ dpu_bmc_password | default(omit) }}"
timeout: 600
update_image_file: "{{ bmc_fw_update_image_file }}"
register: result_update_task
delegate_to: "{{ bmc_fw_update_delegate }}"
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is defined

- name: Extract task id from update task
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is defined
ansible.builtin.set_fact:
bmc_firmware_update_taskid: "{{ result_update_task.return_values.update_status.handle }}"
when: bmc_fw_update_multipart_check.json.MultipartHttpPushUri is defined

- name: Print TASK id for tracking
ansible.builtin.debug:
Expand All @@ -108,20 +109,20 @@
seconds: 10

- name: Get the status of an update operation in a loop
when: bmc_fw_update_job_wait is true
community.general.redfish_info:
category: Update
command: GetUpdateStatus
baseuri: "{{ inventory_hostname }}"
username: "{{ dpu_bmc_username }}"
glimchb marked this conversation as resolved.
Show resolved Hide resolved
password: "{{ dpu_bmc_password }}"
# auth_token: "{{ dpu_bmc_token }}"
auth_token: "{{ dpu_bmc_token | default(omit) }}"
username: "{{ dpu_bmc_username | default(omit) }}"
password: "{{ dpu_bmc_password | default(omit) }}"
update_handle: "{{ bmc_firmware_update_taskid }}"
register: update_progress
until: update_progress.redfish_facts.update_status.status != 'Running'
retries: 60
delay: 30
delegate_to: "{{ bmc_fw_update_delegate }}"
when: bmc_fw_update_job_wait is true

- name: Validate task was completed
ansible.builtin.fail:
Expand All @@ -133,8 +134,7 @@
- name: Reboot BMC to apply new firmware of DPU
ansible.builtin.include_role:
name: bmc_reboot
when:
- bmc_fw_update_reboot is true
when: bmc_fw_update_reboot is true

- name: Get Firmware Inventory
ansible.builtin.include_role:
Expand All @@ -143,15 +143,16 @@

- name: Print BMC Version
ansible.builtin.debug:
msg: "{{ get_bmc_facts_all_fw_versions }}"
msg: "{{ get_bmc_facts_after.get_bmc_facts_all_fw_versions }}"

- name: Store fw version we installed
ansible.builtin.set_fact:
bmc_fw_update_got_fw_version: "{{ vars.get_bmc_facts_all_fw_versions[bmc_fw_update_inventory_name] }}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't work in my setup for some reason, let's try to understand why?

bmc_fw_update_got_fw_version: "{{ get_bmc_facts_after.get_bmc_facts_all_fw_versions[bmc_fw_update_inventory_name] }}"

- name: Validate fw image matches given filename
ansible.builtin.fail:
msg: "{{ bmc_fw_update_version_failure }}"
when:
- bmc_fw_update_reboot is true
- not bmc_fw_update_image_file is search(bmc_fw_update_got_fw_version | regex_search('[0-9-.]+'))
- not (bmc_fw_update_image_file is search(bmc_fw_update_got_fw_version | regex_search('[0-9-.]+')))