* Date-and-time type now properly uses ISO 8601 UTC timezone designators.

* Renamed yang file `ietf-netconf-notification@2008-07-01.yang` to `clixon-rfc5277`.
* Cligen uses posix regex while yang uses XSD. It differs in some aspects. A translator function has been added for `\d` -> `[0-9]` translation, there may be more.
* [ietf-netconf-notification@2008-07-01.yang validation problem #62](https://github.com/clicon/clixon/issues/62)
This commit is contained in:
Olof hagsand 2019-01-11 17:30:08 +01:00
parent 207858e20d
commit f48c8f45c6
16 changed files with 105 additions and 63 deletions

View file

@ -85,6 +85,12 @@
* Any config option from file can be overrided by giving them on command-line. * Any config option from file can be overrided by giving them on command-line.
### API changes on existing features (you may need to change your code) ### API changes on existing features (you may need to change your code)
* Date-and-time type now properly uses ISO 8601 UTC timezone designators.
* Eg 2008-09-21T18:57:21.003456 is changed to 2008-09-21T18:57:21.003456Z
* Renamed yang file `ietf-netconf-notification@2008-07-01.yang` to `clixon-rfc5277`.
* Fixed validation problems, see [https://github.com/clicon/clixon/issues/62]
* Name confusion, the file is manually constructed from the rfc.
* Changed prefix to `ncevent`
* Stricter YANG choice validation leads to enforcement of structures like: `choice c{ mandatory true; leaf x` statements. `x` was not previously enforced. * Stricter YANG choice validation leads to enforcement of structures like: `choice c{ mandatory true; leaf x` statements. `x` was not previously enforced.
* Many hand-crafted validation messages have been removed and replaced with generic validations, which may lead to changed rpc-error messages. * Many hand-crafted validation messages have been removed and replaced with generic validations, which may lead to changed rpc-error messages.
* CLICON_XML_SORT option (in clixon-config.yang) has been removed and set to true permanently. Unsorted XML lists leads to slower performance and old obsolete code can be removed. * CLICON_XML_SORT option (in clixon-config.yang) has been removed and set to true permanently. Unsorted XML lists leads to slower performance and old obsolete code can be removed.
@ -101,6 +107,7 @@
* For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h * For backward compatibility, define CLICON_CLI_MODEL_TREENAME_PATCH in clixon_custom.h
### Minor changes ### Minor changes
* Cligen uses posix regex while yang uses XSD. It differs in some aspects. A translator function has been added for `\d` -> `[0-9]` translation, there may be more.
* Added new clixon-lib yang module for internal netconf protocol. Currently only extends the standard with a debug RPC. * Added new clixon-lib yang module for internal netconf protocol. Currently only extends the standard with a debug RPC.
* Added three-valued return values for several validate functions where -1 is fatal error, 0 is validation failed and 1 is validation OK. * Added three-valued return values for several validate functions where -1 is fatal error, 0 is validation failed and 1 is validation OK.
* This includes: `xmldb_put`, `xml_yang_validate_all`, `xml_yang_validate_add`, `xml_yang_validate_rpc`, `api_path2xml`, `api_path2xpath` * This includes: `xmldb_put`, `xml_yang_validate_all`, `xml_yang_validate_add`, `xml_yang_validate_rpc`, `api_path2xml`, `api_path2xpath`
@ -118,6 +125,7 @@
* <!DOCTYPE (ie DTD) is not supported. * <!DOCTYPE (ie DTD) is not supported.
### Corrected Bugs ### Corrected Bugs
* [ietf-netconf-notification@2008-07-01.yang validation problem #62](https://github.com/clicon/clixon/issues/62)
* Ignore CR(\r) in yang files for DOS files * Ignore CR(\r) in yang files for DOS files
* Keyword "min" (not only "max") can be used in built-in types "range" and "length" statements. * Keyword "min" (not only "max") can be used in built-in types "range" and "length" statements.
* Support for empty yang string added, eg `default "";` * Support for empty yang string added, eg `default "";`

View file

@ -310,7 +310,7 @@ client_statedata(clicon_handle h,
goto done; goto done;
} }
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277")) if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277"))
if ((retval = client_get_streams(h, yspec, xpath, "ietf-netconf-notification", "netconf", xret)) != 0) if ((retval = client_get_streams(h, yspec, xpath, "clixon-rfc5277", "netconf", xret)) != 0)
goto done; goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040")) if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC8040"))
if ((retval = client_get_streams(h, yspec, xpath, "ietf-restconf-monitoring", "restconf-state", xret)) != 0) if ((retval = client_get_streams(h, yspec, xpath, "ietf-restconf-monitoring", "restconf-state", xret)) != 0)

View file

@ -830,7 +830,7 @@ main(int argc,
goto done; goto done;
/* Load yang Netconf stream discovery */ /* Load yang Netconf stream discovery */
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") && if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0) yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done; goto done;
/* Set options: database dir and yangspec (could be hidden in connect?)*/ /* Set options: database dir and yangspec (could be hidden in connect?)*/
if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0) if (xmldb_setopt(h, "dbdir", clicon_xmldb_dir(h)) < 0)

View file

@ -278,8 +278,14 @@ yang2cli_var_sub(clicon_handle h,
} }
} }
} }
if (options & YANG_OPTIONS_PATTERN) if (options & YANG_OPTIONS_PATTERN){
cprintf(cb, " regexp:\"%s\"", pattern); char *posix = NULL;
if (regexp_xsd2posix(pattern, &posix) < 0)
goto done;
cprintf(cb, " regexp:\"%s\"", posix);
if (posix)
free(posix);
}
cprintf(cb, ">"); cprintf(cb, ">");
if (helptext) if (helptext)
cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "(\"%s\")", helptext);
@ -329,7 +335,7 @@ yang2cli_var_union_one(clicon_handle h,
goto done; goto done;
} }
else { else {
if (clicon_type2cv(origtype, restype, &cvtype) < 0) if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
goto done; goto done;
if ((retval = yang2cli_var_sub(h, ys, ytype, cb, helptext, cvtype, if ((retval = yang2cli_var_sub(h, ys, ytype, cb, helptext, cvtype,
options, cvv, pattern, fraction_digits)) < 0) options, cvv, pattern, fraction_digits)) < 0)
@ -417,7 +423,7 @@ yang2cli_var(clicon_handle h,
retval = 0; retval = 0;
goto done; goto done;
} }
if (clicon_type2cv(origtype, restype, &cvtype) < 0) if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
goto done; goto done;
/* Note restype can be NULL here for example with unresolved hardcoded uuid */ /* Note restype can be NULL here for example with unresolved hardcoded uuid */
if (restype && strcmp(restype, "union") == 0){ if (restype && strcmp(restype, "union") == 0){

View file

@ -666,7 +666,7 @@ main(int argc,
yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0) yang_spec_parse_module(h, "ietf-restconf-monitoring", NULL, yspec)< 0)
goto done; goto done;
if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") && if (clicon_option_bool(h, "CLICON_STREAM_DISCOVERY_RFC5277") &&
yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0) yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done; goto done;
/* Call start function in all plugins before we go interactive /* Call start function in all plugins before we go interactive
Pass all args after the standard options to plugin_start Pass all args after the standard options to plugin_start

View file

@ -88,6 +88,7 @@ const char *clicon_int2str(const map_str2int *mstab, int i);
int clicon_str2int(const map_str2int *mstab, char *str); int clicon_str2int(const map_str2int *mstab, char *str);
int nodeid_split(char *nodeid, char **prefix, char **id); int nodeid_split(char *nodeid, char **prefix, char **id);
char *clixon_trim(char *str); char *clixon_trim(char *str);
int regexp_xsd2posix(char *xsd, char **posix);
#ifndef HAVE_STRNDUP #ifndef HAVE_STRNDUP
char *clicon_strndup (const char *, size_t); char *clicon_strndup (const char *, size_t);
#endif /* ! HAVE_STRNDUP */ #endif /* ! HAVE_STRNDUP */

View file

@ -67,7 +67,7 @@ int yang2cv_type(char *ytype, enum cv_type *cv_type);
char *cv2yang_type(enum cv_type cv_type); char *cv2yang_type(enum cv_type cv_type);
yang_stmt *yang_find_identity(yang_stmt *ys, char *identity); yang_stmt *yang_find_identity(yang_stmt *ys, char *identity);
int ys_cv_validate(cg_var *cv, yang_stmt *ys, char **reason); int ys_cv_validate(cg_var *cv, yang_stmt *ys, char **reason);
int clicon_type2cv(char *type, char *rtype, enum cv_type *cvtype); int clicon_type2cv(char *type, char *rtype, yang_stmt *ys, enum cv_type *cvtype);
int yang_type_get(yang_stmt *ys, char **otype, yang_stmt **restype, int yang_type_get(yang_stmt *ys, char **otype, yang_stmt **restype,
int *options, cvec **cvv, char **pattern, int *options, cvec **cvv, char **pattern,
uint8_t *fraction_digits); uint8_t *fraction_digits);

View file

@ -1032,7 +1032,7 @@ netconf_module_load(clicon_handle h)
/* Load yang spec */ /* Load yang spec */
if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0) if (yang_spec_parse_module(h, "ietf-netconf", NULL, yspec)< 0)
goto done; goto done;
if (yang_spec_parse_module(h, "ietf-netconf-notification", NULL, yspec)< 0) if (yang_spec_parse_module(h, "clixon-rfc5277", NULL, yspec)< 0)
goto done; goto done;
retval = 0; retval = 0;
done: done:

View file

@ -548,7 +548,7 @@ stream_notify(clicon_handle h,
yang_spec *yspec = NULL; yang_spec *yspec = NULL;
char *str = NULL; char *str = NULL;
cbuf *cb = NULL; cbuf *cb = NULL;
char timestr[27]; char timestr[28];
struct timeval tv; struct timeval tv;
event_stream_t *es; event_stream_t *es;
@ -622,7 +622,7 @@ stream_notify_xml(clicon_handle h,
yang_spec *yspec = NULL; yang_spec *yspec = NULL;
char *str = NULL; char *str = NULL;
cbuf *cb = NULL; cbuf *cb = NULL;
char timestr[27]; char timestr[28];
struct timeval tv; struct timeval tv;
event_stream_t *es; event_stream_t *es;

View file

@ -634,6 +634,51 @@ clixon_trim(char *str)
return s; return s;
} }
/*! Transform from XSD regex to posix ERE
* The usecase is that Yang (RFC7950) supports XSD regexpressions but CLIgen supports
* Current translations:
* \d --> [0-9]
* POSIX ERE regexps according to man regex(3).
* @param[in] xsd Input regex string according XSD
* @param[out] posix Output (malloced) string according to POSIX ERE
* @see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028
* @note that the translation is ad-hoc, may need more translations
*/
int
regexp_xsd2posix(char *xsd,
char **posix)
{
int retval = -1;
char *x;
char *p = NULL;
int i;
int len;
len = strlen(xsd);
x = xsd;
while ((x = strstr(x, "\\d")) != NULL){
len += 3; /* \d --> [0-9] */
x += 2;
}
if ((p = malloc(len+1)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
memset(p, 0, len+1);
*posix = p;
for (i=0; i<strlen(xsd); i++){
if (strncmp(&xsd[i], "\\d", 2) == 0){
strcpy(p, "[0-9]");
p += 5; i++;
}
else
*p++ = xsd[i];
}
retval = 0;
done:
return retval;
}
/*! strndup() for systems without it, such as xBSD /*! strndup() for systems without it, such as xBSD
*/ */
#ifndef HAVE_STRNDUP #ifndef HAVE_STRNDUP

View file

@ -1082,7 +1082,7 @@ ys_populate_leaf(yang_stmt *ys,
< 0) < 0)
goto done; goto done;
restype = yrestype?yrestype->ys_argument:NULL; restype = yrestype?yrestype->ys_argument:NULL;
if (clicon_type2cv(type, restype, &cvtype) < 0) /* This handles non-resolved also */ if (clicon_type2cv(type, restype, ys, &cvtype) < 0) /* This handles non-resolved also */
goto done; goto done;
/* 2. Create the CV using cvtype and name it */ /* 2. Create the CV using cvtype and name it */
if ((cv = cv_new(cvtype)) == NULL){ if ((cv = cv_new(cvtype)) == NULL){
@ -1230,7 +1230,7 @@ ys_populate_range(yang_stmt *ys,
restype = yrestype?yrestype->ys_argument:NULL; restype = yrestype?yrestype->ys_argument:NULL;
origtype = yarg_id((yang_stmt*)yparent); origtype = yarg_id((yang_stmt*)yparent);
/* This handles non-resolved also */ /* This handles non-resolved also */
if (clicon_type2cv(origtype, restype, &cvtype) < 0) if (clicon_type2cv(origtype, restype, ys, &cvtype) < 0)
goto done; goto done;
if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL) if ((vec = clicon_strsep(ys->ys_argument, "|", &nvec)) == NULL)
goto done; goto done;

View file

@ -254,35 +254,6 @@ yang2cv_type(char *ytype,
*cv_type = ret; *cv_type = ret;
return 0; return 0;
} }
/* special derived types */
if (strcmp("ipv4-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV4ADDR;
return 0;
}
if (strcmp("ipv6-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV6ADDR;
return 0;
}
if (strcmp("ipv4-prefix", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV4PFX;
return 0;
}
if (strcmp("ipv6-prefix", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_IPV6PFX;
return 0;
}
if (strcmp("date-and-time", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_TIME;
return 0;
}
if (strcmp("mac-address", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_MACADDR;
return 0;
}
if (strcmp("uuid", ytype) == 0){ /* RFC6991 */
*cv_type = CGV_UUID;
return 0;
}
return 0; return 0;
} }
@ -330,12 +301,14 @@ cv2yang_type(enum cv_type cv_type)
* not true yang types * not true yang types
* @param[in] origtype Name of original type * @param[in] origtype Name of original type
* @param[in] restype Resolved type. May be null, in that case origtype is used * @param[in] restype Resolved type. May be null, in that case origtype is used
* @param[in] ys Yang stmt of original resolving node
* @param[out] cvtype Translation from resolved type * @param[out] cvtype Translation from resolved type
* @note Thereis a kludge for handling direct translations of native cligen types * @note Thereis a kludge for handling direct translations of native cligen types
*/ */
int int
clicon_type2cv(char *origtype, clicon_type2cv(char *origtype,
char *restype, char *restype,
yang_stmt *ys,
enum cv_type *cvtype) enum cv_type *cvtype)
{ {
int retval = -1; int retval = -1;
@ -344,7 +317,8 @@ clicon_type2cv(char *origtype,
if (restype != NULL){ if (restype != NULL){
yang2cv_type(restype, cvtype); yang2cv_type(restype, cvtype);
if (*cvtype == CGV_ERR){ if (*cvtype == CGV_ERR){
clicon_err(OE_YANG, EINVAL, "\"%s\" type not translated", restype); clicon_err(OE_YANG, 0, "%s: \"%s\" type not translated",
ys_module(ys)->ys_argument, restype);
goto done; goto done;
} }
} }
@ -355,7 +329,8 @@ clicon_type2cv(char *origtype,
*/ */
yang2cv_type(origtype, cvtype); yang2cv_type(origtype, cvtype);
if (*cvtype == CGV_ERR){ if (*cvtype == CGV_ERR){
clicon_err(OE_YANG, EINVAL, "\"%s\": type not resolved", origtype); clicon_err(OE_YANG, 0, "%s:\"%s\": type not resolved",
ys_module(ys)->ys_argument, origtype);
goto done; goto done;
} }
} }
@ -543,10 +518,15 @@ cv_validate1(cg_var *cv,
} }
} }
if ((options & YANG_OPTIONS_PATTERN) != 0){ if ((options & YANG_OPTIONS_PATTERN) != 0){
if ((retval2 = match_regexp(str, pattern)) < 0){ char *posix = NULL;
if (regexp_xsd2posix(pattern, &posix) < 0)
goto done;
if ((retval2 = match_regexp(str, posix)) < 0){
clicon_err(OE_DB, 0, "match_regexp: %s", pattern); clicon_err(OE_DB, 0, "match_regexp: %s", pattern);
return -1; return -1;
} }
if (posix)
free(posix);
if (retval2 == 0){ if (retval2 == 0){
if (reason) if (reason)
*reason = cligen_reason("regexp match fail: \"%s\" does not match %s", *reason = cligen_reason("regexp match fail: \"%s\" does not match %s",
@ -611,7 +591,7 @@ ys_cv_validate_union_one(yang_stmt *ys,
goto done; goto done;
} }
else { else {
if (clicon_type2cv(type, restype, &cvtype) < 0) if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
goto done; goto done;
/* reparse value with the new type */ /* reparse value with the new type */
if ((cvt = cv_new(cvtype)) == NULL){ if ((cvt = cv_new(cvtype)) == NULL){
@ -718,7 +698,7 @@ ys_cv_validate(cg_var *cv,
&options, &cvv, &pattern, &fraction) < 0) &options, &cvv, &pattern, &fraction) < 0)
goto done; goto done;
restype = yrestype?yrestype->ys_argument:NULL; restype = yrestype?yrestype->ys_argument:NULL;
if (clicon_type2cv(type, restype, &cvtype) < 0) if (clicon_type2cv(type, restype, ys, &cvtype) < 0)
goto done; goto done;
if (cv_type_get(ycv) != cvtype){ if (cv_type_get(ycv) != cvtype){
@ -978,7 +958,7 @@ yang_type_resolve(yang_stmt *yorig,
break; break;
/* Did not find a matching typedef there, proceed to next level */ /* Did not find a matching typedef there, proceed to next level */
yn = ys->ys_parent; yn = ys->ys_parent;
if (yn && yn->yn_keyword == Y_SPEC) if (yn && (yn->yn_keyword == Y_SPEC))
yn = NULL; yn = NULL;
ys = (yang_stmt*)yn; ys = (yang_stmt*)yn;
} }

View file

@ -153,7 +153,7 @@ new "netconf NONEXIST subscription"
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>NONEXIST</stream></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></rpc-error></rpc-reply>]]>]]>$' $NCWAIT
new "netconf EXAMPLE subscription with wrong date" new "netconf EXAMPLE subscription with wrong date"
expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</startTime></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>Invalid time: kallekaka</error-message></rpc-error></rpc-reply>]]>]]>$' 0 expectwait "$clixon_netconf -qf $cfg -y $fyang" '<rpc><create-subscription xmlns="urn:ietf:params:xml:ns:netmod:notification"><stream>EXAMPLE</stream><startTime>kallekaka</startTime></create-subscription></rpc>]]>]]>' '^<rpc-reply><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>startTime</bad-element></error-info><error-severity>error</error-severity><error-message>regexp match fail: "kallekaka" does not match' 0
#new "netconf EXAMPLE subscription with replay" #new "netconf EXAMPLE subscription with replay"
#NOW=$(date +"%Y-%m-%dT%H:%M:%S") #NOW=$(date +"%Y-%m-%dT%H:%M:%S")
@ -181,7 +181,7 @@ expectwait 'curl -s -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-
# 2a) start subscription 8s - expect 1-2 notifications # 2a) start subscription 8s - expect 1-2 notifications
new "2a) start subscriptions 8s - expect 1-2 notifications" new "2a) start subscriptions 8s - expect 1-2 notifications"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then
@ -193,10 +193,11 @@ if [ $nr -lt 1 -o $nr -gt 2 ]; then
fi fi
sleep 2 sleep 2
# 2b) start subscription 8s - stoptime after 5s - expect 1-2 notifications # 2b) start subscription 8s - stoptime after 5s - expect 1-2 notifications
new "2b) start subscriptions 8s - stoptime after 5s - expect 1-2 notifications" new "2b) start subscriptions 8s - stoptime after 5s - expect 1-2 notifications"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8 -e +10) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8 -e +10)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then
err "$expect" "$ret" err "$expect" "$ret"
@ -209,7 +210,7 @@ fi
# 2c # 2c
new "2c) start sub 8s - replay from start -8s - expect 3-4 notifications" new "2c) start sub 8s - replay from start -8s - expect 3-4 notifications"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -8) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -8)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then
err "$expect" "$ret" err "$expect" "$ret"
@ -222,7 +223,7 @@ fi
# 2d) start sub 8s - replay from start -8s to stop +4s - expect 3 notifications # 2d) start sub 8s - replay from start -8s to stop +4s - expect 3 notifications
new "2d) start sub 8s - replay from start -8s to stop +4s - expect 3 notifications" new "2d) start sub 8s - replay from start -8s to stop +4s - expect 3 notifications"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -30 -e +4) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -30 -e +4)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then
err "$expect" "$ret" err "$expect" "$ret"
@ -235,7 +236,7 @@ fi
# 2e) start sub 8s - replay from -90s w retention 60s - expect 10 notifications # 2e) start sub 8s - replay from -90s w retention 60s - expect 10 notifications
new "2e) start sub 8s - replay from -90s w retention 60s - expect 10 notifications" new "2e) start sub 8s - replay from -90s w retention 60s - expect 10 notifications"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -90 -e +0) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 10 -s -90 -e +0)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then
err "$expect" "$ret" err "$expect" "$ret"
@ -253,7 +254,7 @@ PID=$!
new "Start subscriptions in parallell" new "Start subscriptions in parallell"
ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8) ret=$($UTIL -u http://localhost/streams/EXAMPLE -t 8)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>" expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect") match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then if [ -z "$match" ]; then

View file

@ -216,8 +216,8 @@ main(int argc, char **argv)
char *url = NULL; char *url = NULL;
char *getdata = NULL; char *getdata = NULL;
int timeout = 10; int timeout = 10;
char start[27] = {0,}; /* strlen = 0 */ char start[28] = {0,}; /* strlen = 0 */
char stop[27] = {0,}; char stop[28] = {0,};
int c; int c;
char *argv0 = argv[0]; char *argv0 = argv[0];
struct timeval now; struct timeval now;

View file

@ -48,7 +48,7 @@ YANGSPECS += ietf-inet-types@2013-07-15.yang
YANGSPECS += ietf-yang-types@2013-07-15.yang YANGSPECS += ietf-yang-types@2013-07-15.yang
YANGSPECS += ietf-restconf@2017-01-26.yang YANGSPECS += ietf-restconf@2017-01-26.yang
YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang YANGSPECS += ietf-restconf-monitoring@2017-01-26.yang
YANGSPECS += ietf-netconf-notification@2008-07-01.yang YANGSPECS += clixon-rfc5277@2008-07-01.yang
YANGSPECS += ietf-yang-library@2016-06-21.yang YANGSPECS += ietf-yang-library@2016-06-21.yang
APPNAME = clixon # subdir ehere these files are installed APPNAME = clixon # subdir ehere these files are installed

View file

@ -1,7 +1,7 @@
module ietf-netconf-notification { module clixon-rfc5277 {
/* namespace "urn:ietf:params:xml:ns:netconf:notification:1.0";*/ /* namespace "urn:ietf:params:xml:ns:netconf:notification:1.0";*/
namespace "urn:ietf:params:xml:ns:netmod:notification"; namespace "urn:ietf:params:xml:ns:netmod:notification";
prefix "rcmon"; prefix "ncevent";
import ietf-yang-types { prefix yang; } import ietf-yang-types { prefix yang; }
import ietf-inet-types { prefix inet; } import ietf-inet-types { prefix inet; }
@ -10,7 +10,8 @@ module ietf-netconf-notification {
"IETF NETCONF (Network Configuration) Working Group"; "IETF NETCONF (Network Configuration) Working Group";
description description
"Note this is a translation from RFC 5277 schema in section 4 to Yang. "Note this is a translation from RFC 5277 schema in section 4 to Yang
made by Olof Hagsand manually for the Clixon project.
RFC 5277 is Copyright (C) The IETF Trust (2008)."; RFC 5277 is Copyright (C) The IETF Trust (2008).";
revision 2008-07-01 { revision 2008-07-01 {
@ -120,14 +121,14 @@ module ietf-netconf-notification {
for more information on filters"; for more information on filters";
} }
leaf startTime { leaf startTime {
type date-and-time; type yang:date-and-time;
description "used to trigger the replay feature description "used to trigger the replay feature
and indicate that the replay should start at the time and indicate that the replay should start at the time
specified. If <startTime> is not present, this is not a replay specified. If <startTime> is not present, this is not a replay
subscription."; subscription.";
} }
leaf stopTime { leaf stopTime {
type date-and-time; type yang:date-and-time;
description "used with the optional description "used with the optional
replay feature to indicate the newest notifications of replay feature to indicate the newest notifications of
interest. If <stopTime> is not present, the notifications will interest. If <stopTime> is not present, the notifications will