Replacing remaining badrequest() with proper restconf error msg.
This commit is contained in:
parent
3ed1c98556
commit
1913407e52
14 changed files with 153 additions and 75 deletions
|
|
@ -424,19 +424,28 @@ api_data_post(clicon_handle h,
|
||||||
/* Parse input data as json or xml into xml */
|
/* Parse input data as json or xml into xml */
|
||||||
if (parse_xml){
|
if (parse_xml){
|
||||||
if (xml_parse_string(data, NULL, &xdata) < 0){
|
if (xml_parse_string(data, NULL, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (json_parse_str(data, &xdata) < 0){
|
else if (json_parse_str(data, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* 4.4.1: The message-body MUST contain exactly one instance of the
|
/* 4.4.1: The message-body MUST contain exactly one instance of the
|
||||||
* expected data resource.
|
* expected data resource.
|
||||||
*/
|
*/
|
||||||
if (xml_child_nr(xdata) != 1){
|
if (xml_child_nr(xdata) != 1){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
x = xml_child_i(xdata,0);
|
x = xml_child_i(xdata,0);
|
||||||
|
|
@ -628,19 +637,28 @@ api_data_put(clicon_handle h,
|
||||||
/* Parse input data as json or xml into xml */
|
/* Parse input data as json or xml into xml */
|
||||||
if (parse_xml){
|
if (parse_xml){
|
||||||
if (xml_parse_string(data, NULL, &xdata) < 0){
|
if (xml_parse_string(data, NULL, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (json_parse_str(data, &xdata) < 0){
|
else if (json_parse_str(data, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* The message-body MUST contain exactly one instance of the
|
/* The message-body MUST contain exactly one instance of the
|
||||||
* expected data resource.
|
* expected data resource.
|
||||||
*/
|
*/
|
||||||
if (xml_child_nr(xdata) != 1){
|
if (xml_child_nr(xdata) != 1){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
x = xml_child_i(xdata,0);
|
x = xml_child_i(xdata,0);
|
||||||
|
|
@ -662,13 +680,19 @@ api_data_put(clicon_handle h,
|
||||||
else {
|
else {
|
||||||
/* Check same symbol in api-path as data */
|
/* Check same symbol in api-path as data */
|
||||||
if (strcmp(xml_name(x), xml_name(xbot))){
|
if (strcmp(xml_name(x), xml_name(xbot))){
|
||||||
badrequest(r);
|
if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
/* If list or leaf-list, api-path keys must match data keys */
|
/* If list or leaf-list, api-path keys must match data keys */
|
||||||
if (y && (y->yn_keyword == Y_LIST ||y->yn_keyword == Y_LEAF_LIST)){
|
if (y && (y->yn_keyword == Y_LIST ||y->yn_keyword == Y_LEAF_LIST)){
|
||||||
if (match_list_keys((yang_stmt*)y, x, xbot) < 0){
|
if (match_list_keys((yang_stmt*)y, x, xbot) < 0){
|
||||||
badrequest(r);
|
if (netconf_operation_failed_xml(&xerr, "protocol", "api-path keys do not match data keys") < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1055,12 +1079,18 @@ api_operations_post(clicon_handle h,
|
||||||
/* Parse input data as json or xml into xml */
|
/* Parse input data as json or xml into xml */
|
||||||
if (parse_xml){
|
if (parse_xml){
|
||||||
if (xml_parse_string(data, NULL, &xdata) < 0){
|
if (xml_parse_string(data, NULL, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (json_parse_str(data, &xdata) < 0){
|
else if (json_parse_str(data, &xdata) < 0){
|
||||||
badrequest(r);
|
if (netconf_malformed_message_xml(&xerr, clicon_err_reason) < 0)
|
||||||
|
goto done;
|
||||||
|
if (api_return_err(h, r, xerr, pretty, use_xml) < 0)
|
||||||
|
goto done;
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL);
|
yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL);
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/config/ ../apps/netconf ../apps/dbctrl ../datastore
|
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/config/ ../apps/netconf ../apps/dbctrl ../datastore ../datastore/text
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
|
|
||||||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
||||||
# spaces.
|
# spaces.
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/backend/ ../apps/restconf/ ../apps/netconf ../apps/dbctrl ../datastore
|
INPUT = ../lib/src/ ../lib/clicon/ ../apps/cli/ ../apps/backend/ ../apps/restconf/ ../apps/netconf ../apps/dbctrl ../datastore ../datastore/text
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
|
|
||||||
|
|
@ -93,27 +93,22 @@ Routing notification
|
||||||
|
|
||||||
The example includes a restonf, netconf, CLI and two backend plugins.
|
The example includes a restonf, netconf, CLI and two backend plugins.
|
||||||
Each plugin is initiated with an API struct followed by a plugin init function.
|
Each plugin is initiated with an API struct followed by a plugin init function.
|
||||||
The content of the API struct is different depending on what kind of plugin it is. Some fields are
|
The content of the API struct is different depending on what kind of plugin it is.
|
||||||
meaningful only for some plugins.
|
The plugin init function may also include registering RPC functions, see below is for a backend.
|
||||||
The plugin init function may also include registering RPC functions.
|
|
||||||
```
|
```
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
"example", /* name */
|
"example", /* name */
|
||||||
clixon_plugin_init,
|
clixon_plugin_init,
|
||||||
plugin_start,
|
plugin_start,
|
||||||
plugin_exit,
|
plugin_exit,
|
||||||
NULL, /* cli prompt N/A for backend */
|
.ca_reset=plugin_reset,/* reset */
|
||||||
NULL, /* cli suspend N/A for backend */
|
.ca_statedata=plugin_statedata, /* statedata */
|
||||||
NULL, /* cli interrupt N/A for backend */
|
.ca_trans_begin=NULL, /* trans begin */
|
||||||
NULL, /* auth N/A for backend */
|
.ca_trans_validate=transaction_validate,/* trans validate */
|
||||||
plugin_reset,
|
.ca_trans_complete=NULL, /* trans complete */
|
||||||
plugin_statedata,
|
.ca_trans_commit=transaction_commit, /* trans commit */
|
||||||
transaction_begin,
|
.ca_trans_end=NULL, /* trans end */
|
||||||
transaction_validate,
|
.ca_trans_abort=NULL /* trans abort */
|
||||||
transaction_complete,
|
|
||||||
transaction_commit,
|
|
||||||
transaction_end,
|
|
||||||
transaction_abort
|
|
||||||
};
|
};
|
||||||
|
|
||||||
clixon_plugin_api *
|
clixon_plugin_api *
|
||||||
|
|
|
||||||
|
|
@ -260,11 +260,11 @@ plugin_start(clicon_handle h,
|
||||||
clixon_plugin_api *clixon_plugin_init(clicon_handle h);
|
clixon_plugin_api *clixon_plugin_init(clicon_handle h);
|
||||||
|
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
"example", /* name */ /*--- Common fields. ---*/
|
"example", /* name */
|
||||||
clixon_plugin_init, /* init */
|
clixon_plugin_init, /* init */
|
||||||
plugin_start, /* start */
|
plugin_start, /* start */
|
||||||
NULL, /* exit */
|
NULL, /* exit */
|
||||||
.ca_reset=plugin_reset,/* reset */ /*--- Backend plugin only ---*/
|
.ca_reset=plugin_reset, /* reset */
|
||||||
.ca_statedata=plugin_statedata, /* statedata */
|
.ca_statedata=plugin_statedata, /* statedata */
|
||||||
.ca_trans_begin=NULL, /* trans begin */
|
.ca_trans_begin=NULL, /* trans begin */
|
||||||
.ca_trans_validate=transaction_validate,/* trans validate */
|
.ca_trans_validate=transaction_validate,/* trans validate */
|
||||||
|
|
|
||||||
|
|
@ -61,5 +61,6 @@ int netconf_operation_not_supported(cbuf *cb, char *type, char *message);
|
||||||
int netconf_operation_failed(cbuf *cb, char *type, char *message);
|
int netconf_operation_failed(cbuf *cb, char *type, char *message);
|
||||||
int netconf_operation_failed_xml(cxobj **xret, char *type, char *message);
|
int netconf_operation_failed_xml(cxobj **xret, char *type, char *message);
|
||||||
int netconf_malformed_message(cbuf *cb, char *message);
|
int netconf_malformed_message(cbuf *cb, char *message);
|
||||||
|
int netconf_malformed_message_xml(cxobj **xret, char *message);
|
||||||
|
|
||||||
#endif /* _CLIXON_NETCONF_LIB_H */
|
#endif /* _CLIXON_NETCONF_LIB_H */
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,16 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! 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 syntax a.b[] $!x $y:
|
* Example YANG:
|
||||||
* NONE: a b <x> <y>;
|
* list a {a.b[] $!x $y:
|
||||||
* VARS: a b <x> y <y>;
|
* list a {
|
||||||
* ALL: a b x <x> y <y>;
|
* key x;
|
||||||
|
* leaf x;
|
||||||
|
* leaf y;
|
||||||
|
* }
|
||||||
|
* NONE: a <x> <y>;
|
||||||
|
* VARS: a <x> y <y>;
|
||||||
|
* ALL: a x <x> y <y>;
|
||||||
*/
|
*/
|
||||||
enum genmodel_type{
|
enum genmodel_type{
|
||||||
GT_ERR =-1, /* Error */
|
GT_ERR =-1, /* Error */
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
* Yang functions
|
||||||
|
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
|
||||||
|
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CLIXON_YANG_H_
|
#ifndef _CLIXON_YANG_H_
|
||||||
|
|
|
||||||
|
|
@ -526,22 +526,25 @@ netconf_access_denied_xml(cxobj **xret,
|
||||||
char *message)
|
char *message)
|
||||||
{
|
{
|
||||||
int retval =-1;
|
int retval =-1;
|
||||||
cbuf *cbret = NULL;
|
cxobj *xerr;
|
||||||
|
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
if (*xret == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (netconf_access_denied(cbret, type, message) < 0)
|
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_parse_string(cbuf_get(cbret), NULL, xret) < 0)
|
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_rootchild(*xret, 0, xret) < 0)
|
if (xml_parse_va(&xerr, NULL, "<error-tag>access-denied</error-tag>"
|
||||||
|
"<error-type>%s</error-type>"
|
||||||
|
"<error-severity>error</error-severity>", type) < 0)
|
||||||
|
goto done;
|
||||||
|
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
|
||||||
|
message) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cbret)
|
|
||||||
cbuf_free(cbret);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -835,22 +838,25 @@ netconf_operation_failed_xml(cxobj **xret,
|
||||||
char *message)
|
char *message)
|
||||||
{
|
{
|
||||||
int retval =-1;
|
int retval =-1;
|
||||||
cbuf *cbret = NULL;
|
cxobj *xerr;
|
||||||
|
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
if (*xret == NULL){
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (netconf_operation_failed(cbret, type, message) < 0)
|
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_parse_string(cbuf_get(cbret), NULL, xret) < 0)
|
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
if (xml_rootchild(*xret, 0, xret) < 0)
|
if (xml_parse_va(&xerr, NULL, "<error-tag>operation-failed</error-tag>"
|
||||||
|
"<error-type>%s</error-type>"
|
||||||
|
"<error-severity>error</error-severity>", type) < 0)
|
||||||
|
goto done;
|
||||||
|
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
|
||||||
|
message) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
if (cbret)
|
|
||||||
cbuf_free(cbret);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -892,3 +898,39 @@ netconf_malformed_message(cbuf *cb,
|
||||||
clicon_err(OE_XML, errno, "cprintf");
|
clicon_err(OE_XML, errno, "cprintf");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Create Netconf malformed-message error XML tree according to RFC 6241 App A
|
||||||
|
*
|
||||||
|
* A message could not be handled because it failed to be parsed correctly.
|
||||||
|
* For example, the message is not well-formed XML or it uses an
|
||||||
|
* invalid character set.
|
||||||
|
* @param[out] xret Error XML tree
|
||||||
|
* @param[in] message Error message
|
||||||
|
* @note New in :base:1.1
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
netconf_malformed_message_xml(cxobj **xret,
|
||||||
|
char *message)
|
||||||
|
{
|
||||||
|
int retval =-1;
|
||||||
|
cxobj *xerr;
|
||||||
|
|
||||||
|
if (*xret == NULL){
|
||||||
|
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||||
|
goto done;
|
||||||
|
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (xml_parse_va(&xerr, NULL, "<error-tag>malformed-message</error-tag>"
|
||||||
|
"<error-type>rpc</error-type>"
|
||||||
|
"<error-severity>error</error-severity>") < 0)
|
||||||
|
goto done;
|
||||||
|
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
|
||||||
|
message) < 0)
|
||||||
|
goto done;
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,9 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* Database specification parser cli syntax
|
* Yang parser. Hopefully useful but not complete
|
||||||
* (Cloned from cligen parser)
|
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
|
||||||
|
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
|
||||||
*/
|
*/
|
||||||
#ifndef _CLIXON_YANG_PARSE_H_
|
#ifndef _CLIXON_YANG_PARSE_H_
|
||||||
#define _CLIXON_YANG_PARSE_H_
|
#define _CLIXON_YANG_PARSE_H_
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Yang 1.0 parser according to RFC6020.
|
|
||||||
* It is hopefully useful but not complete
|
|
||||||
* RFC7950 defines Yang version 1.1
|
|
||||||
*
|
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||||
|
|
@ -34,8 +30,9 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* Database specification parser cli syntax
|
* Yang parser. Hopefully useful but not complete
|
||||||
* (Cloned from cligen parser)
|
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
|
||||||
|
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Yang 1.0 parser according to RFC6020.
|
|
||||||
* It is hopefully useful but not complete
|
|
||||||
* RFC7950 defines Yang version 1.1
|
|
||||||
*
|
*
|
||||||
***** BEGIN LICENSE BLOCK *****
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
|
@ -34,6 +31,9 @@
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
* Yang parser. Hopefully useful but not complete
|
||||||
|
* @see https://tools.ietf.org/html/rfc6020 YANG 1.0
|
||||||
|
* @see https://tools.ietf.org/html/rfc7950 YANG 1.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ expectfn "curl -s -I http://localhost/restconf/data" "HTTP/1.1 200 OK"
|
||||||
#Content-Type: application/yang-data+json"
|
#Content-Type: application/yang-data+json"
|
||||||
|
|
||||||
new2 "restconf empty rpc"
|
new2 "restconf empty rpc"
|
||||||
expecteq "$(curl -s -X POST -d {\"input\":{\"name\":\"\"}} http://localhost/restconf/operations/ex:empty)" ''
|
expecteq "$(curl -s -X POST -d {\"input\":{\"name\":\"\"}} http://localhost/restconf/operations/ex:empty)" ""
|
||||||
|
|
||||||
new2 "restconf get empty config + state json"
|
new2 "restconf get empty config + state json"
|
||||||
expecteq "$(curl -sSG http://localhost/restconf/data)" '{"data": {"interfaces-state": {"interface": [{"name": "eth0","type": "eth","if-index": 42}]}}}
|
expecteq "$(curl -sSG http://localhost/restconf/data)" '{"data": {"interfaces-state": {"interface": [{"name": "eth0","type": "eth","if-index": 42}]}}}
|
||||||
|
|
@ -213,11 +213,11 @@ expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces":
|
||||||
new2 "restconf Re-post eth/0/0 which should generate error"
|
new2 "restconf Re-post eth/0/0 which should generate error"
|
||||||
expecteq "$(curl -s -X POST -d '{"interface":{"name":"eth/0/0","type":"eth","enabled":true}}' http://localhost/restconf/data/interfaces)" '{"ietf-restconf:errors" : {"error": {"error-tag": "data-exists","error-type": "application","error-severity": "error","error-message": "Data already exists; cannot create new resource"}}}
'
|
expecteq "$(curl -s -X POST -d '{"interface":{"name":"eth/0/0","type":"eth","enabled":true}}' http://localhost/restconf/data/interfaces)" '{"ietf-restconf:errors" : {"error": {"error-tag": "data-exists","error-type": "application","error-severity": "error","error-message": "Data already exists; cannot create new resource"}}}
'
|
||||||
|
|
||||||
new2 "Add leaf description using POST"
|
new "Add leaf description using POST"
|
||||||
expecteq "$(curl -s -X POST -d '{"description":"The-first-interface"}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
expecteq "$(curl -s -X POST -d '{"description":"The-first-interface"}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
||||||
|
|
||||||
new "Add nothing using POST"
|
new "Add nothing using POST"
|
||||||
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' "data is in some way badly formed"
|
expectfn 'curl -s -X POST http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0' '"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "malformed-message","error-type": "rpc","error-severity": "error","error-message": " on line 1: syntax error at or before:'
|
||||||
|
|
||||||
new2 "restconf Check description added"
|
new2 "restconf Check description added"
|
||||||
expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces": {"interface": [{"name": "eth/0/0","description": "The-first-interface","type": "eth","enabled": true}]},"interfaces-state": {"interface": [{"name": "eth0","type": "eth","if-index": 42}]}}}
|
expecteq "$(curl -s -G http://localhost/restconf/data)" '{"data": {"interfaces": {"interface": [{"name": "eth/0/0","description": "The-first-interface","type": "eth","enabled": true}]},"interfaces-state": {"interface": [{"name": "eth0","type": "eth","if-index": 42}]}}}
|
||||||
|
|
@ -232,7 +232,7 @@ expectfn 'curl -s -G http://localhost/restconf/data' $state
|
||||||
new2 "restconf Re-Delete eth/0/0 using none should generate error"
|
new2 "restconf Re-Delete eth/0/0 using none should generate error"
|
||||||
expecteq "$(curl -s -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" '{"ietf-restconf:errors" : {"error": {"error-tag": "data-missing","error-type": "application","error-severity": "error","error-message": "Data does not exist; cannot delete resource"}}}
'
|
expecteq "$(curl -s -X DELETE http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" '{"ietf-restconf:errors" : {"error": {"error-tag": "data-missing","error-type": "application","error-severity": "error","error-message": "Data does not exist; cannot delete resource"}}}
'
|
||||||
|
|
||||||
new2 "restconf Add subtree eth/0/0 using PUT"
|
new "restconf Add subtree eth/0/0 using PUT"
|
||||||
expecteq "$(curl -s -X PUT -d '{"interface":{"name":"eth/0/0","type":"eth","enabled":true}}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
expecteq "$(curl -s -X PUT -d '{"interface":{"name":"eth/0/0","type":"eth","enabled":true}}' http://localhost/restconf/data/interfaces/interface=eth%2f0%2f0)" ""
|
||||||
|
|
||||||
new2 "restconf get subtree"
|
new2 "restconf get subtree"
|
||||||
|
|
@ -243,9 +243,12 @@ new2 "restconf rpc using POST json"
|
||||||
expecteq "$(curl -s -X POST -d '{"input":{"routing-instance-name":"ipv4"}}' http://localhost/restconf/operations/rt:fib-route)" '{"output": {"route": {"address-family": "ipv4","next-hop": {"next-hop-list": "2.3.4.5"}}}}
|
expecteq "$(curl -s -X POST -d '{"input":{"routing-instance-name":"ipv4"}}' http://localhost/restconf/operations/rt:fib-route)" '{"output": {"route": {"address-family": "ipv4","next-hop": {"next-hop-list": "2.3.4.5"}}}}
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# Cant get this to work due to quoting
|
||||||
|
#new2 "restconf rpc using POST wrong JSON"
|
||||||
|
#expecteq "$(curl -s -X POST -d '{"input":{"routing-instance-name":ipv4}}' http://localhost/restconf/operations/rt:fib-route)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": " on line 1: syntax error at or before: i"}}}}
'
|
||||||
|
|
||||||
new2 "restconf rpc using POST json w/o mandatory element"
|
new2 "restconf rpc using POST json w/o mandatory element"
|
||||||
expecteq "$(curl -s -X POST -d '{"input":{"wrongelement":"ipv4"}}' http://localhost/restconf/operations/rt:fib-route)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "Missing mandatory variable: routing-instance-name"}}}}
'
|
expecteq "$(curl -s -X POST -d '{"input":{"wrongelement":"ipv4"}}' http://localhost/restconf/operations/rt:fib-route)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "Missing mandatory variable: routing-instance-name"}}}}
'
|
||||||
|
|
||||||
new2 "restconf rpc non-existing rpc w/o namespace"
|
new2 "restconf rpc non-existing rpc w/o namespace"
|
||||||
expecteq "$(curl -s -X POST -d '{}' http://localhost/restconf/operations/kalle)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "yang node not found"}}}}
'
|
expecteq "$(curl -s -X POST -d '{}' http://localhost/restconf/operations/kalle)" '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "yang node not found"}}}}
'
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ new "restconf PUT add interface"
|
||||||
expectfn 'curl -s -X PUT -d {"interface":{"name":"TEST","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' ""
|
expectfn 'curl -s -X PUT -d {"interface":{"name":"TEST","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' ""
|
||||||
|
|
||||||
new "restconf PUT change key error"
|
new "restconf PUT change key error"
|
||||||
expectfn 'curl -is -X PUT -d {"interface":{"name":"ALPHA","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' "Bad request"
|
expectfn 'curl -is -X PUT -d {"interface":{"name":"ALPHA","type":"eth0"}} http://localhost/restconf/data/cont1/interface=TEST' '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-tag": "operation-failed","error-type": "protocol","error-severity": "error","error-message": "api-path keys do not match data keys"}}}}'
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue