Skip to content

Commit

Permalink
Updated collection handling for systems, managers, and chassis to dif…
Browse files Browse the repository at this point in the history
…ferentiate between HTTP 404 from other non-successful responses

Signed-off-by: Mike Raineri <[email protected]>
  • Loading branch information
mraineri committed Jun 8, 2023
1 parent 3252bfe commit 5c4921b
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 49 deletions.
55 changes: 55 additions & 0 deletions redfish_utilities/collections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#! /usr/bin/python
# Copyright Notice:
# Copyright 2019-2023 DMTF. All rights reserved.
# License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/Redfish-Tacklebox/blob/main/LICENSE.md

"""
Collections Module
File : collections.py
Brief : This file contains the definitions and functionalities for performing
operations with resource collections
"""

from .messages import verify_response

class RedfishCollectionNotFoundError( Exception ):
"""
Raised when the specified collection is not found (HTTP Status = 404)
"""
pass

class RedfishCollectionMemberNotFoundError( Exception ):
"""
Raised when the specified member is not found (HTTP Status = 404)
"""
pass

def get_collection_ids( context, collection_uri ):
"""
Iterates over a collection and returns the identifiers of all members
Args:
context: The Redfish client object with an open session
collection_uri: The URI of the collection to process
Returns:
A list of identifiers of the members of the collection
"""

# Get the collection and iterate through its collection
avail_members = []
collection = context.get( collection_uri )
if collection.status == 404:
raise RedfishCollectionNotFoundError( "Service does not contain a collection at URI {}".format( collection_uri ) )
verify_response( collection )
while True:
for member in collection.dict["Members"]:
avail_members.append( member["@odata.id"].strip( "/" ).split( "/" )[-1] )
if "[email protected]" not in collection.dict:
break
collection = context.get( collection.dict["[email protected]"] )
verify_response( collection )

return avail_members
13 changes: 3 additions & 10 deletions redfish_utilities/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import warnings
import xlsxwriter
from .collections import get_collection_ids
from .messages import verify_response
from . import config

Expand Down Expand Up @@ -406,16 +407,8 @@ def get_chassis_ids( context ):
# Get the service root to find the chassis collection
service_root = context.get( "/redfish/v1/" )
if "Chassis" not in service_root.dict:
# No system collection
# No chassis collection
raise RedfishChassisNotFoundError( "Service does not contain a chassis collection" )

# Get the chassis collection and iterate through its collection
avail_chassis = []
chassis_col = context.get( service_root.dict["Chassis"]["@odata.id"] )
while True:
for chassis_member in chassis_col.dict["Members"]:
avail_chassis.append( chassis_member["@odata.id"].strip( "/" ).split( "/" )[-1] )
if "[email protected]" not in chassis_col.dict:
break
chassis_col = context.get( chassis_col.dict["[email protected]"] )
return avail_chassis
return get_collection_ids( context, service_root.dict["Chassis"]["@odata.id"] )
35 changes: 9 additions & 26 deletions redfish_utilities/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
with the managers collection for a given Redfish service
"""

from .collections import get_collection_ids
from .messages import verify_response
from .resets import reset_types

Expand Down Expand Up @@ -51,15 +52,7 @@ def get_manager_ids( context ):
raise RedfishManagerNotFoundError( "Service does not contain a manager collection" )

# Get the manager collection and iterate through its collection
avail_managers = []
manager_col = context.get( service_root.dict["Managers"]["@odata.id"] )
while True:
for manager_member in manager_col.dict["Members"]:
avail_managers.append( manager_member["@odata.id"].strip( "/" ).split( "/" )[-1] )
if "[email protected]" not in manager_col.dict:
break
manager_col = context.get( manager_col.dict["[email protected]"] )
return avail_managers
return get_collection_ids( context, service_root.dict["Managers"]["@odata.id"] )

def get_manager( context, manager_id = None ):
"""
Expand Down Expand Up @@ -88,12 +81,11 @@ def get_manager( context, manager_id = None ):
raise RedfishManagerNotFoundError( "Service does not contain exactly one manager; a target manager needs to be specified: {}".format( ", ".join( avail_managers ) ) )

# Check the response and return the manager if the response is good
try:
verify_response( manager )
except:
if manager.status == 404:
if avail_managers is None:
avail_managers = get_manager_ids( context )
raise RedfishManagerNotFoundError( "Service does not contain a manager called {}; valid managers: {}".format( manager_id, ", ".join( avail_managers ) ) ) from None
raise RedfishManagerNotFoundError( "Service does not contain a manager called {}; valid managers: {}".format( manager_id, ", ".join( avail_managers ) ) )
verify_response( manager )
return manager

def print_manager( manager ):
Expand Down Expand Up @@ -230,15 +222,7 @@ def get_manager_ethernet_interface_ids( context, manager_id = None ):
raise RedfishManagerEthIntNotFoundError( "Manager {} does not contain an Ethernet interface collection".format( manager.dict["Id"] ) )

# Get the Ethernet interface collection and iterate through its collection
avail_interfaces = []
interface_col = context.get( manager.dict["EthernetInterfaces"]["@odata.id"] )
while True:
for interface_member in interface_col.dict["Members"]:
avail_interfaces.append( interface_member["@odata.id"].strip( "/" ).split( "/" )[-1] )
if "[email protected]" not in interface_col.dict:
break
interface_col = context.get( interface_col.dict["[email protected]"] )
return avail_interfaces
return get_collection_ids( context, manager.dict["EthernetInterfaces"]["@odata.id"] )

def get_manager_ethernet_interface( context, manager_id = None, interface_id = None ):
"""
Expand Down Expand Up @@ -273,12 +257,11 @@ def get_manager_ethernet_interface( context, manager_id = None, interface_id = N
raise RedfishManagerEthIntNotFoundError( "Manager {} does not contain exactly one Ethernet interface; a target Ethernet interface needs to be specified: {}".format( manager_id, ", ".join( avail_interfaces ) ) )

# Check the response and return the Ethernet interface if the response is good
try:
verify_response( interface )
except:
if interface.status == 404:
if avail_interfaces is None:
avail_interfaces = get_manager_ethernet_interface_ids( context, manager_id )
raise RedfishManagerEthIntNotFoundError( "Manager {} does not contain an Ethernet interface called {}; valid Ethernet interfaces: {}".format( manager_id, interface_id, ", ".join( avail_interfaces ) ) ) from None
raise RedfishManagerEthIntNotFoundError( "Manager {} does not contain an Ethernet interface called {}; valid Ethernet interfaces: {}".format( manager_id, interface_id, ", ".join( avail_interfaces ) ) )
verify_response( interface )
return interface

def set_manager_ethernet_interface( context, manager_id = None, interface_id = None, vlan = None, ipv4_addresses = None, dhcpv4 = None, ipv6_addresses = None, ipv6_gateways = None, dhcpv6 = None ):
Expand Down
18 changes: 5 additions & 13 deletions redfish_utilities/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import warnings
import sys
from .collections import get_collection_ids
from .messages import verify_response
from .resets import reset_types
from . import config
Expand Down Expand Up @@ -77,15 +78,7 @@ def get_system_ids( context ):
raise RedfishSystemNotFoundError( "Service does not contain a system collection" )

# Get the system collection and iterate through its collection
avail_systems = []
system_col = context.get( service_root.dict["Systems"]["@odata.id"] )
while True:
for system_member in system_col.dict["Members"]:
avail_systems.append( system_member["@odata.id"].strip( "/" ).split( "/" )[-1] )
if "[email protected]" not in system_col.dict:
break
system_col = context.get( system_col.dict["[email protected]"] )
return avail_systems
return get_collection_ids( context, service_root.dict["Systems"]["@odata.id"] )

def get_system( context, system_id = None ):
"""
Expand Down Expand Up @@ -114,12 +107,11 @@ def get_system( context, system_id = None ):
raise RedfishSystemNotFoundError( "Service does not contain exactly one system; a target system needs to be specified: {}".format( ", ".join( avail_systems ) ) )

# Check the response and return the system if the response is good
try:
verify_response( system )
except:
if system.status == 404:
if avail_systems is None:
avail_systems = get_system_ids( context )
raise RedfishSystemNotFoundError( "Service does not contain a system called {}; valid systems: {}".format( system_id, ", ".join( avail_systems ) ) ) from None
raise RedfishSystemNotFoundError( "Service does not contain a system called {}; valid systems: {}".format( system_id, ", ".join( avail_systems ) ) )
verify_response( system )
return system

def get_system_boot( context, system_id = None ):
Expand Down

0 comments on commit 5c4921b

Please sign in to comment.