blob: 2257fc0574aee343427f69b18277654932d79967 [file] [log] [blame]
Michael Walsh35139f92019-03-01 15:58:05 -06001#!/usr/bin/env python
2
3r"""
4See redfish_plus class prolog below for details.
5"""
6
7from redfish.rest.v1 import HttpClient
8import gen_print as gp
Michael Walsh2477e092019-05-17 15:48:56 -05009import func_args as fa
Michael Walsh35139f92019-03-01 15:58:05 -060010
11
12def valid_http_status_code(status, valid_status_codes):
13 r"""
14 Raise exception if status is not found in the valid_status_codes list.
15
16 Description of argument(s):
17 status An HTTP status code (e.g. 200, 400, etc.).
Michael Walsh410b1782019-10-22 15:56:18 -050018 valid_status_codes A list of status codes that the caller considers acceptable. If this is
19 a null list, then any status code is considered acceptable. Note that
20 for the convenience of the caller, valid_status_codes may be either a
21 python list or a string which can be evaluated to become a python list
22 (e.g. "[200]").
Michael Walsh35139f92019-03-01 15:58:05 -060023 """
24
25 if type(valid_status_codes) is not list:
26 valid_status_codes = eval(valid_status_codes)
27 if len(valid_status_codes) == 0:
28 return
29 if status in valid_status_codes:
30 return
31
32 message = "The HTTP status code was not valid:\n"
33 message += gp.sprint_vars(status, valid_status_codes)
34 raise ValueError(message)
35
36
37class redfish_plus(HttpClient):
38 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050039 redfish_plus is a wrapper for redfish rest that provides the following benefits vs. using redfish
40 directly:
Michael Walsh35139f92019-03-01 15:58:05 -060041
42 For rest_request functions (e.g. get, put, post, etc.):
43 - Function-call logging to stdout.
Michael Walsh410b1782019-10-22 15:56:18 -050044 - Automatic valid_status_codes processing (i.e. an exception will be raised if the rest response
45 status code is not as expected.
Michael Walsh35139f92019-03-01 15:58:05 -060046 - Easily used from robot programs.
47 """
48
49 ROBOT_LIBRARY_SCOPE = 'TEST SUITE'
50
51 def rest_request(self, func, *args, **kwargs):
52 r"""
53 Perform redfish rest request and return response.
54
55 This function provides the following additional functionality.
Michael Walsh410b1782019-10-22 15:56:18 -050056 - The calling function's call line is logged to standard out (provided that global variable "quiet"
57 is not set).
Michael Walsh35139f92019-03-01 15:58:05 -060058 - The caller may include a valid_status_codes argument.
Michael Walsh410b1782019-10-22 15:56:18 -050059 - Callers may include inline python code strings to define arguments. This predominantly benefits
60 robot callers.
Michael Walsh2477e092019-05-17 15:48:56 -050061
62 For example, instead of calling like this:
63 ${data}= Create Dictionary HostName=${hostname}
64 Redfish.patch ${REDFISH_NW_PROTOCOL_URI} body=&{data}
65
66 Callers may do this:
67
68 Redfish.patch ${REDFISH_NW_PROTOCOL_URI}
69 ... body=[('HostName', '${hostname}')]
Michael Walsh35139f92019-03-01 15:58:05 -060070
71 Description of argument(s):
Michael Walsh410b1782019-10-22 15:56:18 -050072 func A reference to the parent class function which is to be called (e.g. get,
73 put, etc.).
74 args This is passed directly to the function referenced by the func argument
75 (see the documentation for the corresponding redfish HttpClient method
76 for details).
77 kwargs This is passed directly to the function referenced by the func argument
78 (see the documentation for the corresponding redfish HttpClient method
79 for details) with the following exception: If kwargs contains a
80 valid_status_codes key, it will be removed from kwargs and processed by
81 this function. This allows the caller to indicate what rest status codes
82 are acceptable. The default value is [200]. See the
83 valid_http_status_code function above for details.
Michael Walsh35139f92019-03-01 15:58:05 -060084
85 Example uses:
86
87 From a python program:
88
Michael Walsh410b1782019-10-22 15:56:18 -050089 response = bmc_redfish.get("/redfish/v1/Managers/bmc/EthernetInterfaces", [200, 201])
Michael Walsh35139f92019-03-01 15:58:05 -060090
Michael Walsh410b1782019-10-22 15:56:18 -050091 If this call to the get method generates a response.status equal to anything other than 200 or 201,
92 an exception will be raised.
Michael Walsh35139f92019-03-01 15:58:05 -060093
94 From a robot program:
95
96 BMC_Redfish.logout
Michael Walsh410b1782019-10-22 15:56:18 -050097 ${response}= BMC_Redfish.Get /redfish/v1/Managers/bmc/EthernetInterfaces valid_status_codes=[401]
Michael Walsh35139f92019-03-01 15:58:05 -060098
Michael Walsh410b1782019-10-22 15:56:18 -050099 As part of a robot test, the programmer has logged out to verify that the get request will generate a
100 status code of 401 (i.e. "Unauthorized").
Michael Walsh35139f92019-03-01 15:58:05 -0600101 """
102 gp.qprint_executing(stack_frame_ix=3, style=gp.func_line_style_short)
Michael Walsh410b1782019-10-22 15:56:18 -0500103 # Convert python string object definitions to objects (mostly useful for robot callers).
Michael Walsh2477e092019-05-17 15:48:56 -0500104 args = fa.args_to_objects(args)
105 kwargs = fa.args_to_objects(kwargs)
Michael Walsh35139f92019-03-01 15:58:05 -0600106 valid_status_codes = kwargs.pop('valid_status_codes', [200])
107 response = func(*args, **kwargs)
108 valid_http_status_code(response.status, valid_status_codes)
109 return response
110
111 # Define rest function wrappers.
112 def get(self, *args, **kwargs):
113 return self.rest_request(super(redfish_plus, self).get, *args,
114 **kwargs)
115
116 def head(self, *args, **kwargs):
117 return self.rest_request(super(redfish_plus, self).head, *args,
118 **kwargs)
119
120 def post(self, *args, **kwargs):
121 return self.rest_request(super(redfish_plus, self).post, *args,
122 **kwargs)
123
124 def put(self, *args, **kwargs):
125 return self.rest_request(super(redfish_plus, self).put, *args,
126 **kwargs)
127
128 def patch(self, *args, **kwargs):
129 return self.rest_request(super(redfish_plus, self).patch, *args,
130 **kwargs)
131
132 def delete(self, *args, **kwargs):
133 return self.rest_request(super(redfish_plus, self).delete, *args,
134 **kwargs)
135
136 def __del__(self):
137 del self