#!/usr/bin/env bash # Test for RFC8528 YANG Schema Mount + NACM RFC 8341 # clixon-example is top-level, mounts clixon-mount1 # The example extends the main example using -- -m -M for both backend and cli # Extensive testing of mounted augment/uses: see fyang0 which includes fyang1+fyang2 # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi APPNAME=example cfg=$dir/nacm_mount.xml clispec=$dir/automode.cli fyang=$dir/clixon-example.yang fyang0=$dir/clixon-mount0.yang # Common NACM scripts . ./nacm.sh CFD=$dir/conf.d test -d $CFD || mkdir -p $CFD RESTCONFIG=$(restconf_config user false) if [ $? -ne 0 ]; then err1 "Error when generating certs" fi cat < $cfg $cfg $CFD ${YANG_INSTALLDIR} ${dir} $fyang true $dir /usr/local/lib/$APPNAME/restconf /usr/local/lib/$APPNAME/cli $APPNAME /usr/local/var/run/$APPNAME.sock /usr/local/lib/$APPNAME/backend /usr/local/var/run/$APPNAME.pidfile $dir true true true true internal none true EOF cat < $CFD/autocli.xml false kw-nokey true include clixon enable clixon-* EOF cat < $CFD/restconf.xml $RESTCONFIG EOF cat < $fyang module clixon-example{ yang-version 1.1; namespace "urn:example:clixon"; prefix ex; import ietf-yang-schema-mount { prefix yangmnt; } import ietf-netconf-acm { prefix nacm; } container top{ list mylist{ key name; leaf name{ type string; } container mnt { presence "Otherwise root is not visible"; yangmnt:mount-point "mylabel"{ description "Root for other yang models"; } } } } } EOF cat < $fyang0 module clixon-mount0{ yang-version 1.1; namespace "urn:example:mount0"; prefix m0; container mymount0{ list mylist0{ key name0; leaf name0{ type string; } } list mylist1{ key name1; leaf name1{ type string; } } } } EOF cat < $clispec CLICON_MODE="example"; CLICON_PROMPT="%U@%H %W> "; CLICON_PLUGIN="example_cli"; # Autocli syntax tree operations set @datamodel, cli_auto_set(); merge @datamodel, cli_auto_merge(); create @datamodel, cli_auto_create(); delete("Delete a configuration item") @datamodel, cli_auto_del(); validate("Validate changes"), cli_validate(); commit("Commit the changes"), cli_commit(); quit("Quit"), cli_quit(); show("Show a particular state of the system"){ configuration("Show configuration"), cli_show_auto_mode("candidate", "xml", true, false);{ xml("Show configuration as XML"), cli_show_auto_mode("candidate", "xml", false, false); cli("Show configuration as CLI commands"), cli_show_auto_mode("candidate", "cli", false, false, "report-all", "set "); netconf("Show configuration as netconf edit-config operation"), cli_show_auto_mode("candidate", "netconf", false, false); text("Show configuration as text"), cli_show_auto_mode("candidate", "text", false, false); json("Show configuration as JSON"), cli_show_auto_mode("candidate", "json", false, false); } state("Show configuration and state"), cli_show_auto_mode("running", "xml", false, true); } EOF # The groups are slightly modified from RFC8341 A.1 ($USER added in admin group) # The rule-list is from A.4 # Note read-default is set to permit to ensure that deny-nacm is meaningful RULES=$(cat < false deny deny deny $NGROUPS $NADMIN limited permit limited permit get /ex:top/ex:mylist/ex:mnt/m0:mymount0/m0:mylist0 * permit Allow the 'limited' group full access to mylist0. permit exec * exec permit Allow invocation of the supported server operations. EOF ) # /ex:top/ex:mylist/ex:mnt/m0:mymount0/m0:mylist0 new "test params: -f $cfg" if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -zf $cfg if [ $? -ne 0 ]; then err fi new "start backend -s init -f $cfg -- -m clixon-mount0 -M urn:example:mount0" start_backend -s init -f $cfg -- -m clixon-mount0 -M urn:example:mount0 fi new "wait backend" wait_backend if [ $RC -ne 0 ]; then new "kill old restconf daemon" stop_restconf_pre new "start restconf daemon" start_restconf -f $cfg -- -m clixon-mount0 -M urn:example:mount0 fi new "wait restconf" wait_restconf new "Add mountpoint: x" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "x" "" "" new "netconf commit" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "" new "auth set authentication config" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "$RULES" "" "" new "Add data to mounts" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "xx0x1" "" "" new "Enable nacm" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "true" "" "" new "netconf commit" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "" "" new "get netconf data" expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "" "xx0x1" new "restconf admin read mnt ok" expectpart "$(curl -u andy:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt)" 0 "HTTP/$HVER 200" 'x0x1mylabelclixon-mount0urn:example:mount0' new "restconf limit read mnt ok" expectpart "$(curl -u wilma:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt)" 0 "HTTP/$HVER 200" 'x0' new "restconf guest read mnt access denied" expectpart "$(curl -u guest:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt)" 0 "HTTP/$HVER 403" 'applicationaccess-deniederrordefault deny' new "restconf admin read mnt mylist0 expect ok" expectpart "$(curl -u andy:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0/mylist0=x0)" 0 "HTTP/$HVER 200" 'x0' new "restconf admin read mnt mylist1 expect ok" expectpart "$(curl -u andy:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0/mylist1=x1)" 0 "HTTP/$HVER 200" 'x1' new "restconf limit read mnt mylist0 expect ok" expectpart "$(curl -u wilma:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0/mylist0=x0)" 0 "HTTP/$HVER 200" 'x0' new "restconf limit read mnt mylist0 expect fail" expectpart "$(curl -u wilma:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0/mylist1=x1)" 0 "HTTP/$HVER 404" 'applicationinvalid-valueerrorInstance does not exist' new "restconf guest read mnt mylist0 expect access denied" expectpart "$(curl -u guest:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0/mylist1=x1)" 0 "HTTP/$HVER 403" 'applicationaccess-deniederrordefault deny' # write new "restconf admin write mnt mylist0 expect ok" expectpart "$(curl -u andy:bar $CURLOPTS -X POST -H "Content-Type: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0 -d 'andy')" 0 "HTTP/$HVER 201" new "restconf admin write mnt mylist1 expect ok" expectpart "$(curl -u andy:bar $CURLOPTS -X POST -H "Content-Type: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0 -d 'andy')" 0 "HTTP/$HVER 201" new "restconf limited write mnt mylist0 expect ok" expectpart "$(curl -u wilma:bar $CURLOPTS -X POST -H "Content-Type: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0 -d 'wilma')" 0 "HTTP/$HVER 201" new "restconf limited write mnt mylist1 expect fail" expectpart "$(curl -u wilma:bar $CURLOPTS -X POST -H "Content-Type: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0 -d 'wilma')" 0 "HTTP/$HVER 403" "access-denied" new "restconf guest write mnt mylist0 expect fail" expectpart "$(curl -u guest:bar $CURLOPTS -X POST -H "Content-Type: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0 -d 'guest')" 0 "HTTP/$HVER 403" "access-denied" new "restconf admin get check" expectpart "$(curl -u andy:bar $CURLOPTS -X GET -H "Accept: application/yang-data+xml" $RCPROTO://localhost/restconf/data/clixon-example:top/mylist=x/mnt/clixon-mount0:mymount0)" 0 "HTTP/$HVER 200" 'andy' 'wilma' 'andy' --not-- 'wilma' 'guest' if [ $RC -ne 0 ]; then new "Kill restconf daemon" stop_restconf fi if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill pid=$(pgrep -u root -f clixon_backend) if [ -z "$pid" ]; then err "backend already dead" fi # kill backend stop_backend -f $cfg fi rm -rf $dir new "endtest" endtest