Simplify network workflows to use a single IOM IP address

Either IOM can reach the other via Redfish, so there's no need to collect
separate IOM1/IOM2 addresses. Firmware update and system check now prompt
for one IP per shelf with a note that either IOM's address works.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-04 10:57:44 -04:00
parent 46312e37fb
commit b745643a4b
2 changed files with 31 additions and 49 deletions

View File

@@ -158,26 +158,9 @@ def _check_via_network():
print()
password = prompt_password()
print()
ip = prompt_ip(" IOM IP address (either IOM1 or IOM2)")
print(" Which IOM(s) do you want to check?")
print(f" {_c(C.BOLD, '1')} IOM1 only")
print(f" {_c(C.BOLD, '2')} IOM2 only")
print(f" {_c(C.BOLD, '3')} Both IOM1 and IOM2")
print()
while True:
choice = prompt("Select [1/2/3]")
if choice in ("1", "2", "3"):
break
warn("Please enter 1, 2, or 3.")
iom_list = []
if choice in ("1", "3"):
ip1 = prompt_ip(" IOM1 IP address")
iom_list.append(("IOM1", ip1))
if choice in ("2", "3"):
ip2 = prompt_ip(" IOM2 IP address")
iom_list.append(("IOM2", ip2))
iom_list = [("IOM1", ip), ("IOM2", ip)]
rule("Querying IOM Status")
info("Querying network settings and firmware versions over the network...")

View File

@@ -82,30 +82,25 @@ def _prompt_fw_file(label: str) -> str:
# ── Multi-shelf IP collection ─────────────────────────────────────────────────
def _collect_shelves(iom_choice: str) -> list:
def _collect_shelves() -> list:
"""
Prompt for the password and IOM IP addresses one shelf at a time,
Prompt for the password and a single IOM IP address per shelf,
offering to add more shelves after each entry.
Each shelf has its own password because the Admin password is the BMC
serial number, which is unique to each physical shelf.
Either IOM's IP can be used — both IOMs share the same Redfish endpoint
and can reach each other's resources. Each shelf has its own password
because the Admin password is the BMC serial number, unique per shelf.
Returns a list of (password, [(iom, ip), ...]) tuples, one per shelf.
Returns a list of (password, ip) tuples, one per shelf.
"""
shelves = []
shelf_num = 1
while True:
info(f"Shelf {shelf_num} — enter password and IP address(es).")
info(f"Shelf {shelf_num} — enter password and IOM IP address.")
password = prompt_password()
shelf = []
if iom_choice in ("1", "3"):
ip = prompt_ip(f" Shelf {shelf_num} IOM1 IP address")
shelf.append(("IOM1", ip))
if iom_choice in ("2", "3"):
ip = prompt_ip(f" Shelf {shelf_num} IOM2 IP address")
shelf.append(("IOM2", ip))
shelves.append((password, shelf))
ip = prompt_ip(f" Shelf {shelf_num} IOM IP address (IOM1 or IOM2)")
shelves.append((password, ip))
print()
if not prompt_yn("Add another shelf?", default=False):
@@ -116,17 +111,24 @@ def _collect_shelves(iom_choice: str) -> list:
return shelves
def _make_targets(shelves: list) -> list:
def _make_targets(shelves: list, iom_choice: str) -> list:
"""
Convert the shelves structure into a flat list of (label, iom, ip, password)
tuples suitable for _show_fw_versions(). When there is only one shelf the
label is just the IOM name; for multiple shelves it includes the shelf number.
All IOMs in a shelf share the same IP connection.
"""
ioms = []
if iom_choice in ("1", "3"):
ioms.append("IOM1")
if iom_choice in ("2", "3"):
ioms.append("IOM2")
multi = len(shelves) > 1
return [
(f"S{i} / {iom}" if multi else iom, iom, ip, password)
for i, (password, shelf) in enumerate(shelves, 1)
for iom, ip in shelf
for i, (password, ip) in enumerate(shelves, 1)
for iom in ioms
]
@@ -235,8 +237,8 @@ def firmware_update_workflow():
print()
# ── Collect IPs for one or more shelves ───────────────────────────────────
shelves = _collect_shelves(iom_choice)
targets = _make_targets(shelves)
shelves = _collect_shelves()
targets = _make_targets(shelves, iom_choice)
rule("Current Firmware Versions")
_show_fw_versions(targets)
@@ -273,7 +275,7 @@ def firmware_update_workflow():
warn("For HA systems: update the passive IOM first.")
if len(shelves) > 1:
warn(f"Updating {len(shelves)} shelves sequentially — Shelf 1 first.")
elif any(len(shelf) > 1 for shelf in shelves):
elif iom_choice == "3":
warn("IOM1 will be updated first — adjust order if IOM2 is passive.")
print()
@@ -281,16 +283,13 @@ def firmware_update_workflow():
info("Firmware update cancelled.")
return
# ── Run updates shelf by shelf, IOM by IOM ────────────────────────────────
multi_shelf = len(shelves) > 1
for i, (password, shelf) in enumerate(shelves, 1):
for iom, ip in shelf:
heading = f"Shelf {i}{iom} ({ip})" if multi_shelf else f"{iom} ({ip})"
rule(heading)
if update_iom:
_update_iom_fw(password, ip, iom, iom_fw_path)
if update_fabric:
_update_fabric_fw(password, ip, iom, fabric_fw_path)
# ── Run updates per target (shelf × IOM) ─────────────────────────────────
for label, iom, ip, password in targets:
rule(f"{label} ({ip})")
if update_iom:
_update_iom_fw(password, ip, iom, iom_fw_path)
if update_fabric:
_update_fabric_fw(password, ip, iom, fabric_fw_path)
rule("Post-Update Firmware Validation")
_show_fw_versions(targets)