Showing syntax using CLI commands was broekn and is fixed.
This commit is contained in:
parent
1913407e52
commit
50522df3d9
6 changed files with 67 additions and 70 deletions
|
|
@ -103,6 +103,7 @@ enables saved files to be used as datastore without any editing. Thanks Matt.
|
||||||
* Added cli_show_version()
|
* Added cli_show_version()
|
||||||
|
|
||||||
### Corrected Bugs
|
### Corrected Bugs
|
||||||
|
* Showing syntax using CLI commands was broekn and is fixed.
|
||||||
* Fixed issue https://github.com/clicon/clixon/issues/18 RPC response issues reported by Stephen Jones at Netgate
|
* Fixed issue https://github.com/clicon/clixon/issues/18 RPC response issues reported by Stephen Jones at Netgate
|
||||||
* Fixed issue https://github.com/clicon/clixon/issues/17 special character in strings can break RPCs reported by David Cornejo at Netgate.
|
* Fixed issue https://github.com/clicon/clixon/issues/17 special character in strings can break RPCs reported by David Cornejo at Netgate.
|
||||||
* This was a large rewright of XML parsing and output due to CharData not correctly encoded according to https://www.w3.org/TR/2008/REC-xml-20081126.
|
* This was a large rewright of XML parsing and output due to CharData not correctly encoded according to https://www.w3.org/TR/2008/REC-xml-20081126.
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@
|
||||||
|
|
||||||
/*! Controls how keywords a generated in CLI syntax / prints from object model
|
/*! Controls how keywords a generated in CLI syntax / prints from object model
|
||||||
* Example YANG:
|
* Example YANG:
|
||||||
* list a {a.b[] $!x $y:
|
|
||||||
* list a {
|
* list a {
|
||||||
* key x;
|
* key x;
|
||||||
* leaf x;
|
* leaf x;
|
||||||
|
|
@ -63,7 +62,7 @@
|
||||||
enum genmodel_type{
|
enum genmodel_type{
|
||||||
GT_ERR =-1, /* Error */
|
GT_ERR =-1, /* Error */
|
||||||
GT_NONE=0, /* No extra keywords */
|
GT_NONE=0, /* No extra keywords */
|
||||||
GT_VARS, /* Keywords on non-index variables */
|
GT_VARS, /* Keywords on non-key variables */
|
||||||
GT_ALL, /* Keywords on all variables */
|
GT_ALL, /* Keywords on all variables */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,19 +89,6 @@
|
||||||
#include "clixon_xml_sort.h"
|
#include "clixon_xml_sort.h"
|
||||||
#include "clixon_xml_map.h"
|
#include "clixon_xml_map.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* A node is a leaf if it contains a body.
|
|
||||||
*/
|
|
||||||
static cxobj *
|
|
||||||
leaf(cxobj *xn)
|
|
||||||
{
|
|
||||||
cxobj *xc = NULL;
|
|
||||||
|
|
||||||
while ((xc = xml_child_each(xn, xc, CX_BODY)) != NULL)
|
|
||||||
break;
|
|
||||||
return xc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! x is element and has eactly one child which in turn has none */
|
/*! x is element and has eactly one child which in turn has none */
|
||||||
static int
|
static int
|
||||||
tleaf(cxobj *x)
|
tleaf(cxobj *x)
|
||||||
|
|
@ -118,6 +105,7 @@ tleaf(cxobj *x)
|
||||||
|
|
||||||
/*! Translate XML -> TEXT
|
/*! Translate XML -> TEXT
|
||||||
* @param[in] level print 4 spaces per level in front of each line
|
* @param[in] level print 4 spaces per level in front of each line
|
||||||
|
* XXX rewrite using YANG and remove encrypted password KLUDGE
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xml2txt(FILE *f,
|
xml2txt(FILE *f,
|
||||||
|
|
@ -184,69 +172,60 @@ xml2cli(FILE *f,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xe = NULL;
|
cxobj *xe = NULL;
|
||||||
char *term;
|
cbuf *cbpre = NULL;
|
||||||
int bool;
|
yang_stmt *ys;
|
||||||
int nr;
|
int match;
|
||||||
int i;
|
char *body;
|
||||||
cbuf *cbpre;
|
|
||||||
// yang_stmt *ys;
|
|
||||||
|
|
||||||
// ys = yang_spec(x);
|
ys = xml_spec(x);
|
||||||
|
if (ys->ys_keyword == Y_LEAF || ys->ys_keyword == Y_LEAF_LIST){
|
||||||
|
if (prepend0)
|
||||||
|
fprintf(f, "%s", prepend0);
|
||||||
|
body = xml_body(x);
|
||||||
|
if (gt == GT_ALL || gt == GT_VARS)
|
||||||
|
fprintf(f, "%s ", xml_name(x));
|
||||||
|
if (index(body, ' '))
|
||||||
|
fprintf(f, "\"%s\"", body);
|
||||||
|
else
|
||||||
|
fprintf(f, "%s", body);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
goto ok;
|
||||||
|
}
|
||||||
/* Create prepend variable string */
|
/* Create prepend variable string */
|
||||||
if ((cbpre = cbuf_new()) == NULL){
|
if ((cbpre = cbuf_new()) == NULL){
|
||||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
nr = xml_child_nr(x);
|
|
||||||
if (!nr){
|
|
||||||
if (xml_type(x) == CX_BODY)
|
|
||||||
term = xml_value(x);
|
|
||||||
else
|
|
||||||
term = xml_name(x);
|
|
||||||
if (prepend0)
|
|
||||||
fprintf(f, "%s ", prepend0);
|
|
||||||
if (index(term, ' '))
|
|
||||||
fprintf(f, "\"%s\"\n", term);
|
|
||||||
else
|
|
||||||
fprintf(f, "%s\n", term);
|
|
||||||
retval = 0;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
if (prepend0)
|
if (prepend0)
|
||||||
cprintf(cbpre, "%s", prepend0);
|
cprintf(cbpre, "%s", prepend0);
|
||||||
/* bool determines when to print a variable keyword:
|
cprintf(cbpre, "%s ", xml_name(x));
|
||||||
!leaf T for all (ie parameter)
|
|
||||||
index GT_NONE F
|
if (ys->ys_keyword == Y_LIST){
|
||||||
index GT_VARS F
|
/* If list then first loop through keys */
|
||||||
index GT_ALL T
|
xe = NULL;
|
||||||
!index GT_NONE F
|
while ((xe = xml_child_each(x, xe, -1)) != NULL){
|
||||||
!index GT_VARS T
|
if ((match = yang_key_match((yang_node*)ys, xml_name(xe))) < 0)
|
||||||
!index GT_ALL T
|
|
||||||
*/
|
|
||||||
bool = !leaf(x) || gt == GT_ALL || (gt == GT_VARS);
|
|
||||||
// bool = (!x->xn_index || gt == GT_ALL);
|
|
||||||
if (bool){
|
|
||||||
if (cbuf_len(cbpre))
|
|
||||||
cprintf(cbpre, " ");
|
|
||||||
cprintf(cbpre, "%s", xml_name(x));
|
|
||||||
}
|
|
||||||
xe = NULL;
|
|
||||||
/* First child is unique, then add that, before looping. */
|
|
||||||
i = 0;
|
|
||||||
while ((xe = xml_child_each(x, xe, -1)) != NULL){
|
|
||||||
/* Dont call this if it is index and there are other following */
|
|
||||||
if (0 && i < nr-1)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
if (xml2cli(f, xe, cbuf_get(cbpre), gt) < 0)
|
|
||||||
goto done;
|
goto done;
|
||||||
if (0){ /* assume index is first, otherwise need one more while */
|
if (!match)
|
||||||
|
continue;
|
||||||
if (gt == GT_ALL)
|
if (gt == GT_ALL)
|
||||||
cprintf(cbpre, " %s", xml_name(xe));
|
cprintf(cbpre, "%s ", xml_name(xe));
|
||||||
cprintf(cbpre, " %s", xml_value(xml_child_i(xe, 0)));
|
cprintf(cbpre, "%s ", xml_body(xe));
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
/* Then loop through all other (non-keys) */
|
||||||
|
xe = NULL;
|
||||||
|
while ((xe = xml_child_each(x, xe, -1)) != NULL){
|
||||||
|
if (ys->ys_keyword == Y_LIST){
|
||||||
|
if ((match = yang_key_match((yang_node*)ys, xml_name(xe))) < 0)
|
||||||
|
goto done;
|
||||||
|
if (match)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (xml2cli(f, xe, cbuf_get(cbpre), gt) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ok:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cbpre)
|
if (cbpre)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ new "cli configure"
|
||||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0" "^$"
|
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0" "^$"
|
||||||
|
|
||||||
new "cli show configuration"
|
new "cli show configuration"
|
||||||
expectfn "$clixon_cli -1 -f $cfg show conf cli" "^interfaces interface name eth/0/0" "interfaces interface enabled true$"
|
expectfn "$clixon_cli -1 -f $cfg show conf cli" "^interfaces interface eth/0/0 enabled true"
|
||||||
|
|
||||||
new "cli configure using encoded chars data <&"
|
new "cli configure using encoded chars data <&"
|
||||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 description \"foo<&bar\"" ""
|
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 description \"foo<&bar\"" ""
|
||||||
|
|
@ -101,7 +101,8 @@ new "cli load"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -l o load /tmp/foo" "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o load /tmp/foo" "^$"
|
||||||
|
|
||||||
new "cli check load"
|
new "cli check load"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -l o show conf cli" "^interfaces interface name eth/0/0" "interfaces interface enabled true$"
|
expectfn "$clixon_cli -1 -f $cfg -l o show conf cli" "^interfaces interface name eth/0/0 type bgp
|
||||||
|
interfaces interface eth/0/0 ipv4 enabled true"
|
||||||
|
|
||||||
new "cli debug"
|
new "cli debug"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -l o debug level 1" "^$"
|
expectfn "$clixon_cli -1 -f $cfg -l o debug level 1" "^$"
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,8 @@ new "netconf get replaced config"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth& </name><type>t< > </type><enabled>true</enabled></interface><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth& </name><type>t< > </type><enabled>true</enabled></interface><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||||
|
|
||||||
new "cli show configuration eth& - encoding tests"
|
new "cli show configuration eth& - encoding tests"
|
||||||
expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" "interfaces interface name eth&"
|
expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" "interfaces interface eth& type t<>
|
||||||
|
interfaces interface eth& enabled true"
|
||||||
|
|
||||||
new "netconf discard-changes"
|
new "netconf discard-changes"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,22 @@ module clixon-config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
typedef cli_genmodel_type{
|
||||||
|
description
|
||||||
|
"How to generate CLI from YANG model,
|
||||||
|
eg list a{ key x; leaf x; leaf y;}";
|
||||||
|
type enumeration{
|
||||||
|
enum NONE{
|
||||||
|
description "No extra keywords: a <x> <y>";
|
||||||
|
}
|
||||||
|
enum VARS{
|
||||||
|
description "Keywords on non-key variables: a <x> y <y>";
|
||||||
|
}
|
||||||
|
enum ALL{
|
||||||
|
description "Keywords on all variables: a x <x> y <y>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
typedef nacm_mode{
|
typedef nacm_mode{
|
||||||
description
|
description
|
||||||
"Mode of RFC8341 Network Configuration Access Control Model.
|
"Mode of RFC8341 Network Configuration Access Control Model.
|
||||||
|
|
@ -204,7 +220,7 @@ module clixon-config {
|
||||||
description "Generate code for CLI completion of existing db symbols";
|
description "Generate code for CLI completion of existing db symbols";
|
||||||
}
|
}
|
||||||
leaf CLICON_CLI_GENMODEL_TYPE {
|
leaf CLICON_CLI_GENMODEL_TYPE {
|
||||||
type string;
|
type cli_genmodel_type;
|
||||||
default "VARS";
|
default "VARS";
|
||||||
description "How to generate and show CLI syntax: VARS|ALL";
|
description "How to generate and show CLI syntax: VARS|ALL";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue