xref: /openbmc/openbmc-test-automation/lib/bmc_redfish_utils.robot (revision d95d917db7d7422c69a3c991a5bbda9d1a9cff2c)
1*** Settings ***
2Documentation   BMC and host redfish utility keywords.
3
4Resource        resource.robot
5Resource        bmc_redfish_resource.robot
6
7
8*** Keywords ***
9
10Redfish Power Operation
11    [Documentation]  Do Redfish host power operation.
12    [Arguments]      ${reset_type}
13
14    # Description of arguments:
15    # reset_type     Type of power operation.
16    #                (e.g. On/ForceOff/GracefulRestart/GracefulShutdown)
17
18    # Example:
19    # "Actions": {
20    # "#ComputerSystem.Reset": {
21    #        "@Redfish.ActionInfo": "/redfish/v1/Systems/${SYSTEM_ID}/ResetActionInfo",
22    #        "target": "/redfish/v1/Systems/${SYSTEM_ID}/Actions/ComputerSystem.Reset"
23    #    }
24
25    # Parameters allowable values  /redfish/v1/Systems/${SYSTEM_ID}/ResetActionInfo
26
27    # "@odata.id": "/redfish/v1/Systems/${SYSTEM_ID}/ResetActionInfo",
28    # "@odata.type": "#ActionInfo.v1_1_2.ActionInfo",
29    # "Id": "ResetActionInfo",
30    # "Name": "Reset Action Info",
31    # "Parameters": [
32    #    {
33    #        "AllowableValues": [
34    #            "ForceOff",
35    #            "PowerCycle",
36    #            "Nmi",
37    #            "GracefulShutdown",
38    #            "On",
39    #            "ForceOn",
40    #            "GracefulRestart",
41    #            "ForceRestart"
42    #        ],
43    #        "DataType": "String",
44    #        "Name": "ResetType",
45    #        "Required": true
46    #    }
47    # ]
48
49    ${target}=  Wait Until Keyword Succeeds  1 min  20 sec
50    ...  redfish_utils.Get Target Actions  /redfish/v1/Systems/${SYSTEM_ID}/  ComputerSystem.Reset
51    ${payload}=  Create Dictionary  ResetType=${reset_type}
52    ${resp}=  Redfish.Post  ${target}  body=&{payload}
53    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
54
55
56Redfish BMC Reset Operation
57    [Documentation]  Do Redfish BMC reset operation.
58    [Arguments]  ${reset_type}=GracefulRestart
59
60    # Example:
61    # "Actions": {
62    #    "#Manager.Reset": {
63    #        "@Redfish.ActionInfo": "/redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo",
64    #        "target": "/redfish/v1/Managers/${MANAGER_ID}/Actions/Manager.Reset"
65    #    },
66    #    "#Manager.ResetToDefaults": {
67    #        "ResetType@Redfish.AllowableValues": [
68    #            "ResetAll"
69    #        ],
70    #        "target": "/redfish/v1/Managers/${MANAGER_ID}/Actions/Manager.ResetToDefaults"
71    #    }
72    # },
73
74    # Parameters allowable values  /redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo
75
76    # "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo",
77    # "@odata.type": "#ActionInfo.v1_1_2.ActionInfo",
78    # "Id": "ResetActionInfo",
79    # "Name": "Reset Action Info",
80    # "Parameters": [
81    #    {
82    #        "AllowableValues": [
83    #            "GracefulRestart",
84    #            "ForceRestart"
85    #        ],
86    #        "DataType": "String",
87    #        "Name": "ResetType",
88    #        "Required": true
89    #    }
90    # ]
91
92    ${target}=  Wait Until Keyword Succeeds  1 min  20 sec
93    ...  redfish_utils.Get Target Actions  /redfish/v1/Managers/${MANAGER_ID}/  Manager.Reset
94    ${payload}=  Create Dictionary  ResetType=${reset_type}
95    Redfish.Post  ${target}  body=&{payload}  valid_status_codes=[${HTTP_OK}, ${HTTP_CREATED}]
96
97Redfish Bmc Reset To Defaults Operation
98    [Documentation]    Do Redfish BMC reset to defaults operation.
99    [Arguments]    ${reset_type}=ResetAll
100
101    # Description of arguments:
102    # reset_type     Type of reset operation.
103
104    # Example:
105    # "Actions": {
106    #    "#Manager.Reset": {
107    #        "@Redfish.ActionInfo": "/redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo",
108    #        "target": "/redfish/v1/Managers/${MANAGER_ID}/Actions/Manager.Reset"
109    #    },
110    #    "#Manager.ResetToDefaults": {
111    #        "ResetType@Redfish.AllowableValues": [
112    #            "ResetAll"
113    #        ],
114    #        "target": "/redfish/v1/Managers/${MANAGER_ID}/Actions/Manager.ResetToDefaults"
115    #    }
116    # },
117
118    # Parameters allowable values  /redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo
119
120    # "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/ResetActionInfo",
121    # "@odata.type": "#ActionInfo.v1_1_2.ActionInfo",
122    # "Id": "ResetActionInfo",
123    # "Name": "Reset Action Info",
124    # "Parameters": [
125    #    {
126    #        "AllowableValues": [
127    #            "GracefulRestart",
128    #            "ForceRestart"
129    #        ],
130    #        "DataType": "String",
131    #        "Name": "ResetType",
132    #        "Required": true
133    #    }
134    # ]
135    ${target}=    Wait Until Keyword Succeeds    1 min    20 sec
136    ...    redfish_utils.Get Target Actions    /redfish/v1/Managers/${REDFISH.MANAGER_ID}/    Manager.ResetToDefaults
137    ${payload}=    Create Dictionary    ResetToDefaultsType=${reset_type}
138    Redfish.Post    ${target}    body=&{payload}
139    ...    valid_status_codes=[${HTTP_OK}]
140
141Reset BIOS Via Redfish
142    [Documentation]  Do BIOS reset through Redfish.
143
144    ${target}=  redfish_utils.Get Target Actions  /redfish/v1/Systems/${SYSTEM_ID}/Bios/  Bios.ResetBios
145    Redfish.Post  ${target}  valid_status_codes=[${HTTP_OK}]
146
147
148Set Redfish Delete Session Flag
149    [Documentation]  Disable or enable delete redfish while performing the power operation keyword.
150    [Arguments]  ${set_flag}
151
152    # Description of argument(s):
153    # set_flag    Set user specified enable(1) or disable(0).
154
155    Set Suite Variable  ${REDFISH_DELETE_SESSIONS}  ${set_flag}
156
157
158Redfish Delete Session
159    [Documentation]  Redfish delete session.
160    [Arguments]  ${session_info}
161
162    # Description of argument(s):
163    # session_info      Session information are stored in dictionary.
164
165    # ${session_info} = {
166    #     'SessionIDs': 'XXXXXXXXX',
167    #     'ClientID': 'XXXXXX',
168    #     'SessionToken': 'XXXXXXXXX',
169    #     'SessionResp': session response from redfish login
170    # }
171
172    # SessionIDs   : Session IDs
173    # ClientID     : Client ID
174    # SessionToken : Session token
175    # SessionResp  : Response of creating an redfish login session
176
177    Redfish.Delete  /redfish/v1/SessionService/Sessions/${session_info["SessionIDs"]}
178    ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
179
180
181Redfish Delete List Of Session
182    [Documentation]  Redfish delete session from list of session records, individual session information
183    ...              are stored in dictionary.
184    [Arguments]  ${session_info_list}
185
186    # Description of argument(s):
187    # session_info_list    List contains individual session record are stored in dictionary.
188
189    # ${session_info_list} = [{
190    #     'SessionIDs': 'XXXXXXXXX',
191    #     'ClientID': 'XXXXXX',
192    #     'SessionToken': 'XXXXXXXXX',
193    #     'SessionResp': session response from redfish login
194    # }]
195
196    # SessionIDs   : Session IDs
197    # ClientID     : Client ID
198    # SessionToken : Session token
199    # SessionResp  : Response of creating an redfish login session
200
201    FOR  ${session_record}  IN  @{session_info_list}
202      Redfish.Delete  /redfish/v1/SessionService/Sessions/${session_record["SessionIDs"]}
203      ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
204    END
205
206
207Delete All Redfish Sessions
208    [Documentation]  Delete all active redfish sessions.
209
210    ${saved_session_info}=  Redfish_Utils.Get Redfish Session Info
211
212    ${resp_list}=  Redfish_Utils.Get Member List
213    ...  /redfish/v1/SessionService/Sessions
214
215    # Remove the current login session from the list.
216    Remove Values From List  ${resp_list}  ${saved_session_info["location"]}
217
218    # Remove session with client_id populated from the list.
219    ${client_id_list}=  Get Session With Client Id  ${resp_list}
220    Log To Console  Client sessions skip list: ${client_id_list}
221    FOR  ${client_session}  IN  @{client_id_list}
222        Remove Values From List  ${resp_list}  ${client_session}
223    END
224
225    FOR  ${session}  IN  @{resp_list}
226        Run Keyword And Ignore Error  Redfish.Delete  ${session}
227        ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NO_CONTENT}]
228    END
229
230
231Get Session With Client Id
232    [Documentation]  Iterate through the active sessions and return sessions
233    ...              populated with Context.
234    [Arguments]  ${session_list}
235
236    # Description of argument(s):
237    # session_list   Active session list from SessionService.
238
239    # "@odata.type": "#Session.v1_5_0.Session",
240    # "ClientOriginIPAddress": "xx.xx.xx.xx",
241    # "Context": "MYID-01"
242
243    ${client_id_sessions}=  Create List
244    FOR  ${session}  IN  @{session_list}
245        ${resp}=  Redfish.Get  ${session}   valid_status_codes=[200,404]
246        # This prevents dictionary KeyError exception when the Context
247        # attribute is not populated in generic session response.
248        ${context_var}=  Get Variable Value  ${resp.dict["Context"]}  ${EMPTY}
249        # Handle backward compatibility for OEM.
250        ${oem_var}=  Get Variable Value  ${resp.dict["Oem"]["OpenBMC"]["ClientID"]}  ${EMPTY}
251        IF  '${context_var}' != '${EMPTY}'
252            Append To List  ${client_id_sessions}  ${session}
253        END
254        IF  '${oem_var}' != '${EMPTY}'
255            Append To List  ${client_id_sessions}  ${session}
256        END
257    END
258
259    RETURN  ${client_id_sessions}
260
261
262Get Valid FRUs
263    [Documentation]  Return a dictionary containing all of the valid FRU records for the given fru_type.
264    [Arguments]  ${fru_type}
265
266    # NOTE: A valid FRU record will have a "State" key of "Enabled" and a "Health" key of "OK".
267
268    # Description of argument(s):
269    # fru_type  The type of fru (e.g. "Processors", "Memory", etc.).
270
271    ${fru_records}=  Redfish_Utils.Enumerate Request
272    ...  /redfish/v1/Systems/${SYSTEM_ID}/${fru_type}  return_json=0
273    ${fru_records}=  Filter Struct  ${fru_records}  [('State', 'Enabled'), ('Health', 'OK')]
274
275    RETURN  ${fru_records}
276
277
278Get Num Valid FRUs
279    [Documentation]  Return the number of valid FRU records for the given fru_type.
280    [Arguments]  ${fru_type}
281
282    # Description of argument(s):
283    # fru_type  The type of fru (e.g. "Processors", "Memory", etc.).
284
285    ${fru_records}=  Get Valid FRUs  ${fru_type}
286    ${num_valid_frus}=  Get length  ${fru_records}
287
288    RETURN  ${num_valid_frus}
289
290
291Verify Valid Records
292    [Documentation]  Verify all records retrieved with the given arguments are valid.
293    [Arguments]  ${record_type}  ${redfish_uri}  ${reading_type}
294
295    # Description of Argument(s):
296    # record_type    The sensor record type (e.g. "PowerSupplies")
297    # redfish_uri    The power supply URI (e.g. /redfish/v1/Chassis/chassis/Power)
298    # reading_type   The power watt readings (e.g. "PowerInputWatts")
299
300    # A valid record will have "State" key "Enabled" and "Health" key "OK".
301    ${records}=  Redfish.Get Attribute  ${redfish_uri}  ${record_type}
302
303    Rprint Vars  records
304
305    # Example output:
306    # records:
307    #   [0]:
308    #     [@odata.id]:                 /redfish/v1/Chassis/chassis/Power#/PowerControl/0
309    #     [@odata.type]:               #Power.v1_0_0.PowerControl
310    #     [MemberId]:                  0
311    #     [Name]:                      Chassis Power Control
312    #     [PowerConsumedWatts]:        264.0
313    #     [PowerLimit]:
314    #       [LimitInWatts]:            None
315    #     [PowerMetrics]:
316    #       [AverageConsumedWatts]:    325
317    #       [IntervalInMin]:           3
318    #       [MaxConsumedWatts]:        538
319    #     [Status]:
320    #       [Health]:                  OK
321    #       [State]:                   Enabled
322
323    ${invalid_records}=  Filter Struct  ${records}
324    ...  [('Health', '^OK$'), ('State', '^Enabled$'), ('${reading_type}', '')]  regex=1  invert=1
325    Valid Length  invalid_records  max_length=0
326
327    RETURN  ${records}
328
329
330Redfish Create User
331    [Documentation]  Redfish create user.
332    [Arguments]   ${user_name}  ${password}  ${role_id}  ${enabled}  ${force}=${False}
333
334    # Description of argument(s):
335    # user_name           The user name to be created.
336    # password            The password to be assigned.
337    # role_id             The role ID of the user to be created.
338    #                     (e.g. "Administrator", "Operator", etc.).
339    # enabled             Indicates whether the username being created.
340    #                     should be enabled (${True}, ${False}).
341    # force               Delete user account and re-create if force is True.
342
343    ${curr_role}=  Run Keyword And Ignore Error  Get User Role  ${user_name}
344    # Ex: ${curr_role} = ('PASS', 'Administrator')
345
346    ${user_exists}=  Run Keyword And Return Status  Should Be Equal As Strings  ${curr_role}[0]  PASS
347
348    # Delete user account when force is True.
349    IF  ${force} == ${True}
350        Redfish.Delete  ${REDFISH_ACCOUNTS_URI}${user_name}
351        ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NOT_FOUND}]
352    END
353
354    # Create specified user when force is True or User does not exist.
355    ${payload}=  Create Dictionary
356    ...  UserName=${user_name}  Password=${password}  RoleId=${role_id}  Enabled=${enabled}
357
358    IF  ${force} == ${True} or ${user_exists} == ${False}
359        Redfish.Post  ${REDFISH_ACCOUNTS_URI}  body=&{payload}
360        ...  valid_status_codes=[${HTTP_CREATED}]
361    END
362
363Get User Role
364    [Documentation]  Get User Role.
365    [Arguments]  ${user_name}
366
367    # Description of argument(s):
368    # user_name    User name to get it's role.
369
370    ${role_config}=  Redfish_Utils.Get Attribute
371    ...  ${REDFISH_ACCOUNTS_URI}${user_name}  RoleId
372
373    RETURN  ${role_config}
374
375
376Create Users With Different Roles
377    [Documentation]  Create users with different roles.
378    [Arguments]  ${users}  ${force}=${False}
379
380    # Description of argument(s):
381    # users    Dictionary of roles and user credentials to be created.
382    #          Ex:  {'Administrator': '[admin_user, TestPwd123]', 'Operator': '[operator_user, TestPwd123]'}
383    # force    Delete given user account if already exists when force is True.
384
385    FOR  ${role}  IN  @{users}
386      Redfish Create User  ${users['${role}'][0]}  ${users['${role}']}[1]  ${role}  ${True}  ${force}
387    END
388
389
390Delete BMC Users Via Redfish
391    [Documentation]  Delete BMC users via redfish.
392    [Arguments]  ${users}
393
394    # Description of argument(s):
395    # users    Dictionary of roles and user credentials to be deleted.
396
397    FOR  ${role}  IN  @{users}
398        Redfish.Delete  /redfish/v1/AccountService/Accounts/${users['${role}'][0]}
399        ...  valid_status_codes=[${HTTP_OK}, ${HTTP_NOT_FOUND}]
400    END
401
402
403Expire And Update New Password Via Redfish
404    [Documentation]  Expire and change password and verify using password.
405    [Arguments]  ${username}  ${password}  ${new_password}
406
407    # Description of argument(s):
408    # username        The username to be used to login to the BMC.
409    # password        The password to be used to login to the BMC.
410    # new_password    The new password to be used to update password.
411
412    # Expire admin password using ssh.
413    Open Connection And Log In  ${OPENBMC_USERNAME}  ${OPENBMC_PASSWORD}
414    ${output}  ${stderr}  ${rc}=  BMC Execute Command  passwd --expire ${username}
415    Should Contain Any  ${output}  password expiry information changed
416    ...  password changed
417
418    # Verify user password expired using Redfish
419    Verify User Password Expired Using Redfish  ${username}  ${password}
420
421    # Change user password.
422    Redfish.Patch  /redfish/v1/AccountService/Accounts/${username}
423    ...  body={'Password': '${new_password}'}
424    Redfish.Logout
425
426
427Verify User Password Expired Using Redfish
428    [Documentation]  Checking whether user password expired or not using redfish.
429    [Arguments]  ${username}  ${password}  ${expected_result}=${True}
430
431    # Description of argument(s):
432    # username        The username to be used to login to the BMC.
433    # password        The password to be used to login to the BMC.
434
435    Redfish.Login  ${username}  ${password}
436    ${resp}=  Redfish.Get  /redfish/v1/AccountService/Accounts/${username}
437    Should Be Equal  ${resp.dict["PasswordChangeRequired"]}  ${expected_result}
438
439
440Is BMC LastResetTime Changed
441    [Documentation]  Return fail if BMC last reset time is not changed.
442    [Arguments]  ${reset_time}
443
444    # Description of argument(s):
445    # reset_time  Last BMC reset time.
446
447    ${last_reset_time}=  Get BMC Last Reset Time
448    Should Not Be Equal  ${last_reset_time}  ${reset_time}
449
450
451Redfish BMC Reboot
452    [Documentation]  Use Redfish API reboot BMC and wait for BMC ready.
453
454    #  Get BMC last reset time for compare
455    ${last_reset_time}=  Get BMC Last Reset Time
456
457    # Reboot BMC by Redfish API
458    Redfish BMC Reset Operation
459
460    # Wait for BMC real reboot and Redfish API ready
461    Wait Until Keyword Succeeds  3 min  10 sec
462    ...  Is BMC LastResetTime Changed  ${last_reset_time}
463
464
465Get BMC Last Reset Time
466    [Documentation]  Return BMC LastResetTime.
467
468    ${last_reset_time}=  Redfish.Get Attribute
469    ...  /redfish/v1/Managers/${MANAGER_ID}  LastResetTime
470
471    RETURN  ${last_reset_time}
472
473
474Get BMC Active Session Count
475    [Documentation]  Return active session count from BMC.
476
477    ${session_count}=  Redfish.Get Attribute
478    ...  /redfish/v1/SessionService/Sessions  Members@odata.count
479
480    Log To Console  Redfish active session count: ${session_count}
481    RETURN  ${session_count}
482