2 Documentation Keywords used to create/modify flow objects. The object is defined in the
3 ... corresponding FlowLib.py library and contains pertinent fields and methods (e.g.,
4 ... cookie and barrier fields, string formatted xml that can be used to push to
8 Library RequestsLibrary
9 Variables ../variables/Variables.py
15 [Documentation] Calls FlowLib.Make_Inventory_Flow function and initializes and sanitizes
16 ... the basic flow elements that can be given to flow:inventory
17 ${flow}= Make Inventory Flow
21 [Documentation] Used for creating an object that will use an XML format that
22 ... can be given to flow:service.
23 ${flow}= Make Service Flow
26 Set "${flow}" "${property}" With "${property_val}"
27 [Documentation] Embedded variables to make higher level keywords more readable.
28 ... There are some cases where the python attribute uses an underscore,
29 ... but a hyphen needs to be used. This seems inconsistent, and may need
30 ... to be looked at from the openflow plugin perspective.
32 ... At this point, this library will remove the element ${property} from the
33 ... xml representation of the flow and reset with the given value. \ It's not
34 ... possible, yet, to have multiple elements with the same name. \ That will
35 ... likely be needed in the future.
36 ${property} Run Keyword If "table_id" != "${property}" and "cookie_mask" != "${property}" Replace String ${property} _ -
37 ... ELSE Set Variable ${property}
38 Remove Flow XML Element ${flow} ${property}
39 Add Flow XML Element ${flow} ${property} ${property_val}
40 Set Flow Field ${flow} ${property} ${property_val}
44 [Arguments] ${flow} ${instruction_order} ${action_order} ${action} ${action_val}=${EMPTY}
45 [Documentation] Will remove the instruction element first, then add the proper xml structure
46 ... to implement the action as given in the arguments
47 ##For the case that any of the instruction/apply-actions/action elements are not there we need to add them'
48 Remove Flow XML Element ${flow} instruction
49 Add Flow XML Element ${flow} instruction ${EMPTY} instructions
50 Add Flow XML Element ${flow} order ${instruction_order} instructions/instruction
51 Add Flow XML Element ${flow} apply-actions ${EMPTY} instructions/instruction
52 Add Flow XML Element ${flow} action ${EMPTY} instructions/instruction/apply-actions
53 Add Flow XML Element ${flow} order ${action_order} instructions/instruction/apply-actions/action
54 Add Flow XML Element ${flow} ${action} ${action_val} instructions/instruction/apply-actions/action
57 Set Flow Output Action
58 [Arguments] ${flow} ${instruction_order} ${action_order} ${output_port}
59 Set Flow Action ${flow} ${instruction_order} ${action_order} output-action
60 Add Flow XML Element ${flow} output-node-connector ${output_port} instructions/instruction/apply-actions/action/output-action
63 Set Flow Ethernet Match
64 [Arguments] ${flow} ${match_value_dict}
65 [Documentation] Specific keyword for adding an ethernet match rules where the elements are given
66 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
67 ... existing ethernet-match elements from the flow before adding
68 Clear Flow Matches ${flow} match/ethernet-match
69 Add Flow XML Element ${flow} ethernet-match ${EMPTY} match
70 ${type}= Get From Dictionary ${match_value_dict} type
71 Add Flow XML Element ${flow} ethernet-type ${EMPTY} match/ethernet-match
72 Add Flow XML Element ${flow} type ${type} match/ethernet-match/ethernet-type
73 ${src}= Get From Dictionary ${match_value_dict} source
74 Add Flow XML Element ${flow} ethernet-source ${EMPTY} match/ethernet-match
75 Add Flow XML Element ${flow} address ${src} match/ethernet-match/ethernet-source
76 ${dst}= Get From Dictionary ${match_value_dict} destination
77 Add Flow XML Element ${flow} ethernet-destination ${EMPTY} match/ethernet-match
78 Add Flow XML Element ${flow} address ${dst} match/ethernet-match/ethernet-destination
82 [Arguments] ${flow} ${match_value_dict}
83 [Documentation] Specific keyword for adding an ipv4 match rules where the elements are given
84 ... in key/value pairs inside the ${match_value_dict} argument. This keyword will also remove any
85 ... existing ipv4 match elements from the flow before adding
86 Clear Flow Matches ${flow} match/ipv4-source
87 Clear Flow Matches ${flow} match/ipv4-destination
88 ${src}= Get From Dictionary ${match_value_dict} source
89 Add Flow XML Element ${flow} ipv4-source ${src} match
90 ${dst}= Get From Dictionary ${match_value_dict} destination
91 Add Flow XML Element ${flow} ipv4-destination ${dst} match
96 [Documentation] Will clean out any existing flow actions in the given ${flow} object
97 Remove Flow XML Element ${flow} instructions/instruction
101 [Arguments] ${flow} ${match_element}
102 [Documentation] Will clean out any existing flow matches in the given ${flow} object
103 Remove Flow XML Element ${flow} match/${match_element}
106 Set Flow XML Element Attribute
107 [Arguments] ${flow} ${element} ${id} ${value}
108 [Documentation] Will set the given id/value pair to the given to the element provided
109 ... and make the proper changes to the ${flow} object also provided.
110 ${flow_xml}= Parse XML ${flow.xml}
111 Set Element Attribute ${flow_xml} ${id} ${value} xpath=${element}
112 ${xml_string}= Element To String ${flow_xml}
113 Set Flow Field ${flow} xml ${xml_string}
118 [Arguments] ${flow} ${element} ${element_val}=${EMPTY} ${xpath}=.
119 [Documentation] Will modify the current xml representation of the ${flow} object to contain
120 ... the given ${element} at the given ${xpath}. If the ${element} uses a value, that can be
121 ... passed eith the ${element_val} which defaults to ${EMPTY} if not used. NOTE: since there
122 ... are two default parameters to this keyword, if you have an ${xpath} to use, but no ${element_val}
123 ... you will still need to pass ${EMPTY} when invoking so that ${xpath} will end up at the right
124 ... location in the parameter list
125 ${flow_xml}= Parse XML ${flow.xml}
126 Add Element ${flow_xml} <${element}>${element_val}</${element}> xpath=${xpath}
127 ${xml_string}= Element To String ${flow_xml}
128 Set Flow Field ${flow} xml ${xml_string}
132 Remove Flow XML Element
133 [Arguments] ${flow} ${element_xpath}
134 [Documentation] Removes the element at the given ${element_xpath} within the given ${flow}
135 ... object. The ${flow} object's xml representation will be updated to reflect this removal.
136 ${flow_xml}= Parse XML ${flow.xml}
137 Run Keyword And Ignore Error Remove Elements ${flow_xml} xpath=${element_xpath}
138 ${xml_string}= Element To String ${flow_xml}
139 Set Flow Field ${flow} xml ${xml_string}
142 Add Flow To Controller And Verify
143 [Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
144 [Documentation] Push flow through REST-API and verify in data-store
145 ${resp} RequestsLibrary.Put session ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${HEADERS_XML} data=${flow_body}
147 Should Be Equal As Strings ${resp.status_code} 200
148 ${resp} RequestsLibrary.Get session ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id} headers=${ACCEPT_XML}
150 Should Be Equal As Strings ${resp.status_code} 200
151 compare xml ${flow_body} ${resp.content}
153 Verify Flow On Mininet Switch
154 [Arguments] ${flow_elements}
155 [Documentation] Checking flow on switch
157 write dpctl dump-flows -O OpenFlow13
158 ${switchoutput} Read Until >
159 : FOR ${flowElement} IN @{flow_elements}
160 \ should Contain ${switchoutput} ${flowElement}
162 Remove Flow From Controller And Verify
163 [Arguments] ${flow_body} ${node_id} ${table_id} ${flow_id}
164 [Documentation] Remove flow
165 ${resp} RequestsLibrary.Delete session ${REST_CON}/node/${node_id}/table/${table_id}/flow/${flow_id}
167 Should Be Equal As Strings ${resp.status_code} 200
168 ${resp} RequestsLibrary.Get session ${REST_CON}/node/${node_id}/table/${table_id}
170 Should Not Contain ${resp.content} ${flow_id}
172 Verify Flow Does Not Exist On Mininet Switch
173 [Arguments] ${flow_elements}
174 [Documentation] Checking flow on switch is removed
176 write dpctl dump-flows -O OpenFlow13
177 ${switchoutput} Read Until >
178 : FOR ${flowElement} IN @{flow_elements}
179 \ should Not Contain ${switchoutput} ${flowElement}
182 [Arguments] ${node_id}
183 [Documentation] Removes any flows considered "default". one such flow is
184 ... to forward all traffic to the CONTROLLER with priority 0 at flow-table 0
185 ... If/When others are implemented this keyword can be updated to include those.
186 ${flow}= Make Service Flow
187 Set "${flow}" "priority" With "0"
188 Set "${flow}" "flow-table" With "0"
189 Add Flow XML Element ${flow} node /inv:nodes/inv:node[inv:id="${node_id}"]
190 Set Flow XML Element Attribute ${flow} node xmlns:inv urn:opendaylight:inventory
191 Log Flow XML is ${flow.xml}
192 write dpctl dump-flows -O OpenFlow13
193 ${switchoutput} Read Until >
194 ${headers}= Create Dictionary Content-Type=application/yang.data+xml
195 ${resp} RequestsLibrary.Post session restconf/operations/sal-flow:remove-flow data=${flow.xml} headers=${headers}
197 Should Be Equal As Strings ${resp.status_code} 200
198 ${resp}= RequestsLibrary.Get session ${OPERATIONAL_NODES_API}
200 Should Not Contain ${resp.content} "output-node-connector": "CONTROLLER",
201 ${strings_to_check_for}= Create List CONTROLLER
202 Verify Flow Does Not Exist On Mininet Switch ${strings_to_check_for}
204 Create Flow Variables For Suite From XML File
206 [Documentation] Given the flow XML ${file}, it will create several suite wide variables
207 ${data}= OperatingSystem.Get File ${file}
208 ${xmlroot}= Parse Xml ${file}
209 ${table_id}= Get Element Text ${xmlroot} table_id
210 ${flow_id}= Get Element Text ${xmlroot} id
211 ${flow_priority}= Get Element Text ${xmlroot} priority
212 ${upddata}= Get Data For Flow Put Update ${data}
213 Set Suite Variable ${table_id}
214 Set Suite Variable ${flow_id}
215 Set Suite Variable ${flow_priority}
216 Set Suite Variable ${data}
217 Set Suite Variable ${upddata}
218 Set Suite Variable ${xmlroot}
220 Check Datastore Presence
221 [Arguments] ${fname} ${reqconfpres} ${reqoperpres} ${upd}
222 [Documentation] Checks if flow is properly existing or not existing in the config and operational
223 ... datastores, based on the variables ${reqconfpres} and ${reqoperpres}
224 Create Flow Variables For Suite From XML File ${XmlsDir}/${fname}
225 # Note: ${upddata} and ${data} are suite variables set by the keyword above.
226 ${det}= Set Variable If ${upd}==${True} ${upddata} ${data}
227 Check Config Flow ${reqconfpres} ${det}
228 Check Operational Flow ${reqoperpres} ${det}
230 Flow Presence In Config Store
231 [Arguments] ${expvalue}
232 [Documentation] Checks the config store for given flow. Returns True if present, otherwise returns False
233 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
234 ${headers}= Create Dictionary Accept=application/xml
235 ${resp}= RequestsLibrary.Get session ${CONFIG_NODES_API}/node/openflow:${switch_idx}/table/${table_id}/flow/${flow_id} headers=${headers}
238 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
239 ${pres} ${msg}= Is Flow Configured ${expvalue} ${resp.content}
240 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
241 Return From Keyword ${pres} ${msg}
243 Flow Presence In Operational Store
244 [Arguments] ${expvalue}
245 [Documentation] Checks the operational store for given flow. Returns True if present, otherwise returns False
246 ... This keyword assumes that the global/suite variables are available (${table_id}, ${flow_id} and ${switch_idx}
247 ${headers}= Create Dictionary Accept=application/xml
248 ${resp}= RequestsLibrary.Get session ${OPERATIONAL_NODES_API}/node/openflow:${switch_idx}/table/${table_id} headers=${headers}
251 Return From Keyword If ${resp.status_code}!=200 ${False} ${EMPTY}
252 ${pres} ${msg}= Is Flow Operational2 ${expvalue} ${resp.content}
253 Run Keyword If '''${msg}'''!='${EMPTY}' Log ${msg}
254 Return From Keyword ${pres} ${msg}
256 Get Presence Failure Message
257 [Arguments] ${ds} ${expected} ${presence} ${diffmsg}
258 [Documentation] Utility keyword to help manipulate mesage strings that may be used later to PASS or FAIL with
259 Return From Keyword If '''${diffmsg}'''!='${EMPTY}' Flow found in ${ds} data store but: ${diffmsg}
260 ${msgf}= Set Variable If ${expected}==${True} The flow is expected in ${ds} data store, but The flow is not expected in ${ds} data store, but
261 ${msgp}= Set Variable If ${presence}==${True} it is present. it is not present.
262 Return From Keyword ${msgf} ${msgp}
265 [Arguments] ${expected} ${expvalue}
266 [Documentation] Wrapper keyword that calls "Flow Presence In Config Store" and "Get Presence Failure Message" from this library
267 ... to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
268 ${presence_flow} ${msg}= Flow Presence In Config Store ${expvalue}
269 ${msgf}= Get Presence Failure Message config ${expected} ${presence_flow} ${msg}
270 Should Be Equal ${expected} ${presence_flow} msg=${msgf}
272 Check Operational Flow
273 [Arguments] ${expected} ${expvalue}
274 [Documentation] Wrapper keyword that calls "Flow Presence In Operational Store" and "Get Presence Failure Message" from this library
275 ... to verify that the ${expvalue} flow is or is not found in the config store, depending on whether or not it was ${expected}
276 ${presence_table} ${msg}= Flow Presence In Operational Store ${expvalue}
277 ${msgf}= Get Presence Failure Message operational ${expected} ${presence_table} ${msg}
278 Should Be Equal ${expected} ${presence_table} msg=${msgf}
281 [Arguments] ${node_id} ${xmlroot}
282 [Documentation] Deploys a flow specified by given flow details (${node_id}, ${xmlroot}) using add-flow operation.
283 ... ${xmlroot} is an xml object of parser xml flow details, usually created by Create Flow Variables For Suite From XML File
284 ... keyword from this library.
285 ${req}= Copy Element ${xmlroot}
286 Remove Element ${req} id clear_tail=True
287 Set Element Tag ${req} input
288 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
289 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
290 ${nodeelm}= Get Element ${req} node
291 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
293 ${strxml}= Element To String ${req}
294 ${resp}= RequestsLibrary.Post session /restconf/operations/sal-flow:add-flow data=${strxml}
296 Should Be Equal As Strings ${resp.status_code} 200
298 Add Flow Via Restconf
299 [Arguments] ${node_id} ${table_id} ${flow_body}
300 [Documentation] Configures a flow specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using POST method
302 ${resp}= RequestsLibrary.Post session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} data=${flow_body}
304 ${msg}= Set Variable Adding flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id} failed, http response ${resp.status_code} received.
305 Should Be Equal As Strings ${resp.status_code} 204 msg=${msg}
308 [Arguments] ${node_id} ${configured_flow_body} ${updating_flow_body}
309 [Documentation] Updates a flow by using update-flow operation. ${xmlroot} is usually a variable created by
310 ... Create Flow Variables For Suite From XML File keyword from this library.
311 Log ${configured_flow_body}
312 Log ${updating_flow_body}
313 ${xml} Parse Xml <input xmlns="urn:opendaylight:flow:service"></input>
315 ${origflow}= Parse Xml ${configured_flow_body}
316 ${updflow}= Parse Xml ${updating_flow_body}
317 Remove Element ${origflow} id clear_tail=True
318 Remove Element ${updflow} id clear_tail=True
319 Remove Element Attribute ${origflow} xmlns
320 Remove Element Attribute ${updflow} xmlns
321 Set Element Tag ${origflow} original-flow
322 Set Element Tag ${updflow} updated-flow
323 Add Element ${xml} ${origflow}
324 Add Element ${xml} ${updflow}
325 Add Element ${xml} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
326 ${nodeelm}= Get Element ${xml} node
327 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
329 ${strxml}= Element To String ${xml}
330 ${resp}= RequestsLibrary.Post session /restconf/operations/sal-flow:update-flow data=${strxml}
332 Should Be Equal As Strings ${resp.status_code} 200
334 Update Flow Via Restconf
335 [Arguments] ${node_id} ${table_id} ${flow_id} ${flow_body}
336 [Documentation] Updates a flow configuration by given flow details (${node_id}, ${table_id}, ${flow_body}) using PUT method
338 ${resp}= RequestsLibrary.Put session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} data=${flow_body}
340 ${msg}= Set Variable Updating flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
341 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}
344 [Arguments] ${node_id} ${xmlroot}
345 [Documentation] Deletes a flow by using remove-flow opearation. ${xmlroot} is usually a variable created by
346 ... Create Flow Variables For Suite From XML File keyword from this library.
347 ${req}= Copy Element ${xmlroot}
348 Remove Element ${req} id clear_tail=True
349 Set Element Tag ${req} input
350 Set Element Attribute ${req} xmlns urn:opendaylight:flow:service
351 Add Element ${req} <node>/inv:nodes/inv:node[inv:id="openflow:${node_id}"]</node>
352 ${nodeelm}= Get Element ${req} node
353 Set Element Attribute ${nodeelm} xmlns:inv urn:opendaylight:inventory
355 ${strxml}= Element To String ${req}
356 ${resp}= RequestsLibrary.Post session /restconf/operations/sal-flow:remove-flow data=${strxml}
358 Should Be Equal As Strings ${resp.status_code} 200
360 Delete Flow Via Restconf
361 [Arguments] ${node_id} ${table_id} ${flow_id}
362 [Documentation] Deletes a flow from configuration datastore specified by given flow details (${node_id}, ${table_id}, ${flow_body}) using DELETE method
363 ${resp}= RequestsLibrary.Delete session ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id}
365 ${msg}= Set Variable Delete flow for ${CONFIG_NODES_API}/node/openflow:${node_id}/table/${table_id}/flow/${flow_id} failed, http response ${resp.status_code} received.
366 Should Be Equal As Strings ${resp.status_code} 200 msg=${msg}