xref: /openbmc/openbmc-test-automation/lib/bmc_redfish_utils.py (revision 0ee7e3d2b81ba768f5522a77ec16b74c6739d0e0)
1#!/usr/bin/env python
2
3r"""
4BMC redfish utility functions.
5"""
6
7import json
8from robot.libraries.BuiltIn import BuiltIn
9
10
11class bmc_redfish_utils(object):
12
13    def __init__(self):
14        r"""
15        Initialize the bmc_redfish_utils object.
16        """
17        # Obtain a reference to the global redfish object.
18        self._redfish_ = BuiltIn().get_library_instance('redfish')
19
20    def get_redfish_session_info(self):
21        r"""
22        Returns redfish sessions info dictionary.
23
24        {
25            'key': 'yLXotJnrh5nDhXj5lLiH' ,
26            'location': '/redfish/v1/SessionService/Sessions/nblYY4wlz0'
27        }
28        """
29        session_dict = {
30            "key": self._redfish_._session_key_,
31            "location": self._redfish_._session_location_
32        }
33        return session_dict
34
35    def get_attribute(self, resource_path, attribute):
36        r"""
37        Get resource attribute.
38
39        Description of argument(s):
40        resource_path    URI resource absolute path (e.g. "/redfish/v1/Systems/1").
41        attribute        Name of the attribute (e.g. 'PowerState').
42        """
43
44        resp = self._redfish_.get(resource_path)
45        if attribute in resp.dict:
46            return resp.dict[attribute]
47
48        return None
49
50    def get_properties(self, resource_path):
51        r"""
52        Returns dictionary of attributes for the resource.
53
54        Description of argument(s):
55        resource_path    URI resource absolute path (e.g. "/redfish/v1/Systems/1").
56        """
57
58        resp = self._redfish_.get(resource_path)
59        return resp.dict
60
61    def list_request(self, resource_path):
62        r"""
63        Perform a GET list request and return available resource paths.
64
65        Description of argument(s):
66        resource_path  URI resource absolute path
67                       (e.g. "/redfish/v1/SessionService/Sessions").
68        """
69
70        global resource_list
71        resource_list = []
72
73        self._rest_response_ = self._redfish_.get(resource_path)
74
75        # Return empty list.
76        if self._rest_response_.status != 200:
77            return resource_list
78
79        self.walk_nested_dict(self._rest_response_.dict)
80
81        if not resource_list:
82            return uri_path
83
84        for resource in resource_list:
85            self._rest_response_ = self._redfish_.get(resource)
86            if self._rest_response_.status != 200:
87                continue
88            self.walk_nested_dict(self._rest_response_.dict)
89
90        resource_list.sort()
91        return resource_list
92
93    def enumerate_request(self, resource_path):
94        r"""
95        Perform a GET enumerate request and return available resource paths.
96
97        Description of argument(s):
98        resource_path  URI resource absolute path
99                       (e.g. "/redfish/v1/SessionService/Sessions").
100        """
101
102        url_list = self.list_request(resource_path)
103
104        resource_dict = {}
105
106        # Return empty dict.
107        if not url_list:
108            return resource_dict
109
110        for resource in url_list:
111            # JsonSchemas data are not required in enumeration.
112            # Example: '/redfish/v1/JsonSchemas/' and sub resources.
113            if 'JsonSchemas' in resource:
114                continue
115            self._rest_response_ = self._redfish_.get(resource)
116            if self._rest_response_.status != 200:
117                continue
118            resource_dict[resource] = self._rest_response_.dict
119
120        return json.dumps(resource_dict, sort_keys=True,
121                          indent=4, separators=(',', ': '))
122
123    def walk_nested_dict(self, data):
124        r"""
125        Parse through the nested dictionary and get the resource id paths.
126
127        Description of argument(s):
128        data    Nested dictionary data from response message.
129        """
130
131        for key, value in data.items():
132            if isinstance(value, dict):
133                self.walk_nested_dict(value)
134            else:
135                if 'Members' == key:
136                    if isinstance(value, list):
137                        for index in value:
138                            if index['@odata.id'] not in resource_list:
139                                resource_list.append(index['@odata.id'])
140                if '@odata.id' == key:
141                    if value not in resource_list and not value.endswith('/'):
142                        resource_list.append(value)
143