1*** Settings ***
2Documentation  Network interface IPv6 configuration and verification
3               ...  tests.
4
5Resource       ../../lib/bmc_redfish_resource.robot
6Resource       ../../lib/openbmc_ffdc.robot
7Resource       ../../lib/bmc_ipv6_utils.robot
8Library        ../../lib/bmc_network_utils.py
9Library        Collections
10
11Test Setup     Test Setup Execution
12Test Teardown  Test Teardown Execution
13Suite Setup    Suite Setup Execution
14
15
16*** Variables ***
17${test_ipv6_addr}          2001:db8:3333:4444:5555:6666:7777:8888
18${test_ipv6_invalid_addr}  2001:db8:3333:4444:5555:6666:7777:JJKK
19
20# Valid prefix length is a integer ranges from 1 to 128.
21${test_prefix_length}     64
22
23
24*** Test Cases ***
25
26Get IPv6 Address And Verify
27    [Documentation]  Get IPv6 Address And Verify.
28    [Tags]  Get_IPv6_Address_And_Verify
29
30    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
31      Verify IPv6 On BMC  ${ipv6_network_configuration['Address']}
32    END
33
34
35Get PrefixLength And Verify
36    [Documentation]  Get IPv6 prefix length and verify.
37    [Tags]  Get_PrefixLength_And_Verify
38
39    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
40      Verify IPv6 On BMC  ${ipv6_network_configuration['PrefixLength']}
41    END
42
43
44Get IPv6 Default Gateway And Verify
45    [Documentation]  Get IPv6 default gateway and verify.
46    [Tags]  Get_IPv6_Default_Gateway_And_Verify
47
48    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}
49    ${ipv6_gateway}=  Get From Dictionary  ${resp.dict}  IPv6DefaultGateway
50    Verify IPv6 Default Gateway On BMC  ${ipv6_gateway}
51
52
53Verify All Configured IPv6 And PrefixLength On BMC
54    [Documentation]  Verify IPv6 address and its prefix length on BMC.
55    [Tags]  Verify_All_Configured_IPv6_And_PrefixLength_On_BMC
56
57    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
58      Verify IPv6 And PrefixLength  ${ipv6_network_configuration['Address']}
59      ...  ${ipv6_network_configuration['PrefixLength']}
60    END
61
62
63Configure IPv6 Address And Verify
64    [Documentation]  Configure IPv6 address and verify.
65    [Tags]  Configure_IPv6_Address_And_Verify
66    [Template]  Configure IPv6 Address On BMC
67
68
69    # IPv6 address     Prefix length
70    ${test_ipv6_addr}  ${test_prefix_length}
71
72
73Delete IPv6 Address And Verify
74    [Documentation]  Delete IPv6 address and verify.
75    [Tags]  Delete_IPv6_Address_And_Verify
76
77    Configure IPv6 Address On BMC  ${test_ipv6_addr}  ${test_prefix_length}
78
79    Delete IPv6 Address  ${test_ipv6_addr}
80
81
82*** Keywords ***
83
84Suite Setup Execution
85    [Documentation]  Do suite setup execution.
86
87    ${active_channel_config}=  Get Active Channel Config
88    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
89
90    Set Suite variable  ${ethernet_interface}
91
92
93Test Setup Execution
94    [Documentation]  Test setup execution.
95
96    Redfish.Login
97
98    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
99    Set Test Variable  @{ipv6_network_configurations}
100
101    # Get BMC IPv6 address and prefix length.
102    ${ipv6_data}=  Get BMC IPv6 Info
103    Set Test Variable  ${ipv6_data}
104
105
106Test Teardown Execution
107    [Documentation]  Test teardown execution.
108
109    FFDC On Test Case Fail
110    Redfish.Logout
111
112
113Get IPv6 Network Configuration
114    [Documentation]  Get Ipv6 network configuration.
115    # Sample output:
116    # {
117    #  "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0",
118    #  "@odata.type": "#EthernetInterface.v1_4_1.EthernetInterface",
119    #   "DHCPv4": {
120    #    "DHCPEnabled": false,
121    #    "UseDNSServers": false,
122    #    "UseDomainName": true,
123    #    "UseNTPServers": false
124    #  },
125    #  "DHCPv6": {
126    #    "OperatingMode": "Disabled",
127    #    "UseDNSServers": false,
128    #    "UseDomainName": true,
129    #    "UseNTPServers": false
130    #  },
131    #  "Description": "Management Network Interface",
132    #  "FQDN": "localhost",
133    #  "HostName": "localhost",
134    #  "IPv4Addresses": [
135    #    {
136    #      "Address": "xx.xx.xx.xx",
137    #      "AddressOrigin": "Static",
138    #      "Gateway": "xx.xx.xx.1",
139    #      "SubnetMask": "xx.xx.xx.0"
140    #    },
141    #    {
142    #      "Address": "169.254.xx.xx",
143    #      "AddressOrigin": "IPv4LinkLocal",
144    #      "Gateway": "0.0.0.0",
145    #      "SubnetMask": "xx.xx.0.0"
146    #    },
147    #  ],
148    #  "IPv4StaticAddresses": [
149    #    {
150    #      "Address": "xx.xx.xx.xx",
151    #      "AddressOrigin": "Static",
152    #      "Gateway": "xx.xx.xx.1",
153    #      "SubnetMask": "xx.xx.0.0"
154    #    }
155    # }
156    #  ],
157    #  "IPv6AddressPolicyTable": [],
158    #  "IPv6Addresses": [
159    #    {
160    #      "Address": "fe80::xxxx:xxxx:xxxx:xxxx",
161    #      "AddressOrigin": "LinkLocal",
162    #      "AddressState": null,
163    #      "PrefixLength": xx
164    #    }
165    #  ],
166    #  "IPv6DefaultGateway": "",
167    #  "IPv6StaticAddresses": [
168    #    { "Address": "xxxx:xxxx:xxxx:xxxx::xxxx",
169    #      "AddressOrigin": "Static",
170    #      "AddressState": null,
171    #      "PrefixLength": xxx
172    #    }
173    #  ],
174    #  "Id": "eth0",
175    #  "InterfaceEnabled": true,
176    #  "LinkStatus": "LinkUp",
177    #  "MACAddress": "xx:xx:xx:xx:xx:xx",
178    #  "Name": "Manager Ethernet Interface",
179    #  "NameServers": [],
180    #  "SpeedMbps": 0,
181    #  "StaticNameServers": [],
182    #  "Status": {
183    #    "Health": "OK",
184    #    "HealthRollup": "OK",
185    #    "State": "Enabled"
186    #  },
187    #  "VLANs": {
188    #    "@odata.id": "/redfish/v1/Managers/${MANAGER_ID}/EthernetInterfaces/eth0/VLANs"
189
190
191    ${active_channel_config}=  Get Active Channel Config
192    ${resp}=  Redfish.Get  ${REDFISH_NW_ETH_IFACE}${active_channel_config['${CHANNEL_NUMBER}']['name']}
193
194    @{ipv6_network_configurations}=  Get From Dictionary  ${resp.dict}  IPv6StaticAddresses
195    [Return]  @{ipv6_network_configurations}
196
197
198Verify IPv6 And PrefixLength
199    [Documentation]  Verify IPv6 address and prefix length on BMC.
200    [Arguments]  ${ipv6_addr}  ${prefix_len}
201
202    # Description of the argument(s):
203    # ipv6_addr   IPv6 address to be verified.
204    # prefix_len  PrefixLength value to be verified.
205
206    # Catenate IPv6 address and its prefix length.
207    ${ipv6_with_prefix}=  Catenate  ${ipv6_addr}/${prefix_len}
208
209    # Get IPv6 address details on BMC using IP command.
210    @{ip_data}=  Get BMC IPv6 Info
211
212    # Verify if IPv6 and prefix length is configured on BMC.
213
214    Should Contain  ${ip_data}  ${ipv6_with_prefix}
215    ...  msg=IPv6 and prefix length pair does not exist.
216
217
218Configure IPv6 Address On BMC
219    [Documentation]  Add IPv6 Address on BMC.
220    [Arguments]  ${ipv6_addr}  ${prefix_len}  ${valid_status_codes}=${HTTP_OK}
221
222    # Description of argument(s):
223    # ipv6_addr           IPv6 address to be added (e.g. "2001:EEEE:2222::2022").
224    # prefix_len          Prefix length for the IPv6 to be added
225    #                     (e.g. "64").
226    # valid_status_codes  Expected return code from patch operation
227    #                     (e.g. "200").
228
229    ${prefix_length}=  Convert To Integer  ${prefix_len}
230    ${empty_dict}=  Create Dictionary
231    ${ipv6_data}=  Create Dictionary  Address=${ipv6_addr}
232    ...  PrefixLength=${prefix_length}
233
234    ${patch_list}=  Create List
235
236    # Get existing static IPv6 configurations on BMC.
237    ${ipv6_network_configurations}=  Get IPv6 Network Configuration
238    ${num_entries}=  Get Length  ${ipv6_network_configurations}
239
240    FOR  ${INDEX}  IN RANGE  0  ${num_entries}
241      Append To List  ${patch_list}  ${empty_dict}
242    END
243
244    ${valid_status_codes}=  Run Keyword If  '${valid_status_codes}' == '${HTTP_OK}'
245    ...  Set Variable   ${HTTP_OK},${HTTP_NO_CONTENT}
246    ...  ELSE  Set Variable  ${valid_status_codes}
247
248    # We need not check for existence of IPv6 on BMC while adding.
249    Append To List  ${patch_list}  ${ipv6_data}
250    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
251
252    ${active_channel_config}=  Get Active Channel Config
253    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
254
255    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
256    ...  valid_status_codes=[${valid_status_codes}]
257
258    Return From Keyword If  '${valid_status_codes}' != '${HTTP_OK},${HTTP_NO_CONTENT}'
259
260    # Note: Network restart takes around 15-18s after patch request processing.
261    Sleep  ${NETWORK_TIMEOUT}s
262    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
263
264    Verify IPv6 And PrefixLength  ${ipv6_addr}  ${prefix_len}
265
266    # Verify if existing static IPv6 addresses still exist.
267    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
268      Verify IPv6 On BMC  ${ipv6_network_configuration['Address']}
269    END
270
271    Validate IPv6 Network Config On BMC
272
273
274Validate IPv6 Network Config On BMC
275    [Documentation]  Check that IPv6 network info obtained via redfish matches info
276    ...              obtained via CLI.
277    @{network_configurations}=  Get IPv6 Network Configuration
278    ${ipv6_data}=  Get BMC IPv6 Info
279    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
280      Should Contain Match  ${ipv6_data}  ${ipv6_network_configuration['Address']}/*
281      ...  msg=IPv6 address does not exist.
282    END
283
284
285Delete IPv6 Address
286    [Documentation]  Delete IPv6 address of BMC.
287    [Arguments]  ${ipv6_addr}  ${valid_status_codes}=${HTTP_OK}
288
289    # Description of argument(s):
290    # ipv6_addr           IPv6 address to be deleted (e.g. "2001:1234:1234:1234::1234").
291    # valid_status_codes  Expected return code from patch operation
292    #                     (e.g. "200").  See prolog of rest_request
293    #                     method in redfish_plus.py for details.
294
295    ${empty_dict}=  Create Dictionary
296    ${patch_list}=  Create List
297
298    @{ipv6_network_configurations}=  Get IPv6 Network Configuration
299    FOR  ${ipv6_network_configuration}  IN  @{ipv6_network_configurations}
300        IF  '${ipv6_network_configuration['Address']}' == '${ipv6_addr}'
301            Append To List  ${patch_list}  ${null}
302        ELSE
303            Append To List  ${patch_list}  ${empty_dict}
304        END
305    END
306
307    ${ip_found}=  Run Keyword And Return Status  List Should Contain Value
308    ...  ${patch_list}  ${null}  msg=${ipv6_addr} does not exist on BMC
309    Pass Execution If  ${ip_found} == ${False}  ${ipv6_addr} does not exist on BMC
310
311    # Run patch command only if given IP is found on BMC
312    ${data}=  Create Dictionary  IPv6StaticAddresses=${patch_list}
313
314    ${active_channel_config}=  Get Active Channel Config
315    ${ethernet_interface}=  Set Variable  ${active_channel_config['${CHANNEL_NUMBER}']['name']}
316
317    Redfish.patch  ${REDFISH_NW_ETH_IFACE}${ethernet_interface}  body=&{data}
318    ...  valid_status_codes=[${valid_status_codes}]
319
320    # Note: Network restart takes around 15-18s after patch request processing
321    Sleep  ${NETWORK_TIMEOUT}s
322    Wait For Host To Ping  ${OPENBMC_HOST}  ${NETWORK_TIMEOUT}
323
324    # IPv6 address that is deleted should not be there on BMC.
325    ${delete_status}=  Run Keyword And Return Status  Verify IPv6 On BMC  ${ipv6_addr}
326    IF  '${valid_status_codes}' == '${HTTP_OK}'
327        Should Be True  '${delete_status}' == '${False}'
328    ELSE
329        Should Be True  '${delete_status}' == '${True}'
330    END
331
332    Validate IPv6 Network Config On BMC
333