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/docker/main/Makefile.in b/docker/main/Makefile.in index b10050f8..b9c2a45f 100644 --- a/docker/main/Makefile.in +++ b/docker/main/Makefile.in @@ -75,7 +75,7 @@ push: # Note tests will kill the daemons started in the start scrips test: docker ./cleanup.sh ; PORT=8080 ./start.sh # kill (ignore error) and the start it - sudo docker exec -it clixon-system bash -c 'cd /usr/local/bin/test && ./all.sh' + sudo docker exec -t clixon-system bash -c 'cd /usr/local/bin/test && ./all.sh' depend: diff --git a/test/cicd/Makefile.in b/test/cicd/Makefile.in index 16a63d1a..251390f6 100644 --- a/test/cicd/Makefile.in +++ b/test/cicd/Makefile.in @@ -40,6 +40,7 @@ SHELL = /bin/sh .PHONY: all clean distclean depend install uninstall +# Optional specific LOGDIR, eg "LOGDIR=/var/log make" # Include "site.mk" file if it exists and define the HOSTS variables # eg : @@ -54,7 +55,11 @@ all: $(HOSTS) # Real hosts reachable by ssh $(HOSTS): - ./cicd.sh $@ 2>&1 | tee $@.log +ifdef LOGDIR + ./cicd.sh $@ 2>&1 > $(LOGDIR)/$@.log +else + ./cicd.sh $@ 2>&1 | tee /$@.log +endif clean: rm -f *.log 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/test/vagrant/Makefile.in b/test/vagrant/Makefile.in index bcee54ee..a4bc11a5 100644 --- a/test/vagrant/Makefile.in +++ b/test/vagrant/Makefile.in @@ -40,6 +40,7 @@ SHELL = /bin/sh .PHONY: all clean distclean depend install uninstall +# Optional specific LOGDIR, eg "LOGDIR=/var/log make" # The "site.mk" file if it exists and define the VAGRANTS variables # eg: @@ -59,7 +60,11 @@ logs: # Local vagrant hosts eg generic/centos8. The vagrantdir is a subdirectory and logs will # appear eg as generic/centos8.log $(VAGRANTS): logs +ifdef LOGDIR + ./vagrant.sh $@ 2>&1 > "$(LOGDIR)/$(subst /,-,$@).log" +else ./vagrant.sh $@ 2>&1 | tee "logs/$(subst /,-,$@).log" +endif destroy: for i in $(VAGRANTS) ; \ diff --git a/test/vagrant/vagrant.sh b/test/vagrant/vagrant.sh index a9d18196..1df31a36 100755 --- a/test/vagrant/vagrant.sh +++ b/test/vagrant/vagrant.sh @@ -96,6 +96,7 @@ system=$($sshcmd uname) # we use the release "hack" instead # Some release have packages, some need to be built from source buildfcgi=false buildevhtp=false +buildcmake=false # Some releases (eg centos/7) has too old cmake to build libevhtp case $release in openbsd) # packages for building @@ -154,7 +155,8 @@ case $release in evhtp) $sshcmd sudo yum install -y libevent openssl buildevhtp=true - $sshcmd sudo yum install -y libevent-devel cmake openssl-devel + buildcmake=true # Actually, only necessary on centos/7 + $sshcmd sudo yum install -y libevent-devel openssl-devel ;; esac ;; @@ -249,11 +251,28 @@ case ${with_restconf} in . ./nginx.sh $dir $idfile $port $wwwuser ;; evhtp) + if $buildcmake; then + $sshcmd "test -d cmake || sudo git clone https://gitlab.kitware.com/cmake/cmake.git" + $sshcmd "(cd cmake; sudo ./bootstrap)" + $sshcmd "(cd cmake; sudo make)" + $sshcmd "(cd cmake; sudo make install)" + fi if $buildevhtp; then - $sshcmd "test -d libevhtp || sudo git clone https://github.com/criticalstack/libevhtp.git" - $sshcmd "(cd libevhtp/build; sudo cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON ..)" - $sshcmd "(cd libevhtp/build; sudo make)" - $sshcmd "(cd libevhtp/build; sudo make install)" + if true; then + $sshcmd << 'EOF' + test -d libevhtp || sudo git clone https://github.com/criticalstack/libevhtp.git + cd libevhtp/build; + CMAKE=$(which cmake) + sudo $CMAKE -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON .. + sudo make + sudo make install +EOF + else + $sshcmd "test -d libevhtp || sudo git clone https://github.com/criticalstack/libevhtp.git" + $sshcmd "(cd libevhtp/build; sudo /usr/local/bin/cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON ..)" + $sshcmd "(cd libevhtp/build; sudo make)" + $sshcmd "(cd libevhtp/build; sudo make install)" + fi fi ;; esac 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"; }