Revised CLICON_YANG_UNKNOWN_ANYDATA patch: dont allow new nodes after initial startup
This commit is contained in:
parent
316cad35ff
commit
36576143b5
3 changed files with 75 additions and 21 deletions
|
|
@ -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){
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
#!/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
|
||||
# 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
|
||||
|
|
@ -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='<ca xmlns="urn:example:any"><b><k>22</k><u3><u31>42</u31></u3></b><u2><u21
|
|||
|
||||
XMLU='<cu xmlns="urn:example:unknown"><b><k>22</k><u3><u31>42</u31></u3></b><u2><u21>a string</u21></u2></cu><u1 xmlns="urn:example:unknown"><u11>23</u11></u1>'
|
||||
|
||||
# Full state
|
||||
# Full state with unknowns
|
||||
STATE0='<sa xmlns="urn:example:any"><sb><k>22</k><u5>55</u5></sb><u4><u5>a string</u5></u4></sa><su xmlns="urn:example:unknown"><sb><k>22</k><u5>55</u5></sb><u4><u5>a string</u5></u4></su>'
|
||||
|
||||
# Partial state with unknowns removed in the unknown module
|
||||
|
|
@ -99,11 +109,16 @@ testrun()
|
|||
unknown=$2
|
||||
|
||||
if $unknown; then # treat unknown as anydata or not
|
||||
unknownreply="<rpc-reply><ok/></rpc-reply>]]>]]>"
|
||||
if $startup; then # If startup
|
||||
XML="$XMLA$XMLU"
|
||||
else
|
||||
unknownreply="<rpc-reply><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>u1</bad-element></error-info><error-severity>error</error-severity><error-message>Unassigned yang spec</error-message></rpc-error></rpc-reply>]]>]]>"
|
||||
XML="$XMLA"
|
||||
unknownreply="<rpc-reply><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>u1</bad-element></error-info><error-severity>error</error-severity><error-message>Unassigned yang spec</error-message></rpc-error></rpc-reply>]]>]]>"
|
||||
fi
|
||||
else
|
||||
XML="$XMLA"
|
||||
unknownreply="<rpc-reply><rpc-error><error-type>application</error-type><error-tag>unknown
|
||||
-element</error-tag><error-info><bad-element>u1</bad-element></error-info><error-severity>error</error-severity><error-message>Unassigned yang spec</error-message></rpc-error></rpc-reply>]]>]]>"
|
||||
fi
|
||||
|
||||
if $startup; then # get config from startup
|
||||
|
|
@ -127,6 +142,7 @@ testrun()
|
|||
<CLICON_BACKEND_PIDFILE>/usr/local/var/$APPNAME/$APPNAME.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>$dir</CLICON_XMLDB_DIR>
|
||||
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
|
||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||
<CLICON_YANG_UNKNOWN_ANYDATA>$unknown</CLICON_YANG_UNKNOWN_ANYDATA>
|
||||
$F
|
||||
</clixon-config>
|
||||
|
|
@ -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 '<rpc><get content="nonconfig"></get></rpc>]]>]]>' "^<rpc-reply><data>$STATE</data></rpc-reply>]]>]]>"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get content="nonconfig"></get></rpc>]]>]]>' "^<rpc-reply><data>$STATE1</data></rpc-reply>]]>]]>"
|
||||
|
||||
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 '<rpc><get content="nonconfig"></get></rpc>]]>]]>' "^<rpc-reply><data>$STATE</data></rpc-reply>]]>]]>"
|
||||
else
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get content="nonconfig"></get></rpc>]]>]]>' "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</error-message>"
|
||||
|
||||
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" "<error-tag>operation-failed</error-tag><error-info><bad-element>u5</bad-element></error-info>"
|
||||
|
||||
# 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 '<rpc><myrpc xmlns="urn:example:any"></myrpc></rpc>]]>]]>' '<error-tag>operation-not-supported</error-tag>'
|
||||
|
||||
new "anydata RPC"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><myrpc xmlns="urn:example:any"><u7><u8>88</u8></u7></myrpc></rpc>]]>]]>' '<error-tag>operation-not-supported</error-tag>'
|
||||
|
||||
new "unknown RPC"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><myrpc xmlns="urn:example:unknown"><u7><u8>88</u8></u7></myrpc></rpc>]]>]]>' '<error-tag>unknown-element</error-tag>'
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
fi
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
# Check if premature kill
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue