diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dbd79e7..9282b663 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Clixon Changelog +* [4.9.0](#490) Expected 15 December 2020 * [4.8.0](#480) 18 October 2020 * [4.7.0](#470) 14 September 2020 * [4.6.0](#460) 14 August 2020 @@ -24,6 +25,8 @@ * [3.3.2](#332) Aug 27 2017 * [3.3.1](#331) June 7 2017 +## 4.9.0 Expected: 15 Dec 2020 + ## 4.8.0 18 October 2020 diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index bd50abc9..9645ebd2 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -1596,7 +1596,7 @@ from_client_msg(clicon_handle h, enum nacm_credentials_t creds; char *rpcname; char *rpcprefix; - char *namespace; + char *namespace = NULL; clicon_debug(1, "%s", __FUNCTION__); yspec = clicon_dbspec_yang(h); @@ -1636,16 +1636,17 @@ from_client_msg(clicon_handle h, } rpcname = xml_name(x); rpcprefix = xml_prefix(x); - if (0) { /* XXX notyet (4.8) restconf seems not to produce right namespace */ - if (xml2ns(x, rpcprefix, &namespace) < 0) + /* Note that this validation is also made in xml_yang_validate_rpc, but not for hello + */ + if (xml2ns(x, rpcprefix, &namespace) < 0) + goto done; + /* Only accept resolved NETCONF base namespace */ + if (namespace == NULL || strcmp(namespace, NETCONF_BASE_NAMESPACE) != 0){ + if (netconf_unknown_namespace(cbret, "protocol", rpcprefix, "No appropriate namespace associated with prefix") < 0) goto done; - /* Only accept resolved NETCONF base namespace */ - if (namespace == NULL || strcmp(namespace, NETCONF_BASE_NAMESPACE) != 0){ - if (netconf_unknown_namespace(cbret, "protocol", rpcprefix, "No appropriate namespace associated with prefix")< 0) - goto done; - goto reply; - } + goto reply; } + if (strcmp(rpcname, "rpc") == 0){ ; /* continue below */ } diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 05590aec..e053b62b 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -477,16 +477,6 @@ from_validate_common(clicon_handle h, /* Clear flags xpath for get */ xml_apply0(td->td_target, CX_ELMNT, (xml_applyfn_t*)xml_flag_reset, (void*)(XML_FLAG_MARK|XML_FLAG_CHANGE)); - /* Validate the target state. It is not completely clear this should be done - * here. It is being made in generic_validate below. - * But xml_diff requires some basic validation, at least check that yang-specs - * have been assigned - */ - if ((ret = xml_yang_validate_all_top(h, td->td_target, xret)) < 0) - goto done; - if (ret == 0) - goto fail; - /* 2. Parse xml trees * This is the state we are going from */ if (xmldb_get0(h, "running", YB_MODULE, NULL, "/", 0, &td->td_src, NULL) < 0) diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index ca66f8bc..b51a9262 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -756,7 +756,6 @@ api_operations_post(clicon_handle h, cxobj *xbot = NULL; yang_stmt *y = NULL; cxobj *xoutput = NULL; - cxobj *xa; cxobj *xe; char *username; cbuf *cbret = NULL; @@ -822,17 +821,18 @@ api_operations_post(clicon_handle h, /* 3. Build xml tree with user and rpc: * */ - if ((xtop = xml_new("rpc", NULL, CX_ELMNT)) == NULL) + if ((username = clicon_username_get(h)) != NULL){ + if (clixon_xml_parse_va(YB_NONE, NULL, &xtop, NULL, "", + NETCONF_BASE_NAMESPACE, username) < 0) + goto done; + } + else + if (clixon_xml_parse_va(YB_NONE, NULL, &xtop, NULL, "", + NETCONF_BASE_NAMESPACE) < 0) + goto done; + if (xml_rootchild(xtop, 0, &xtop) < 0) goto done; xbot = xtop; - /* Here xtop is: */ - if ((username = clicon_username_get(h)) != NULL){ - if ((xa = xml_new("username", xtop, CX_ATTR)) == NULL) - goto done; - if (xml_value_set(xa, username) < 0) - goto done; - /* Here xtop is: */ - } if ((ret = api_path2xml(oppath, yspec, xtop, YC_SCHEMANODE, 1, &xbot, &y, &xerr)) < 0) goto done; if (ret == 0){ /* validation failed */ diff --git a/configure b/configure index 4a329c83..d9dd594a 100755 --- a/configure +++ b/configure @@ -2257,9 +2257,9 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. CLIXON_VERSION_MAJOR="4" -CLIXON_VERSION_MINOR="8" +CLIXON_VERSION_MINOR="9" CLIXON_VERSION_PATCH="0" -CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" +CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\"" # Check CLIgen if test "$prefix" = "NONE"; then diff --git a/configure.ac b/configure.ac index f6e96277..d5022394 100644 --- a/configure.ac +++ b/configure.ac @@ -48,9 +48,9 @@ AC_INIT(lib/clixon/clixon.h.in) AC_CONFIG_AUX_DIR(aux) CLIXON_VERSION_MAJOR="4" -CLIXON_VERSION_MINOR="8" +CLIXON_VERSION_MINOR="9" CLIXON_VERSION_PATCH="0" -CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}\"" +CLIXON_VERSION="\"${CLIXON_VERSION_MAJOR}.${CLIXON_VERSION_MINOR}.${CLIXON_VERSION_PATCH}.PRE\"" # Check CLIgen if test "$prefix" = "NONE"; then diff --git a/example/main/example_cli.cli b/example/main/example_cli.cli index 84fddcc2..3658e5a8 100644 --- a/example/main/example_cli.cli +++ b/example/main/example_cli.cli @@ -72,15 +72,15 @@ show("Show a particular state of the system"){ xml("Show comparison in xml"), compare_dbs((int32)0); text("Show comparison in text"), compare_dbs((int32)1); } - configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", false, false);{ - xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", false, false); - cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", false, false, "set "); - netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", false, false); - text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", false, false); - json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", false, false); + configuration("Show configuration"), cli_auto_show("datamodel", "candidate", "text", true, false);{ + xml("Show configuration as XML"), cli_auto_show("datamodel", "candidate", "xml", true, false); + cli("Show configuration as CLI commands"), cli_auto_show("datamodel", "candidate", "cli", true, false, "set "); + netconf("Show configuration as netconf edit-config operation"), cli_auto_show("datamodel", "candidate", "netconf", true, false); + text("Show configuration as text"), cli_auto_show("datamodel", "candidate", "text", true, false); + json("Show configuration as JSON"), cli_auto_show("datamodel", "candidate", "json", true, false); } - state("Show configuration and state"), cli_auto_show("datamodel", "running", "text", false, true); { - xml("Show configuration and state as XML"), cli_auto_show("datamodel", "running", "xml", false, true); + state("Show configuration and state"), cli_auto_show("datamodel", "running", "text", true, true); { + xml("Show configuration and state as XML"), cli_auto_show("datamodel", "running", "xml", true, true); } } diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index abf1f703..ee4c7586 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -330,11 +330,25 @@ xml_yang_validate_rpc(clicon_handle h, int retval = -1; yang_stmt *yn=NULL; /* rpc name */ cxobj *xn; /* rpc name */ + char *rpcprefix; + char *namespace = NULL; if (strcmp(xml_name(xrpc), "rpc")){ clicon_err(OE_XML, EINVAL, "Expected RPC"); goto done; } + rpcprefix = xml_prefix(xrpc); + if (xml2ns(xrpc, rpcprefix, &namespace) < 0){ + fprintf(stderr, "%s ERROR\n", __FUNCTION__); + goto done; + } + /* Only accept resolved NETCONF base namespace */ + if (namespace == NULL || strcmp(namespace, NETCONF_BASE_NAMESPACE) != 0){ + fprintf(stderr, "%s UNKNOWN\n", __FUNCTION__); + if (netconf_unknown_namespace_xml(xret, "protocol", rpcprefix, "No appropriate namespace associated with prefix")< 0) + goto done; + goto fail; + } xn = NULL; /* xn is name of rpc, ie */ while ((xn = xml_child_each(xrpc, xn, CX_ELMNT)) != NULL) { diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 220bb3bc..1f6df27c 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -159,7 +159,7 @@ xml2txt_recurse(FILE *f, (*fn)(f, "%s;\n", xml_value(x)); break; case CX_ELMNT: - (*fn)(f, "%*s;\n", 4*level, xml_name(x)); + (*fn)(f, "%*s%s;\n", 4*level, "", xml_name(x)); break; default: break; diff --git a/test/test_perf_state.sh b/test/test_perf_state.sh index 16478f85..020353d6 100755 --- a/test/test_perf_state.sh +++ b/test/test_perf_state.sh @@ -166,7 +166,7 @@ edit interfaces a foo b interface e1 show state xml EOF new "cli get test single req" -expectpart "$($clixon_cli -F $fin -f $cfg)" 0 "e1ex:ethtrueup$" +expectpart "$($clixon_cli -F $fin -f $cfg)" 0 "e1" "ex:eth" "true" "up$" new "cli get $perfreq single reqs" { time -p for (( i=0; i<$perfreq; i++ )); do