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