07-13-2022 12:26 PM - edited 07-13-2022 12:36 PM
Hi.
I have a CFN -> RFN scenario. An action on the CFN fetches some config from RFN and returns it in the output.message of type string.
Actual config is in the XML format. Perhaps call it a nested XML. What is interesting is that while output is nicely rendered in GUI
it gets mangled into escape string for < in curl or python requests module
The actual action POST response is correct normal tag, but the "body" of the response is just a string I write an XML payload into. And that string gets escaped for <. I tried pre-emptively escaping the < myself but it just ends up adding more escape strings to the output.
I did log the action code itself and it correctly processes the "body" text. This happens somewhere on the relation NSO RESTCONF engine - POST client. I ran out of ideas what to do.
Solved! Go to Solution.
07-18-2022 02:44 AM
You can use the yang anydata or anyxml stements. Anydata should be used in your case because there is a yang model of the data being returned, just that it is not statically known.
container action {
tailf:action test {
tailf:actionpoint anyxmltest-action;
output {
leaf result-string {
type string;
}
anyxml any-result;
anydata data-result;
}
}
}
Here is the python action:
class TestAction(Action):
@Action.action
def cb_action(self, uinfo, name, kp, input, output, trans):
self.log.info('action name: ', name)
# Updating the output data structure will result in a response
# being returned to the caller.
XML = '<hello>world</hello>'
output.result_string = XML
output.any_result = XML
output.data_result = XML
And result of testing:
snovello@SNOVELLO-M-V1ZP ANYXML % curl -u admin:admin --request POST 'http://127.0.0.1:8080/restconf/data/anyxmltest:action/test'
<output xmlns='http://example.com/anyxmltest'>
<result-string><hello>world</hello></result-string>
<any-result><hello>world</hello></any-result>
<data-result><hello>world</hello></data-result>
</output>
snovello@SNOVELLO-M-V1ZP ANYXML %
07-15-2022 03:32 AM
Hello,
Can you share with us your code ?
07-15-2022 02:46 PM
Hello ,
From the WEBUI , it's working because it's using JSONRPC and not RESTCONF API. I did try the same and got same error but when you switch the Accept to JSON you will get something better.
curl -X POST -u admin:admin -i http://localhost:8081/restconf/operations/action/get-config -d '{"input": {"response-format":"xml"}}' -H "Content-type:application/yang-data+json" -H "Accept:application/yang-data+json"
HTTP/1.1 200 OK
Date: Fri, 15 Jul 2022 21:44:31 GMT
Cache-Control: private, no-cache, must-revalidate, proxy-revalidate
Content-Length: 704
Content-Type: application/yang-data+json
Pragma: no-cache
Content-Security-Policy: default-src 'self'; block-all-mixed-content; base-uri 'self'; frame-ancestors 'none';
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
{
"get-config-from-rfs:output": {
"result": "<config xmlns=\"http://tail-f.com/ns/config/1.0\">\n <devices xmlns=\"http://tail-f.com/ns/ncs\">\n <authgroups>\n <group>\n <name>default</name>\n <umap>\n <local-user>admin</local-user>\n <remote-name>admin</remote-name>\n <remote-password>$9$09ec/rAIrWPCWZZIv87YrZD8Q2oJa0RET3sX0JMadic=</remote-password>\n </umap>\n <umap>\n <local-user>oper</local-user>\n <remote-name>oper</remote-name>\n <remote-password>$9$afUGLCtUdztJBsxAnS6yULzCCqv10jzfe1f8OWw6pYc=</remote-password>\n </umap>\n </group>\n </authgroups>\n </devices>\n</config>"
}
}
07-17-2022 05:02 AM - edited 07-17-2022 10:12 AM
Hey, yes we figured out that one too, however unfortunately returning XML in JSON causes \n and \ artefacts which, if handled, screws with the GUI print of the action (it isn't readable anymore). Also, unfortunately XML in XML is a requirement.
My guess is that some sort of encoding is happening in the RESTCONF engine on the NSO. The funny part is that only < are encoded and > are not.
As far as I can tell at this point, the only way out of this is correction on the client side.
07-18-2022 02:44 AM
You can use the yang anydata or anyxml stements. Anydata should be used in your case because there is a yang model of the data being returned, just that it is not statically known.
container action {
tailf:action test {
tailf:actionpoint anyxmltest-action;
output {
leaf result-string {
type string;
}
anyxml any-result;
anydata data-result;
}
}
}
Here is the python action:
class TestAction(Action):
@Action.action
def cb_action(self, uinfo, name, kp, input, output, trans):
self.log.info('action name: ', name)
# Updating the output data structure will result in a response
# being returned to the caller.
XML = '<hello>world</hello>'
output.result_string = XML
output.any_result = XML
output.data_result = XML
And result of testing:
snovello@SNOVELLO-M-V1ZP ANYXML % curl -u admin:admin --request POST 'http://127.0.0.1:8080/restconf/data/anyxmltest:action/test'
<output xmlns='http://example.com/anyxmltest'>
<result-string><hello>world</hello></result-string>
<any-result><hello>world</hello></any-result>
<data-result><hello>world</hello></data-result>
</output>
snovello@SNOVELLO-M-V1ZP ANYXML %
07-18-2022 04:10 AM
Thanks a bunch! It works.
I was approaching the issue from the wrong angle... was looking if there is an option to set leaf string encoding in YANG somehow.
I wouldn't have figured out that anydata thingy on my own.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide