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