diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 7afa8091..7d304305 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -843,6 +843,13 @@ main(int argc, goto done; /* if status = STARTUP_INVALID, cbret contains info */ } + /* + * Disable unknown to anydata auto-creation after startup + */ + if (clicon_option_bool(h, "CLICON_YANG_UNKNOWN_ANYDATA") == 1){ + clicon_option_bool_set(h, "CLICON_YANG_UNKNOWN_ANYDATA", 0); + xml_bind_yang_unknown_anydata(0); + } /* Merge extra XML from file and reset function to running */ if (status == STARTUP_OK && startup_mode != SM_NONE){ diff --git a/test/test_yang_anydata.sh b/test/test_yang_anydata.sh index 1966c1d8..48cbdb26 100755 --- a/test/test_yang_anydata.sh +++ b/test/test_yang_anydata.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # Test YANG ANYDATA: # Also Test CLICON_YANG_UNKNOWN_ANYDATA: Treat unknown XML/JSON nodes as anydata. -# Test matric is three dimensions: -# 1. YANG spec: u-elements are a) anydata or b) unknown -# 2. Access is made to top-elements: a) top-level, b) in container, c) in list -# 3. data is in a) startup b) netconf 3)state +# Test matrix is three dimensions: +# 1. YANG spec: Add elements denotend with "u" which are either a) defined as anydata or b) unknown +# 2. Make access to elements as: a) top-level, b) in container, c) in list +# 3. data is in a) startup b) netconf 3) state # Load an XML file with unknown yang constructs that is labelled as anydata # Ensure clixon is robust to handle that @@ -48,6 +48,14 @@ module any{ } anydata u4; } + rpc myrpc { + input { + anydata u7; + } + output { + anydata u8; + } + } } EOF @@ -73,6 +81,8 @@ module unknown{ } } } + rpc myrpc { + } } EOF @@ -81,7 +91,7 @@ XMLA='2242/usr/local/var/$APPNAME/$APPNAME.pidfile $dir false + false $unknown $F @@ -159,6 +175,16 @@ EOF new "waiting" wait_backend fi + if [ $RC -ne 0 ]; then + new "kill old restconf daemon" + stop_restconf_pre + + new "start restconf daemon" + start_restconf -f $cfg + + fi + new "wait restconf" + wait_restconf if ! $startup; then # If not startup, add xml using netconf @@ -185,24 +211,45 @@ EOF new "cli commit" expectpart "$($clixon_cli -1 -f $cfg commit)" 0 "^$" - if $unknown; then - STATE="$STATE0" # full state - else - STATE="$STATE1" # partial state - fi - echo "$STATE" > $fstate + + new "restconf get config" + expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=config)" 0 "HTTP/1.1 200 OK" "$XML" + + # Save partial state in state file with unknown removed (positive test) + echo "$STATE1" > $fstate new "Get state (positive test)" - expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$STATE]]>]]>" + expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$STATE1]]>]]>" - echo "$STATE0" > $fstate # full state + new "restconf get state(positive)" + expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=nonconfig)" 0 "HTTP/1.1 200 OK" "$STATE1" + + # full state with unknowns + echo "$STATE0" > $fstate new "Get state (negative test)" - if $unknown; then - expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$STATE]]>]]>" - else - expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "error-message>Failed to find YANG spec of XML node: u5 with parent: sb in namespace: urn:example:unknown. Internal error, state callback returned invalid XML: example_backend" + expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "error-message>Failed to find YANG spec of XML node: u5 with parent: sb in namespace: urn:example:unknown. Internal error, state callback returned invalid XML: example_backend" + + new "restconf get state(negative)" + expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data?content=nonconfig)" 0 "HTTP/1.1 412 Precondition Failed" "operation-failedu5" + + # RPC:s take "not-supported" as OK: syntax OK and according to mdeol, just not implemented in + # server. But "unknown-element" as truly unknwon. + # (Would need to add a handler to get a proper OK) + new "Not supported RPC" + expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' 'operation-not-supported' + + new "anydata RPC" + expecteof "$clixon_netconf -qf $cfg" 0 '88]]>]]>' 'operation-not-supported' + + new "unknown RPC" + expecteof "$clixon_netconf -qf $cfg" 0 '88]]>]]>' 'unknown-element' + + if [ $RC -ne 0 ]; then + new "Kill restconf daemon" + stop_restconf fi + if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill diff --git a/yang/clixon/clixon-config@2020-06-17.yang b/yang/clixon/clixon-config@2020-06-17.yang index 45025e77..4544e538 100644 --- a/yang/clixon/clixon-config@2020-06-17.yang +++ b/yang/clixon/clixon-config@2020-06-17.yang @@ -334,7 +334,7 @@ module clixon-config { type boolean; default false; description - "Treat unknown XML/JSON nodes as anydata. + "Treat unknown XML/JSON nodes as anydata when loading from startup db. This does not apply to namespaces, which means a top-level node: xxx:yyy is accepted only if yyy is unknown, not xxx"; }