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 */
|
||||
if (parse_xml){
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* 4.4.1: The message-body MUST contain exactly one instance of the
|
||||
* expected data resource.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
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 */
|
||||
if (parse_xml){
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* The message-body MUST contain exactly one instance of the
|
||||
* expected data resource.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
x = xml_child_i(xdata,0);
|
||||
|
|
@ -662,13 +680,19 @@ api_data_put(clicon_handle h,
|
|||
else {
|
||||
/* Check same symbol in api-path as data */
|
||||
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;
|
||||
}
|
||||
/* 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 (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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1055,12 +1079,18 @@ api_operations_post(clicon_handle h,
|
|||
/* Parse input data as json or xml into xml */
|
||||
if (parse_xml){
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
yinput = yang_find((yang_node*)yrpc, Y_INPUT, NULL);
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# 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
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
|
|
|
|||
|
|
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
|||
# spaces.
|
||||
# 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
|
||||
# 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.
|
||||
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
|
||||
meaningful only for some plugins.
|
||||
The plugin init function may also include registering RPC functions.
|
||||
The content of the API struct is different depending on what kind of plugin it is.
|
||||
The plugin init function may also include registering RPC functions, see below is for a backend.
|
||||
```
|
||||
static clixon_plugin_api api = {
|
||||
"example", /* name */
|
||||
clixon_plugin_init,
|
||||
plugin_start,
|
||||
plugin_exit,
|
||||
NULL, /* cli prompt N/A for backend */
|
||||
NULL, /* cli suspend N/A for backend */
|
||||
NULL, /* cli interrupt N/A for backend */
|
||||
NULL, /* auth N/A for backend */
|
||||
plugin_reset,
|
||||
plugin_statedata,
|
||||
transaction_begin,
|
||||
transaction_validate,
|
||||
transaction_complete,
|
||||
transaction_commit,
|
||||
transaction_end,
|
||||
transaction_abort
|
||||
.ca_reset=plugin_reset,/* reset */
|
||||
.ca_statedata=plugin_statedata, /* statedata */
|
||||
.ca_trans_begin=NULL, /* trans begin */
|
||||
.ca_trans_validate=transaction_validate,/* trans validate */
|
||||
.ca_trans_complete=NULL, /* trans complete */
|
||||
.ca_trans_commit=transaction_commit, /* trans commit */
|
||||
.ca_trans_end=NULL, /* trans end */
|
||||
.ca_trans_abort=NULL /* trans abort */
|
||||
};
|
||||
|
||||
clixon_plugin_api *
|
||||
|
|
|
|||
|
|
@ -260,13 +260,13 @@ plugin_start(clicon_handle h,
|
|||
clixon_plugin_api *clixon_plugin_init(clicon_handle h);
|
||||
|
||||
static clixon_plugin_api api = {
|
||||
"example", /* name */ /*--- Common fields. ---*/
|
||||
clixon_plugin_init, /* init */
|
||||
plugin_start, /* start */
|
||||
NULL, /* exit */
|
||||
.ca_reset=plugin_reset,/* reset */ /*--- Backend plugin only ---*/
|
||||
.ca_statedata=plugin_statedata, /* statedata */
|
||||
.ca_trans_begin=NULL, /* trans begin */
|
||||
"example", /* name */
|
||||
clixon_plugin_init, /* init */
|
||||
plugin_start, /* start */
|
||||
NULL, /* exit */
|
||||
.ca_reset=plugin_reset, /* reset */
|
||||
.ca_statedata=plugin_statedata, /* statedata */
|
||||
.ca_trans_begin=NULL, /* trans begin */
|
||||
.ca_trans_validate=transaction_validate,/* trans validate */
|
||||
.ca_trans_complete=NULL, /* trans complete */
|
||||
.ca_trans_commit=transaction_commit, /* trans commit */
|
||||
|
|
|
|||
|
|
@ -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_xml(cxobj **xret, char *type, char *message);
|
||||
int netconf_malformed_message(cbuf *cb, char *message);
|
||||
int netconf_malformed_message_xml(cxobj **xret, char *message);
|
||||
|
||||
#endif /* _CLIXON_NETCONF_LIB_H */
|
||||
|
|
|
|||
|
|
@ -49,10 +49,16 @@
|
|||
*/
|
||||
|
||||
/*! Controls how keywords a generated in CLI syntax / prints from object model
|
||||
* Example syntax a.b[] $!x $y:
|
||||
* NONE: a b <x> <y>;
|
||||
* VARS: a b <x> y <y>;
|
||||
* ALL: a b x <x> y <y>;
|
||||
* Example YANG:
|
||||
* list a {a.b[] $!x $y:
|
||||
* list a {
|
||||
* key x;
|
||||
* leaf x;
|
||||
* leaf y;
|
||||
* }
|
||||
* NONE: a <x> <y>;
|
||||
* VARS: a <x> y <y>;
|
||||
* ALL: a x <x> y <y>;
|
||||
*/
|
||||
enum genmodel_type{
|
||||
GT_ERR =-1, /* Error */
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
|
||||
***** 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_
|
||||
|
|
|
|||
|
|
@ -526,22 +526,25 @@ netconf_access_denied_xml(cxobj **xret,
|
|||
char *message)
|
||||
{
|
||||
int retval =-1;
|
||||
cbuf *cbret = NULL;
|
||||
cxobj *xerr;
|
||||
|
||||
if ((cbret = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
if (netconf_access_denied(cbret, type, message) < 0)
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_parse_string(cbuf_get(cbret), NULL, xret) < 0)
|
||||
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||
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;
|
||||
retval = 0;
|
||||
done:
|
||||
if (cbret)
|
||||
cbuf_free(cbret);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -835,22 +838,25 @@ netconf_operation_failed_xml(cxobj **xret,
|
|||
char *message)
|
||||
{
|
||||
int retval =-1;
|
||||
cbuf *cbret = NULL;
|
||||
cxobj *xerr;
|
||||
|
||||
if ((cbret = cbuf_new()) == NULL){
|
||||
clicon_err(OE_XML, errno, "cbuf_new");
|
||||
goto done;
|
||||
if (*xret == NULL){
|
||||
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
|
||||
goto done;
|
||||
}
|
||||
if (netconf_operation_failed(cbret, type, message) < 0)
|
||||
else if (xml_name_set(*xret, "rpc-reply") < 0)
|
||||
goto done;
|
||||
if (xml_parse_string(cbuf_get(cbret), NULL, xret) < 0)
|
||||
if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL)
|
||||
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;
|
||||
retval = 0;
|
||||
done:
|
||||
if (cbret)
|
||||
cbuf_free(cbret);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -892,3 +898,39 @@ netconf_malformed_message(cbuf *cb,
|
|||
clicon_err(OE_XML, errno, "cprintf");
|
||||
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 *****
|
||||
|
||||
* Database specification parser cli syntax
|
||||
* (Cloned from cligen parser)
|
||||
* 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
|
||||
*/
|
||||
#ifndef _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 *****
|
||||
|
||||
Copyright (C) 2009-2018 Olof Hagsand and Benny Holmgren
|
||||
|
|
@ -34,8 +30,9 @@
|
|||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
* Database specification parser cli syntax
|
||||
* (Cloned from cligen parser)
|
||||
* 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
|
||||
*/
|
||||
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -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 *****
|
||||
|
||||
|
|
@ -34,6 +31,9 @@
|
|||
|
||||
***** 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"
|
||||
|
||||
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"
|
||||
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"
|
||||
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)" ""
|
||||
|
||||
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"
|
||||
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"
|
||||
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)" ""
|
||||
|
||||
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"}}}}
|
||||
'
|
||||
|
||||
# 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"
|
||||
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"
|
||||
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' ""
|
||||
|
||||
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"
|
||||
sudo pkill -u www-data clixon_restconf
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue