Associate password with each shelf for multi-shelf firmware updates
Each ES24N shelf has a unique Admin password (its BMC serial number), so a single shared password is incorrect for multi-shelf runs. The password prompt now appears once per shelf inside _collect_shelves(), stored as the first element of each (password, [(iom, ip), ...]) shelf tuple. _make_targets() threads the password into each (label, iom, ip, password) target entry, and _show_fw_versions() uses the per-target password instead of a global one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -214,17 +214,18 @@ def _get_fabric_fw_version(password: str, host: str, iom: str) -> str:
|
|||||||
return _c(C.RED, "Unreachable")
|
return _c(C.RED, "Unreachable")
|
||||||
|
|
||||||
|
|
||||||
def _show_fw_versions(password: str, targets: list):
|
def _show_fw_versions(targets: list):
|
||||||
"""
|
"""
|
||||||
Query and display firmware versions.
|
Query and display firmware versions.
|
||||||
targets: list of (label, iom, ip) tuples where
|
targets: list of (label, iom, ip, password) tuples where
|
||||||
label: display string (e.g. "IOM1", "S1 / IOM1")
|
label: display string (e.g. "IOM1", "S1 / IOM1")
|
||||||
iom: actual IOM name used in Redfish paths ("IOM1" or "IOM2")
|
iom: actual IOM name used in Redfish paths ("IOM1" or "IOM2")
|
||||||
ip: management IP address
|
ip: management IP address
|
||||||
|
password: Admin password for this shelf
|
||||||
"""
|
"""
|
||||||
info("Querying firmware versions...")
|
info("Querying firmware versions...")
|
||||||
rows = []
|
rows = []
|
||||||
for label, iom, ip in targets:
|
for label, iom, ip, password in targets:
|
||||||
iom_ver = _get_iom_fw_version(password, ip, iom)
|
iom_ver = _get_iom_fw_version(password, ip, iom)
|
||||||
fabric_ver = _get_fabric_fw_version(password, ip, iom)
|
fabric_ver = _get_fabric_fw_version(password, ip, iom)
|
||||||
rows.append([label, ip, iom_ver, fabric_ver])
|
rows.append([label, ip, iom_ver, fabric_ver])
|
||||||
|
|||||||
@@ -82,18 +82,20 @@ def _prompt_fw_file(label: str) -> str:
|
|||||||
# ── Multi-shelf IP collection ─────────────────────────────────────────────────
|
# ── Multi-shelf IP collection ─────────────────────────────────────────────────
|
||||||
def _collect_shelves(iom_choice: str) -> list:
|
def _collect_shelves(iom_choice: str) -> list:
|
||||||
"""
|
"""
|
||||||
Prompt for IOM IP addresses one shelf at a time, offering to add more
|
Prompt for the password and IOM IP addresses one shelf at a time,
|
||||||
shelves after each entry.
|
offering to add more shelves after each entry.
|
||||||
|
|
||||||
Returns a list of shelves; each shelf is a list of (iom, ip) tuples
|
Each shelf has its own password because the Admin password is the BMC
|
||||||
for the IOM(s) selected (e.g. [("IOM1", "10.0.0.1")] or
|
serial number, which is unique to each physical shelf.
|
||||||
[("IOM1", "10.0.0.1"), ("IOM2", "10.0.0.2")]).
|
|
||||||
|
Returns a list of (password, [(iom, ip), ...]) tuples, one per shelf.
|
||||||
"""
|
"""
|
||||||
shelves = []
|
shelves = []
|
||||||
shelf_num = 1
|
shelf_num = 1
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
info(f"Enter the management IP address(es) for Shelf {shelf_num}.")
|
info(f"Shelf {shelf_num} — enter password and IP address(es).")
|
||||||
|
password = prompt_password()
|
||||||
shelf = []
|
shelf = []
|
||||||
if iom_choice in ("1", "3"):
|
if iom_choice in ("1", "3"):
|
||||||
ip = prompt_ip(f" Shelf {shelf_num} IOM1 IP address")
|
ip = prompt_ip(f" Shelf {shelf_num} IOM1 IP address")
|
||||||
@@ -101,7 +103,7 @@ def _collect_shelves(iom_choice: str) -> list:
|
|||||||
if iom_choice in ("2", "3"):
|
if iom_choice in ("2", "3"):
|
||||||
ip = prompt_ip(f" Shelf {shelf_num} IOM2 IP address")
|
ip = prompt_ip(f" Shelf {shelf_num} IOM2 IP address")
|
||||||
shelf.append(("IOM2", ip))
|
shelf.append(("IOM2", ip))
|
||||||
shelves.append(shelf)
|
shelves.append((password, shelf))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
if not prompt_yn("Add another shelf?", default=False):
|
if not prompt_yn("Add another shelf?", default=False):
|
||||||
@@ -114,14 +116,14 @@ def _collect_shelves(iom_choice: str) -> list:
|
|||||||
|
|
||||||
def _make_targets(shelves: list) -> list:
|
def _make_targets(shelves: list) -> list:
|
||||||
"""
|
"""
|
||||||
Convert the shelves structure into a flat list of (label, iom, ip) tuples
|
Convert the shelves structure into a flat list of (label, iom, ip, password)
|
||||||
suitable for _show_fw_versions(). When there is only one shelf the label
|
tuples suitable for _show_fw_versions(). When there is only one shelf the
|
||||||
is just the IOM name; for multiple shelves it includes the shelf number.
|
label is just the IOM name; for multiple shelves it includes the shelf number.
|
||||||
"""
|
"""
|
||||||
multi = len(shelves) > 1
|
multi = len(shelves) > 1
|
||||||
return [
|
return [
|
||||||
(f"S{i} / {iom}" if multi else iom, iom, ip)
|
(f"S{i} / {iom}" if multi else iom, iom, ip, password)
|
||||||
for i, shelf in enumerate(shelves, 1)
|
for i, (password, shelf) in enumerate(shelves, 1)
|
||||||
for iom, ip in shelf
|
for iom, ip in shelf
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -217,9 +219,6 @@ def firmware_update_workflow():
|
|||||||
info("Ensure this system has network access to the IOM management interface.")
|
info("Ensure this system has network access to the IOM management interface.")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
password = prompt_password()
|
|
||||||
print()
|
|
||||||
|
|
||||||
print(" Which IOM(s) would you like to update?")
|
print(" Which IOM(s) would you like to update?")
|
||||||
print(f" {_c(C.BOLD, '1')} IOM1 only")
|
print(f" {_c(C.BOLD, '1')} IOM1 only")
|
||||||
print(f" {_c(C.BOLD, '2')} IOM2 only")
|
print(f" {_c(C.BOLD, '2')} IOM2 only")
|
||||||
@@ -238,7 +237,7 @@ def firmware_update_workflow():
|
|||||||
targets = _make_targets(shelves)
|
targets = _make_targets(shelves)
|
||||||
|
|
||||||
rule("Current Firmware Versions")
|
rule("Current Firmware Versions")
|
||||||
_show_fw_versions(password, targets)
|
_show_fw_versions(targets)
|
||||||
|
|
||||||
print(" What would you like to update?")
|
print(" What would you like to update?")
|
||||||
print(f" {_c(C.BOLD, '1')} IOM Firmware only")
|
print(f" {_c(C.BOLD, '1')} IOM Firmware only")
|
||||||
@@ -282,7 +281,7 @@ def firmware_update_workflow():
|
|||||||
|
|
||||||
# ── Run updates shelf by shelf, IOM by IOM ────────────────────────────────
|
# ── Run updates shelf by shelf, IOM by IOM ────────────────────────────────
|
||||||
multi_shelf = len(shelves) > 1
|
multi_shelf = len(shelves) > 1
|
||||||
for i, shelf in enumerate(shelves, 1):
|
for i, (password, shelf) in enumerate(shelves, 1):
|
||||||
for iom, ip in shelf:
|
for iom, ip in shelf:
|
||||||
heading = f"Shelf {i} — {iom} ({ip})" if multi_shelf else f"{iom} ({ip})"
|
heading = f"Shelf {i} — {iom} ({ip})" if multi_shelf else f"{iom} ({ip})"
|
||||||
rule(heading)
|
rule(heading)
|
||||||
@@ -292,7 +291,7 @@ def firmware_update_workflow():
|
|||||||
_update_fabric_fw(password, ip, iom, fabric_fw_path)
|
_update_fabric_fw(password, ip, iom, fabric_fw_path)
|
||||||
|
|
||||||
rule("Post-Update Firmware Validation")
|
rule("Post-Update Firmware Validation")
|
||||||
_show_fw_versions(password, targets)
|
_show_fw_versions(targets)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
draw_box([
|
draw_box([
|
||||||
|
|||||||
Reference in New Issue
Block a user