xref: /openbmc/openbmc-test-automation/lib/rest_client.robot (revision 1963a4bb5a7bcb58392f5640684de80acd636ab9)
1*** Settings ***
2Library           Collections
3Library           String
4Library           RequestsLibrary
5Library           OperatingSystem
6Resource          resource.robot
7Library           disable_warning_urllib.py
8Library           utils.py
9Library           gen_misc.py
10Library           var_funcs.py
11Resource          rest_response_code.robot
12
13*** Variables ***
14# Assign default value to QUIET for programs which may not define it.
15${QUIET}  ${0}
16
17${XAUTH_TOKEN}  ${EMPTY}
18
19*** Keywords ***
20OpenBMC Get Request
21    [Documentation]  Do REST GET request and return the result.
22    # Example result data:
23    # Response code:200, Content:{
24    #   "data": [
25    #     "/xyz/openbmc_project/state/host0",
26    #     "/xyz/openbmc_project/state/chassis0",
27    #     "/xyz/openbmc_project/state/bmc0"
28    #   ],
29    #   "message": "200 OK",
30    #   "status": "ok"
31    # }
32    [Arguments]    ${uri}    ${timeout}=30  ${quiet}=${QUIET}  &{kwargs}
33    # Description of argument(s):
34    # uri      The URI to establish connection with
35    #          (e.g. '/xyz/openbmc_project/software/').
36    # timeout  Timeout in seconds to establish connection with URI.
37    # quiet    If enabled, turns off logging to console.
38    # kwargs   Any additional arguments to be passed directly to the
39    #          Get Request call. For example, the caller might
40    #          set kwargs as follows:
41    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
42
43    Initialize OpenBMC  ${timeout}  quiet=${quiet}
44
45    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
46    ${headers}=  Create Dictionary  X-Auth-Token=${XAUTH_TOKEN}  Accept=application/json
47    Set To Dictionary  ${kwargs}  headers  ${headers}
48    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Get
49    ...  base_uri=${base_uri}  args=&{kwargs}
50    ${resp}=  GET On Session  openbmc  ${base_uri}  &{kwargs}  timeout=${timeout}  expected_status=any
51    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${resp}
52    Delete All Sessions
53    RETURN    ${resp}
54
55OpenBMC Post Request
56    [Documentation]  Do REST POST request and return the result.
57    # Example result data:
58    # <Response [200]>
59    [Arguments]    ${uri}    ${timeout}=10  ${quiet}=${QUIET}  &{kwargs}
60    # Description of argument(s):
61    # uri      The URI to establish connection with
62    #          (e.g. '/xyz/openbmc_project/software/').
63    # timeout  Timeout in seconds to establish connection with URI.
64    # quiet    If enabled, turns off logging to console.
65    # kwargs   Any additional arguments to be passed directly to the
66    #          Post Request call. For example, the caller might
67    #          set kwargs as follows:
68    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
69
70    Initialize OpenBMC    ${timeout}  quiet=${quiet}
71    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
72    ${headers}=  Create Dictionary   Content-Type=application/json
73    ...  X-Auth-Token=${XAUTH_TOKEN}
74    Set To Dictionary  ${kwargs}  headers  ${headers}
75    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Post
76    ...  base_uri=${base_uri}  args=&{kwargs}
77    ${ret}=  POST On Session  openbmc  ${base_uri}  &{kwargs}  timeout=${timeout}
78    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${ret}
79    Delete All Sessions
80    RETURN    ${ret}
81
82OpenBMC Put Request
83    [Documentation]  Do REST PUT request on the resource identified by the URI.
84    [Arguments]    ${uri}    ${timeout}=10    &{kwargs}
85    # Description of argument(s):
86    # uri      The URI to establish connection with
87    #          (e.g. '/xyz/openbmc_project/software/').
88    # timeout  Timeout in seconds to establish connection with URI.
89    # kwargs   Arguments passed to the REST call.
90    # kwargs   Any additional arguments to be passed directly to the
91    #          Put Request call. For example, the caller might
92    #          set kwargs as follows:
93    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
94
95    Initialize OpenBMC    ${timeout}
96    ${base_uri}=   Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
97    ${headers}=  Create Dictionary   Content-Type=application/json
98    ...  X-Auth-Token=${XAUTH_TOKEN}
99    Log Request  method=Put  base_uri=${base_uri}  args=&{kwargs}
100    ${resp}=  PUT On Session  openbmc  ${base_uri}  json=${kwargs["data"]}  headers=${headers}
101    Log Response    ${resp}
102    Delete All Sessions
103    RETURN    ${resp}
104
105OpenBMC Delete Request
106    [Documentation]  Do REST request to delete the resource identified by the
107    ...  URI.
108    [Arguments]    ${uri}    ${timeout}=10   ${quiet}=${QUIET}    &{kwargs}
109    # Description of argument(s):
110    # uri      The URI to establish connection with
111    #          (e.g. '/xyz/openbmc_project/software/').
112    # timeout  Timeout in seconds to establish connection with URI.
113    # quiet    If enabled, turns off logging to console.
114    # kwargs   Any additional arguments to be passed directly to the
115    #          Delete Request call. For example, the caller might
116    #          set kwargs as follows:
117    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
118
119    Initialize OpenBMC    ${timeout}
120    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
121    ${headers}=  Create Dictionary   Content-Type=application/json
122    ...  X-Auth-Token=${XAUTH_TOKEN}
123    Set To Dictionary   ${kwargs}  headers   ${headers}
124    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Delete
125    ...  base_uri=${base_uri}  args=&{kwargs}
126    ${ret}=  DELETE On Session  openbmc  ${base_uri}  &{kwargs}  timeout=${timeout}
127    Run Keyword If  '${quiet}' == '${0}'  Log Response    ${ret}
128    Delete All Sessions
129    RETURN    ${ret}
130
131Initialize OpenBMC
132    [Documentation]  Do a REST login connection within specified time.
133    [Arguments]  ${timeout}=20  ${quiet}=${1}
134    ...  ${rest_username}=${OPENBMC_USERNAME}
135    ...  ${rest_password}=${OPENBMC_PASSWORD}
136
137    # Description of argument(s):
138    # timeout        REST login attempt time out.
139    # quiet          Suppress console log if set.
140    # rest_username  The REST username.
141    # rest_password  The REST password.
142
143    ${bmcweb_status}=  Run Keyword And Return Status  BMC Web Login Request
144    ...  ${timeout}  ${rest_username}  ${rest_password}
145
146    Return From Keyword If  ${bmcweb_status} == ${True}
147
148    # This will retry at 20 second interval.
149    Wait Until Keyword Succeeds  40 sec  20 sec
150    ...  Post Login Request  ${timeout}  ${quiet}
151    ...  ${rest_username}  ${rest_password}
152
153
154BMC Web Login Request
155    [Documentation]  Do BMC web-based login.
156    [Arguments]  ${timeout}=20  ${rest_username}=${OPENBMC_USERNAME}
157    ...  ${rest_password}=${OPENBMC_PASSWORD}
158
159    # Description of argument(s):
160    # timeout        REST login attempt time out.
161    # rest_username  The REST username.
162    # rest_password  The REST password.
163
164    Create Session  openbmc  ${AUTH_URI}  timeout=${timeout}
165
166    ${headers}=  Create Dictionary  Content-Type=application/json
167    @{credentials}=  Create List  ${rest_username}  ${rest_password}
168    ${data}=  Create Dictionary  data=@{credentials}
169    ${resp}=  POST On Session  openbmc  /login  json=${data}  headers=${headers}
170    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
171
172    ${processed_token_data}=
173    ...  Evaluate  re.split(r'[;,]', '${resp.headers["Set-Cookie"]}')  modules=re
174    ${result}=  Key Value List To Dict  ${processed_token_data}  delim==
175
176    # Example result data:
177    # 'XSRF-TOKEN=hQuOyDJFEIbrN4aOg2CT; Secure,
178    # BMCWEB-SESSION=c4wloTiETumSxPI9nLeg; Secure; HttpOnly'
179
180    # To handle latest bmcweb token exceptions.
181    ${session_token}=
182    ...  Get Variable Value  ${result['bmcweb-session']}  ${result['session']}
183    Set Global Variable  ${XAUTH_TOKEN}  ${session_token}
184
185
186Post Login Request
187    [Documentation]  Do REST login request.
188    [Arguments]  ${timeout}=20  ${quiet}=${1}
189    ...  ${rest_username}=${OPENBMC_USERNAME}
190    ...  ${rest_password}=${OPENBMC_PASSWORD}
191
192    # Description of argument(s):
193    # timeout        REST login attempt time out.
194    # quiet          Suppress console log if set.
195    # rest_username  The REST username.
196    # rest_password  The REST password.
197
198    Create Session  openbmc  ${AUTH_URI}  timeout=${timeout}  max_retries=3
199
200    ${headers}=  Create Dictionary  Content-Type=application/json
201    @{credentials}=  Create List  ${rest_username}  ${rest_password}
202    ${data}=  Create Dictionary   data=@{credentials}
203    ${status}  ${resp}=  Run Keyword And Ignore Error  POST On Session  openbmc
204    ...  /login  json=${data}  headers=${headers}
205
206    Should Be Equal  ${status}  PASS  msg=${resp}
207    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
208
209
210Log Out OpenBMC
211    [Documentation]  Log out of the openbmc REST session.
212
213    ${headers}=  Create Dictionary  Content-Type=application/json
214    ...  X-Auth-Token=${XAUTH_TOKEN}
215    ${data}=  Create dictionary  data=@{EMPTY}
216
217    # If there is no active session it will throw the following exception
218    # "Non-existing index or alias 'openbmc'"
219    ${resp}=  POST On Session  openbmc
220    ...  /logout  json=${data}  headers=${headers}
221
222    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
223    ...  msg=${resp}
224
225
226Log Request
227    [Documentation]  Log the specific REST URI, method name on the console.
228    [Arguments]    &{kwargs}
229    ${msg}=  Catenate  SEPARATOR=  URI:  ${AUTH_URI}  ${kwargs["base_uri"]}
230    ...  , method:  ${kwargs["method"]}  , args:  ${kwargs["args"]}
231    Logging    ${msg}    console=True
232
233
234Log Response
235    [Documentation]  Log the response code on the console.
236    [Arguments]    ${resp}
237
238    ${msg}=  Catenate  SEPARATOR=  Response code:  ${resp.status_code}
239    ...  , Content:  ${resp.content}
240    Logging    ${msg}    console=True
241
242
243Logging
244    [Documentation]  Log the specified message on the console.
245    [Arguments]    ${msg}    ${console}=default False
246    Log  ${msg}  console=True
247
248
249Read Attribute
250    [Documentation]  Retrieve attribute value from URI and return result.
251    # Example result data for the attribute 'FieldModeEnabled' in
252    # "/xyz/openbmc_project/software/attr/" :
253    # 0
254    [Arguments]    ${uri}    ${attr}    ${timeout}=10  ${quiet}=${QUIET}
255    ...  ${expected_value}=${EMPTY}
256    # Description of argument(s):
257    # uri               URI of the object that the attribute lives on
258    #                   (e.g. '/xyz/openbmc_project/software/').
259    # attr              Name of the attribute (e.g. 'FieldModeEnabled').
260    # timeout           Timeout for the REST call.
261    # quiet             If enabled, turns off logging to console.
262    # expected_value    If this argument is not empty, the retrieved value
263    #                   must match this value.
264
265    # Make sure uri ends with slash.
266    ${uri}=  Add Trailing Slash  ${uri}
267
268    ${resp}=  OpenBMC Get Request  ${uri}attr/${attr}  timeout=${timeout}
269    ...  quiet=${quiet}
270    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
271    Run Keyword If  '${expected_value}' != '${EMPTY}'
272    ...  Should Be Equal As Strings  ${expected_value}  ${resp.json()["data"]}
273    RETURN    ${resp.json()["data"]}
274
275
276Write Attribute
277    [Documentation]  Write a D-Bus attribute with REST.
278    [Arguments]  ${uri}  ${attr}  ${timeout}=10  ${verify}=${FALSE}
279    ...  ${expected_value}=${EMPTY}  &{kwargs}
280
281    # Description of argument(s):
282    # uri               URI of the object that the attribute lives on
283    #                   (e.g. '/xyz/openbmc_project/software/').
284    # attr              Name of the attribute (e.g. 'FieldModeEnabled').
285    # timeout           Timeout for the REST call.
286    # verify            If set to ${TRUE}, the attribute will be read back to
287    #                   ensure that its value is set to ${verify_attr}.
288    # expected_value    Only used if verify is set to ${TRUE}. The value that
289    #                   ${attr} should be set to. This defaults to
290    #                   ${kwargs['data']. There are cases where the caller
291    #                   expects some other value in which case this value can
292    #                   be explicitly specified.
293    # kwargs            Arguments passed to the REST call. This should always
294    #                   contain the value to set the property to at the 'data'
295    #                   key (e.g. data={"data": 1}).
296
297    # Make sure uri ends with slash.
298    ${uri}=  Add Trailing Slash  ${uri}
299
300    ${base_uri}=  Catenate  SEPARATOR=  ${DBUS_PREFIX}  ${uri}
301    ${resp}=  Openbmc Put Request  ${base_uri}attr/${attr}
302    ...  timeout=${timeout}  &{kwargs}
303    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
304
305    # Verify the attribute was set correctly if the caller requested it.
306    Return From Keyword If  ${verify} == ${FALSE}
307
308    ${expected_value}=  Set Variable If  '${expected_value}' == '${EMPTY}'
309    ...  ${kwargs['data']['data']}  ${expected_value}
310    ${value}=  Read Attribute  ${uri}  ${attr}
311    Should Be Equal  ${value}  ${expected_value}
312
313Read Properties
314    [Documentation]  Read data part of the URI object and return result.
315    # Example result data:
316    # [u'/xyz/openbmc_project/software/cf7bf9d5',
317    #  u'/xyz/openbmc_project/software/5ecb8b2c',
318    #  u'/xyz/openbmc_project/software/active',
319    #  u'/xyz/openbmc_project/software/functional']
320    [Arguments]  ${uri}  ${timeout}=10  ${quiet}=${QUIET}
321    # Description of argument(s):
322    # uri               URI of the object
323    #                   (e.g. '/xyz/openbmc_project/software/').
324    # timeout           Timeout for the REST call.
325    # quiet             If enabled, turns off logging to console.
326
327    ${resp}=  OpenBMC Get Request  ${uri}  timeout=${timeout}  quiet=${quiet}
328    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_OK}
329
330    RETURN  ${resp.json()["data"]}
331
332Call Method
333    [Documentation]  Invoke the specific REST service method.
334    [Arguments]  ${uri}  ${method}  ${timeout}=10  ${quiet}=${QUIET}  &{kwargs}
335    # Description of arguments:
336    # uri      The URI to establish connection with
337    #          (e.g. '/xyz/openbmc_project/software/').
338    # timeout  Timeout in seconds to establish connection with URI.
339    # quiet    If enabled, turns off logging to console.
340    # kwargs   Arguments passed to the REST call.
341
342    ${base_uri}=    Catenate    SEPARATOR=    ${DBUS_PREFIX}    ${uri}
343    ${resp}=  OpenBmc Post Request  ${base_uri}action/${method}
344    ...  timeout=${timeout}  quiet=${quiet}  &{kwargs}
345    RETURN    ${resp}
346
347
348Upload Image To BMC
349    [Documentation]  Upload image to BMC via REST and return status code.
350    [Arguments]  ${uri}  ${timeout}=10  ${quiet}=${1}
351    ...  ${valid_status_codes}=[${HTTP_OK}, ${HTTP_ACCEPTED}]  &{kwargs}
352
353    # Description of argument(s):
354    # uri                           URI for uploading image via REST e.g.
355    #                               "/upload/image".
356    # timeout                       Time allocated for the REST command to
357    #                               return status (specified in Robot
358    #                               Framework Time Format e.g. "3 mins").
359    # quiet                         If enabled, turns off logging to console.
360    # valid_status_codes            A list of status codes that are valid for
361    #                               the REST post command. This can be
362    #                               specified as a string the evaluates to a
363    #                               python object (e.g. [${HTTP_OK}]).
364    # kwargs                        A dictionary keys/values to be passed
365    #                               directly to Post Request.
366
367
368    # If /redfish/v1/SessionService/Sessions POST fails, fallback to
369    # REST /login method.
370    ${passed}=  Run Keyword And Return Status   Redfish Login
371    Run Keyword If  ${passed} != True   Initialize OpenBMC  ${timeout}  quiet=${quiet}
372    ${session_object}=  Set Variable If  ${passed}  redfish  openbmc
373
374    ${base_uri}=  Catenate  SEPARATOR=  ${DBUS_PREFIX}  ${uri}
375    ${headers}=  Create Dictionary  Content-Type=application/octet-stream
376    ...  X-Auth-Token=${XAUTH_TOKEN}  Accept=application/json
377    Set To Dictionary  ${kwargs}  headers  ${headers}
378    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Post
379    ...  base_uri=${base_uri}  args=&{kwargs}
380    ${ret}=  POST On Session  ${session_object}  ${base_uri}  &{kwargs}  timeout=${timeout}
381    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${ret}
382    Valid Value  ret.status_code  ${valid_status_codes}
383    Delete All Sessions
384
385    RETURN  ${ret}
386
387
388Redfish Login
389    [Documentation]  Do BMC web-based login.
390    [Arguments]  ${timeout}=20  ${rest_username}=${OPENBMC_USERNAME}
391    ...  ${rest_password}=${OPENBMC_PASSWORD}  ${kwargs}=${EMPTY}
392
393    # Description of argument(s):
394    # timeout        REST login attempt time out.
395    # rest_username  The REST username.
396    # rest_password  The REST password.
397    # kwargs   Any additional arguments to be passed directly to the
398    #          Get Request call. For example, the caller might
399    #          set kwargs as follows:
400    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
401
402    Create Session  redfish  ${AUTH_URI}  timeout=${timeout}
403    ${headers}=  Create Dictionary  Content-Type=application/json
404    ${data}=  Set Variable If  '${kwargs}' == '${EMPTY}'
405    ...    {"UserName":"${rest_username}", "Password":"${rest_password}"}
406    ...    {"UserName":"${rest_username}", "Password":"${rest_password}", ${kwargs}}
407
408    ${resp}=  POST On Session  redfish  /redfish/v1/SessionService/Sessions
409    ...  data=${data}  headers=${headers}
410    Should Be Equal As Strings  ${resp.status_code}  ${HTTP_CREATED}
411
412    Set Global Variable  ${XAUTH_TOKEN}  ${resp.headers["X-Auth-Token"]}
413
414    RETURN  ${resp.json()}
415
416
417Redfish Get Request
418    [Documentation]  Do REST POST request and return the result.
419    [Arguments]  ${uri}  ${timeout}=10  ${quiet}=${QUIET}  &{kwargs}
420
421    # Description of argument(s):
422    # uri      The URI to establish connection with
423    #          (e.g. '/xyz/openbmc_project/software/').
424    # timeout  Timeout in seconds to establish connection with URI.
425    # quiet    If enabled, turns off logging to console.
426    # kwargs   Any additional arguments to be passed directly to the
427    #          Post Request call. For example, the caller might
428    #          set kwargs as follows:
429    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
430
431    ${base_uri}=  Catenate  SEPARATOR=  ${DBUS_PREFIX}  ${uri}
432    ${headers}=  Create Dictionary  Content-Type=application/json  X-Auth-Token=${XAUTH_TOKEN}
433    Set To Dictionary   ${kwargs}  headers  ${headers}
434    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Post  base_uri=${base_uri}  args=&{kwargs}
435    ${resp}=  GET On Session  redfish  ${base_uri}  &{kwargs}  timeout=${timeout}
436    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${resp}
437
438    RETURN  ${resp}
439
440
441Redfish Post Request
442    [Documentation]  Do REST POST request and return the result.
443    [Arguments]  ${uri}  ${timeout}=10  ${quiet}=${QUIET}  &{kwargs}
444
445    # Description of argument(s):
446    # uri      The URI to establish connection with
447    #          (e.g. '/xyz/openbmc_project/software/').
448    # timeout  Timeout in seconds to establish connection with URI.
449    # quiet    If enabled, turns off logging to console.
450    # kwargs   Any additional arguments to be passed directly to the
451    #          Post Request call. For example, the caller might
452    #          set kwargs as follows:
453    #          ${kwargs}=  Create Dictionary  allow_redirect=${True}.
454
455    ${base_uri}=  Catenate  SEPARATOR=  ${DBUS_PREFIX}  ${uri}
456    ${headers}=  Create Dictionary  Content-Type=application/json  X-Auth-Token=${XAUTH_TOKEN}
457    Set To Dictionary   ${kwargs}  headers  ${headers}
458    Run Keyword If  '${quiet}' == '${0}'  Log Request  method=Post  base_uri=${base_uri}  args=&{kwargs}
459    ${resp}=  POST On Session  redfish  ${base_uri}  &{kwargs}  timeout=${timeout}  expected_status=any
460    Run Keyword If  '${quiet}' == '${0}'  Log Response  ${resp}
461
462    RETURN  ${resp}
463