Reputation: 2841
I am needing to modify my Openflow configurations in my Opendaylight (0.11.x sodium) system. I follow the documentation which has helped guide is in
The top paragraph references modifying a config but doesn't actually show an example. And just to be clear, by modification I mean a merge operation. I.e., in terms of the netconf edit-config RFC-6241, I am wanting to modify only some of the leafs of a config, but keep older leafs.
Unfortunately, the options I see given in the openflow documentation is only creating, deleting, and replacing. We need to figure out how to do a merge.
In doing some research, it appears there is functionality with REST PATCH
commands, however I am unable to get Opendaylight to work with it. Here is what I am trying:
PATCH //127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:244354675513412/table/0/flow/105 HTTP/1.1
Content-Type: application/yang.patch+xml
Accept: application/yang.patch+json
Authorization: Basic YWRtaW46YWRtaW4=
User-Agent: PostmanRuntime/7.26.8
Postman-Token: 875a3c91-f6b1-4d21-8f2d-615b3c4b5cdd
Host: 127.0.0.1:8181
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 1233
Cookie: JSESSIONID=node0dqx2exo4lrydz1adjhvc9lum374.node0
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<flow xmlns='urn:opendaylight:flow:inventory' xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
<strict>false</strict>
<id>105</id>
<priority>9</priority>
<table_id>0</table_id>
<hard-timeout>0</hard-timeout>
<idle-timeout>0</idle-timeout>
<flow-name>10dot0SubnetToPort1_from_4</flow-name>
<match>
<ethernet-match>
<ethernet-type>
<type>2048</type>
</ethernet-type>
<ethernet-destination>
<address>FF:FF:29:01:19:61</address>
</ethernet-destination>
<ethernet-source>
<address>00:00:00:11:23:AE</address>
</ethernet-source>
</ethernet-match>
</match>
<instructions>
<instruction>
<order>1</order>
<apply-actions>
<action>
<order>0</order>
<output-action>
<output-node-connector>6</output-node-connector>
<max-length>66</max-length>
</output-action>
</action>
</apply-actions>
</instruction>
</instructions>
</flow>
But the response I get back is: 406 Not Acceptable
and nothing else... No <error...
rpc-response or anything. I also am studying the log files in DEBUG and TRACE mode and can't pick up any hint as to what is going wrong.
I also tried pasting in nc:operation='merge'
to each element like this...
...
<output-action nc:operation='merge'>
<output-node-connector nc:operation='merge'>6</output-node-connector>
<max-length nc:operation='merge'>66</max-length>
</output-action>
...
But this also results in the same 406 Not Acceptable
response.
Goal: how does one properly merge/modify a config in OpenDaylight/Openflow
Upvotes: 1
Views: 912
Reputation: 41
This looks to be an issue of global-level config/node-level config in netconf edit operation. ODL sends out netconf RPCs to mounted netconf devices. I'm certain of later version (11.2 and on) are supporting yang-patch at node-level config. Not sure which version you're using ??
Also this could be an issue of netconf device you're trying to configure, if node-level config is not supported and enabled, ODL could receive error from netconf response.
Either way, checking yang-tool logs on ODL can make this clear for you. you can enable logs on karaf for yang-tools and can set-up detailed logs. That could explain this more.
Upvotes: 0
Reputation: 11
I have tried to execute yang-patch using the RFC 8040 endpoint and I'm still having some issues--it appears I cannot delete a target with a value other than "/"
. This is to modify flows in the openflow plugin.
Querying a particular flow here is what I get:
GET localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0
Response:
{
"flow-node-inventory:instruction": [
{
"order": 0,
"apply-actions": {
"action": [
{
"order": 4,
"output-action": {
"output-node-connector": "2",
"max-length": 60
}
},
{
"order": 0,
"set-field": {
"ipv4-source": "10.0.0.254/32"
},
"set-nw-src-action": {
"ipv4-address": "10.0.0.254/32"
}
},
{
"order": 1,
"set-field": {
"ipv4-destination": "10.0.0.21/32"
},
"set-nw-dst-action": {
"ipv4-address": "10.0.0.21/32"
}
},
{
"order": 2,
"output-action": {
"output-node-connector": "2",
"max-length": 60
}
},
{
"order": 3,
"set-field": {
"ipv4-destination": "10.0.0.29/32"
},
"set-nw-dst-action": {
"ipv4-address": "10.0.0.29/32"
}
}
]
}
}
]
}
This is expected--I've installed a flow with specific actions and they're listed appropriately.
Now, let's say I want to delete the action with order=4
above. I would think I would create my request in the following way:
PATCH localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0
Content-type and accept-types are set according to the yang.patch requirements.
Body:
{
"ietf-restconf:yang-patch" : {
"patch-id" : "0",
"edit" : [
{
"edit-id" : "edit1",
"operation" : "delete",
"target" : "/flow-node-inventory:apply-actions/flow-node-inventory:action[flow-node-inventory:order='4']"
}
]
}
}
Response:
{
"ietf-yang-patch:yang-patch-status": {
"patch-id": "0",
"edit-status": {
"edit": [
{
"edit-id": "edit1",
"errors": {
"error": [
{
"error-type": "protocol",
"error-tag": "data-missing",
"error-path": "/(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:152169965450049}]/AugmentationIdentifier{childNames=[(urn:opendaylight:flow:inventory?revision=2013-08-19)description, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-actions, (urn:opendaylight:flow:inventory?revision=2013-08-19)hardware, (urn:opendaylight:flow:inventory?revision=2013-08-19)switch-features, (urn:opendaylight:flow:inventory?revision=2013-08-19)stale-meter, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-instructions, (urn:opendaylight:flow:inventory?revision=2013-08-19)meter, (urn:opendaylight:flow:inventory?revision=2013-08-19)serial-number, (urn:opendaylight:flow:inventory?revision=2013-08-19)stale-group, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-match-types, (urn:opendaylight:flow:inventory?revision=2013-08-19)port-number, (urn:opendaylight:flow:inventory?revision=2013-08-19)table, (urn:opendaylight:flow:inventory?revision=2013-08-19)group, (urn:opendaylight:flow:inventory?revision=2013-08-19)manufacturer, (urn:opendaylight:flow:inventory?revision=2013-08-19)table-features, (urn:opendaylight:flow:inventory?revision=2013-08-19)software, (urn:opendaylight:flow:inventory?revision=2013-08-19)ip-address]}/(urn:opendaylight:flow:inventory?revision=2013-08-19)table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=0}]/flow/flow[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=259}]/instructions/instruction/instruction[{(urn:opendaylight:flow:inventory?revision=2013-08-19)order=0}]/instruction/apply-actions/action/action[{(urn:opendaylight:flow:inventory?revision=2013-08-19)order=4}]",
"error-message": "Data does not exist"
}
]
}
}
]
}
}
}
Now, I know the data exists, but it seems that I cannot request a delete for the particular element I've specified in the target. Indeed, the only way I can delete a particular element is to use "target" : "/"
, which will delete the child elements according to the last hierarchical element in the URL.
Not sure what I'm doing wrong here--I would have thought I could specify a target and get a delete to execute accordingly, but I'm not sure what else I need to do.
Upvotes: 1
Reputation: 41
You're correct about 'target' field and its function. However, target field should only contain the name of resource/prefix you're trying to modify.
I'd suggest you to change your flow and target resources accordingly. What I mean by that is you need to make sure the flow and target resources are leading to same resource you're trying to configure.
It should be something like :
PATCH localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0/flow-node-inventory:apply-actions/order=4
and keep Target resource as = /flow-node-inventory:action[flow-node-inventory:order='4']
Try GET on the flow to confirm you're receiving only the resource you're trying to modify/delete.
Upvotes: 2
Reputation: 41
Try to install 'odl-restconf-nb-RFC8040' endpoint on your karaf shell. ODL provides two end-point for restconf communication. Although less documents on RFC-8040, yang-patch gives no error through that. (YANG-PATCH allows "create, delete, insert, merge, move, replace, remove" operations. Creating, modifying and deleting configs can be done by changing operation in this payload. https://docs.opendaylight.org/projects/netconf/en/latest/user-guide.html#reconfiguring-an-existing-connector )
RFC-8040 defines YANG-PATCH according to this RFC : https://datatracker.ietf.org/doc/html/draft-ietf-netconf-yang-patch-14#section-2
Your header looks good.
Your API will begin like : PATCH //127.0.0.1:8181/rests/data/.../...
Upvotes: 1