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