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