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