1Documentation  Utility for SNMP configurations via Redfish.
2
3*** Settings ***
4
5Resource                ../../lib/utils.robot
6Resource                ../../lib/connection_client.robot
7Library                 ../../lib/gen_misc.py
8Library                 ../../lib/utils.py
9
10*** Variables ***
11
12${snmp_function}     SNMPTrap
13${snmp_version}      SNMPv2c
14${subscription_uri}  /redfish/v1/EventService/Subscriptions
15
16${CMD_INTERNAL_FAILURE}  busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/logging
17...  xyz.openbmc_project.Logging.Create Create ssa{ss} xyz.openbmc_project.Common.Error.InternalFailure
18...  xyz.openbmc_project.Logging.Entry.Level.Error 0
19
20${CMD_FRU_CALLOUT}  busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/logging
21...  xyz.openbmc_project.Logging.Create Create ssa{ss} xyz.openbmc_project.Common.Error.Timeout
22...  xyz.openbmc_project.Logging.Entry.Level.Error 2 "TIMEOUT_IN_MSEC" "5"
23...  "CALLOUT_INVENTORY_PATH" "/xyz/openbmc_project/inventory/system/chassis/motherboard"
24
25${CMD_INFORMATIONAL_ERROR}  busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/logging
26...  xyz.openbmc_project.Logging.Create Create ssa{ss} xyz.openbmc_project.Common.Error.TestError2
27...  xyz.openbmc_project.Logging.Entry.Level.Informational 0
28
29${SNMP_TRAP_BMC_INTERNAL_FAILURE}  xyz.openbmc_project.Common.Error.InternalFailure
30${SNMP_TRAP_BMC_CALLOUT_ERROR}  xyz.openbmc_project.Common.Error.Timeout
31${SNMP_TRAP_BMC_INFORMATIONAL_ERROR}  xyz.openbmc_project.Common.Error.TestError2
32
33
34*** Keywords ***
35
36Get SNMP Manager List
37    [Documentation]  Get the list of SNMP managers and return IP addresses and ports.
38
39    # Get the list of SNMP manager URIs.
40    @{snmp_mgr_uris}=  Get SNMP Child URIs
41
42    ${snmp_mgr_list}=  Create List
43
44    FOR  ${snmp_mgr_uri}  IN  @{snmp_mgr_uris}
45      # Sample output:
46      # {
47      #  "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp1",
48      #  "@odata.type": "#EventDestination.v1_7_0.EventDestination",
49      #  "Context": "",
50      #  "Destination": "snmp://xx.xx.xx.xx:162",
51      #  "EventFormatType": "Event",
52      #  "Id": "snmp1",
53      #  "Name": "Event Destination snmp1",
54      #  "Protocol": "SNMPv2c",
55      #  "SubscriptionType": "SNMPTrap"
56
57      ${resp}=  Redfish.Get  ${snmp_mgr_uri}
58      ${snmp_mgr}=  Get From Dictionary  ${resp.dict}  Destination
59      Append To List  ${snmp_mgr_list}  ${snmp_mgr}
60    END
61
62    [Return]  ${snmp_mgr_list}
63
64
65Configure SNMP Manager Via Redfish
66    [Documentation]  Configure SNMP manager on BMC via Redfish.
67    [Arguments]  ${snmp_mgr_ip}  ${snmp_port}  ${valid_status_codes}=${HTTP_CREATED}
68
69    # Description of argument(s):
70    # snmp_mgr_ip  SNMP manager IP address
71    # snmp_port  SNMP manager port
72    # valid_status_code  expected code
73
74    ${snmp_mgr_data}=  Create Dictionary  Destination=snmp://${snmp_mgr_ip}:${snmp_port}
75    ...  SubscriptionType=${snmp_function}  Protocol=${snmp_version}
76
77    Redfish.Post  ${subscription_uri}  body=&{snmp_mgr_data}
78    ...  valid_status_codes=[${valid_status_codes}]
79
80
81Verify SNMP Manager Configured On BMC
82    [Documentation]  Verify SNMP manager configured on BMC.
83    [Arguments]  ${snmp_mgr_ip}  ${snmp_port}
84
85    # Description of argument(s):
86    # snmp_mgr_ip  SNMP manager IP address
87    # snmp_port  SNMP manager port
88
89    # Get the list of SNMP managers that are configured on BMC.
90    @{snmp_mgr_list}=  Get SNMP Manager List
91
92    ${snmp_ip_port}=  Catenate  ${snmp_mgr_ip}:${snmp_port}
93
94    List Should Contain Value  ${snmp_mgr_list}  snmp://${snmp_ip_port}
95    ...  msg=SNMP manager is not configured.
96
97
98Get SNMP Child URIs
99    [Documentation]  Get the list of all SNMP manager URIs.
100
101    # Sample output of SNMP URI:
102    # {
103    #  "@odata.id": "/redfish/v1/EventService/Subscriptions",
104    #  "@odata.type": "#EventDestinationCollection.EventDestinationCollection",
105    #  "Members": [
106    #    {
107    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp6"
108    #    },
109    #    {
110    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp2"
111    #    },
112    #    {
113    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp9"
114    #    },
115    #    {
116    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp1"
117    #    },
118    #    {
119    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp8"
120    #    },
121    #    {
122    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp4"
123    #    },
124    #    {
125    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp7"
126    #    },
127    #    {
128    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp5"
129    #    },
130    #    {
131    #      "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp3"
132    #    }
133    #  ],
134    #  "Members@odata.count": 9,
135    #  "Name": "Event Destination Collections"
136
137    # Get the list of child URIs.
138    @{snmp_mgr_uris}=  Redfish.Get Members List  ${subscription_uri}  filter=snmp
139
140    [Return]  ${snmp_mgr_uris}
141
142
143Delete SNMP Manager Via Redfish
144    [Documentation]  Delete SNMP manager.
145    [Arguments]  ${snmp_mgr_ip}  ${snmp_port}
146
147    # Description of argument(s):
148    # snmp_mgr_ip  SNMP manager IP.
149    # snmp_port    Network port where SNMP manager is listening.
150
151    ${is_snmp_found}=  Set Variable  ${False}
152    ${snmp_ip_port}=  Catenate  ${snmp_mgr_ip}:${snmp_port}
153
154    # Get the list of SNMP manager URIs.
155    @{snmp_mgr_uris}=  Get SNMP Child URIs
156
157    # Find the SNMP manager URI that has IP and port configured.
158    FOR  ${snmp_mgr_uri}  IN  @{snmp_mgr_uris}
159      # Sample output:
160      # {
161      #  "@odata.id": "/redfish/v1/EventService/Subscriptions/snmp1",
162      #  "@odata.type": "#EventDestination.v1_7_0.EventDestination",
163      #  "Context": "",
164      #  "Destination": "snmp://xx.xx.xx.xx:162",
165      #  "EventFormatType": "Event",
166      #  "Id": "snmp1",
167      #  "Name": "Event Destination snmp1",
168      #  "Protocol": "SNMPv2c",
169      #  "SubscriptionType": "SNMPTrap"
170
171      # Find the SNMP manager that has matching destination details.
172      ${snmp_mgr}=  Redfish.Get Attribute  ${snmp_mgr_uri}  Destination
173
174      # Delete the SNMP manager if the requested IP & ports are found
175      # and mark is_snmp_found to true.
176      Run Keyword If  'snmp://${snmp_ip_port}' == '${snmp_mgr}'
177      ...  Run Keywords  Set Local Variable  ${is_snmp_found}  ${True}
178      ...  AND  Redfish.Delete  ${snmp_mgr_uri}
179      ...  AND  Exit For Loop
180    END
181
182    Pass Execution If  ${is_snmp_found} == ${False}
183    ...  SNMP Manager: ${snmp_mgr_ip}:${snmp_port} is not configured on BMC
184
185    # Check if the SNMP manager is really deleted from BMC.
186    ${status}=  Run Keyword And Return Status
187    ...  Verify SNMP Manager Configured On BMC  ${snmp_mgr_ip}  ${snmp_port}
188
189    Should Be Equal  ${status}  ${False}  msg=SNMP manager is not deleted in the backend.
190
191
192Create Error On BMC And Verify Trap
193    [Documentation]  Generate error on BMC and verify if trap is sent.
194    [Arguments]  ${event_log}=${CMD_INTERNAL_FAILURE}  ${expected_error}=${SNMP_TRAP_BMC_INTERNAL_FAILURE}
195
196    # Description of argument(s):
197    # event_log       Event logs to be created.
198    # expected_error  Expected error on SNMP.
199
200    Configure SNMP Manager Via Redfish  ${SNMP_MGR1_IP}  ${SNMP_DEFAULT_PORT}  ${HTTP_CREATED}
201
202    Start SNMP Manager
203
204    # Generate error log.
205    BMC Execute Command  ${event_log}
206
207    SSHLibrary.Switch Connection  snmp_server
208    ${SNMP_LISTEN_OUT}=  Read  delay=1s
209
210    Delete SNMP Manager Via Redfish  ${SNMP_MGR1_IP}  ${SNMP_DEFAULT_PORT}
211
212    # Stop SNMP manager process.
213    SSHLibrary.Execute Command  sudo killall snmptrapd
214
215    # Sample SNMP trap:
216    # 2021-06-16 07:05:29 xx.xx.xx.xx [UDP: [xx.xx.xx.xx]:58154->[xx.xx.xx.xx]:xxx]:
217    # DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (2100473) 5:50:04.73
218    #   SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.49871.1.0.0.1
219    #  SNMPv2-SMI::enterprises.49871.1.0.1.1 = Gauge32: 369    SNMPv2-SMI::enterprises.49871.1.0.1.2 = Opaque:
220    # UInt64: 1397718405502468474     SNMPv2-SMI::enterprises.49871.1.0.1.3 = INTEGER: 3
221    #      SNMPv2-SMI::enterprises.49871.1.0.1.4 = STRING: "xxx.xx.xx Failure"
222
223    ${lines}=  Split To Lines  ${SNMP_LISTEN_OUT}
224    ${trap_info}=  Get From List  ${lines}  -1
225    ${snmp_trap}=  Split String  ${trap_info}  \t
226
227    Verify SNMP Trap  ${snmp_trap}  ${expected_error}
228
229    [Return]  ${snmp_trap}
230
231
232Verify SNMP Trap
233    [Documentation]  Verify SNMP trap.
234    [Arguments]  ${snmp_trap}  ${expected_error}=${SNMP_TRAP_BMC_INTERNAL_FAILURE}
235
236    # Description of argument(s):
237    # snmp_trap       SNMP trap collected on SNMP manager.
238    # expected_error  Expected error on SNMP.
239
240    # Verify all the mandatory fields of trap.
241    Should Contain  ${snmp_trap}[0]  DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks:
242    Should Be Equal  ${snmp_trap}[1]  SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.49871.1.0.0.1
243    Should Match Regexp  ${snmp_trap}[2]  SNMPv2-SMI::enterprises.49871.1.0.1.1 = Gauge32: \[0-9]*
244    Should Match Regexp  ${snmp_trap}[3]  SNMPv2-SMI::enterprises.49871.1.0.1.2 = Opaque: UInt64: \[0-9]*
245    Should Match Regexp  ${snmp_trap}[4]  SNMPv2-SMI::enterprises.49871.1.0.1.3 = INTEGER: \[0-9]
246    Should Be Equal  ${snmp_trap}[5]  SNMPv2-SMI::enterprises.49871.1.0.1.4 = STRING: "${expected_error}"
247
248
249Start SNMP Manager
250    [Documentation]  Start SNMP listener on the remote SNMP manager.
251
252    Open Connection And Log In  ${SNMP_MGR1_USERNAME}  ${SNMP_MGR1_PASSWORD}
253    ...  alias=snmp_server  host=${SNMP_MGR1_IP}
254
255    # The execution of the SNMP_TRAPD_CMD is necessary to cause SNMP to begin
256    # listening to SNMP messages.
257    SSHLibrary.write  ${SNMP_TRAPD_CMD} &
258
259
260Create Error On BMC And Verify Trap On Non-Default Port
261    [Documentation]  Generate error on BMC and verify if trap is sent to non default port.
262    [Arguments]  ${event_log}=${CMD_INTERNAL_FAILURE}  ${expected_error}=${SNMP_TRAP_BMC_INTERNAL_FAILURE}
263
264    # Description of argument(s):
265    # event_log       Event logs to be created.
266    # expected_error  Expected error on SNMP.
267
268    Configure SNMP Manager Via Redfish  ${SNMP_MGR1_IP}  ${NON_DEFAULT_PORT1}
269
270    Start SNMP Manager On Specific Port  ${SNMP_MGR1_IP}  ${NON_DEFAULT_PORT1}
271
272    # Generate error log.
273    BMC Execute Command  ${event_log}
274
275    SSHLibrary.Switch Connection  snmp_server
276    ${SNMP_LISTEN_OUT}=  Read  delay=1s
277
278    Delete SNMP Manager Via Redfish  ${SNMP_MGR1_IP}  ${NON_DEFAULT_PORT1}
279
280    # Stop SNMP manager process.
281    SSHLibrary.Execute Command  sudo killall snmptrapd
282
283    # Sample SNMP trap:
284    # 2021-06-16 07:05:29 xx.xx.xx.xx [UDP: [xx.xx.xx.xx]:58154->[xx.xx.xx.xx]:xxx]:
285    # DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (2100473) 5:50:04.73
286    #   SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.49871.1.0.0.1
287    #  SNMPv2-SMI::enterprises.49871.1.0.1.1 = Gauge32: 369    SNMPv2-SMI::enterprises.49871.1.0.1.2 = Opaque:
288    # UInt64: 1397718405502468474     SNMPv2-SMI::enterprises.49871.1.0.1.3 = INTEGER: 3
289    #      SNMPv2-SMI::enterprises.49871.1.0.1.4 = STRING: "xxx.xx.xx Failure"
290
291    ${lines}=  Split To Lines  ${SNMP_LISTEN_OUT}
292    ${trap_info}=  Get From List  ${lines}  -1
293    ${snmp_trap}=  Split String  ${trap_info}  \t
294
295    Verify SNMP Trap  ${snmp_trap}  ${expected_error}
296
297    [Return]  ${snmp_trap}
298
299
300Start SNMP Manager On Specific Port
301    [Documentation]  Start SNMP listener on specific port on the remote SNMP manager.
302    [Arguments]  ${snmp_mgr_ip}  ${snmp_port}
303
304    # Description of argument(s):
305    # snmp_mgr_ip  SNMP manager IP.
306    # snmp_port    Network port on which SNMP manager need to run.
307
308    ${ip_and_port}=  Catenate  ${snmp_mgr_ip}:${snmp_port}
309
310    Open Connection And Log In  ${SNMP_MGR1_USERNAME}  ${SNMP_MGR1_PASSWORD}
311    ...  alias=snmp_server  host=${SNMP_MGR1_IP}
312
313    # The execution of the SNMP_TRAPD_CMD is necessary to cause SNMP to begin
314    # listening to SNMP messages.
315    SSHLibrary.write  ${SNMP_TRAPD_CMD} ${ip_and_port} &
316
317
318Generate Error On BMC And Verify Trap
319    [Documentation]  Generate error on BMC and verify if trap is sent.
320    [Arguments]  ${event_log}=${CMD_INTERNAL_FAILURE}  ${expected_error}=${SNMP_TRAP_BMC_INTERNAL_FAILURE}
321
322    # Description of argument(s):
323    # event_log       Event logs to be created.
324    # expected_error  Expected error on SNMP.
325
326    Start SNMP Manager
327
328    # Generate error log.
329    BMC Execute Command  ${event_log}
330
331    SSHLibrary.Switch Connection  snmp_server
332    ${SNMP_LISTEN_OUT}=  Read  delay=1s
333
334    Delete SNMP Manager Via Redfish  ${SNMP_MGR1_IP}  ${SNMP_DEFAULT_PORT}
335
336    # Stop SNMP manager process.
337    SSHLibrary.Execute Command  sudo killall snmptrapd
338
339    # Sample SNMP trap:
340    # 2021-06-16 07:05:29 xx.xx.xx.xx [UDP: [xx.xx.xx.xx]:58154->[xx.xx.xx.xx]:xxx]:
341    # DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (2100473) 5:50:04.73
342    #   SNMPv2-MIB::snmpTrapOID.0 = OID: SNMPv2-SMI::enterprises.49871.1.0.0.1
343    #  SNMPv2-SMI::enterprises.49871.1.0.1.1 = Gauge32: 369    SNMPv2-SMI::enterprises.49871.1.0.1.2 = Opaque:
344    # UInt64: 1397718405502468474     SNMPv2-SMI::enterprises.49871.1.0.1.3 = INTEGER: 3
345    #      SNMPv2-SMI::enterprises.49871.1.0.1.4 = STRING: "xxx.xx.xx Failure"
346
347    ${lines}=  Split To Lines  ${SNMP_LISTEN_OUT}
348    ${trap_info}=  Get From List  ${lines}  -1
349    ${snmp_trap}=  Split String  ${trap_info}  \t
350
351    Verify SNMP Trap  ${snmp_trap}  ${expected_error}
352
353    [Return]  ${snmp_trap}
354
355