* Revised RESTCONF->NETCONF insert/point translation
* Netconf edit-config "operation" attribute namespace check is enforced
This commit is contained in:
parent
c97346921b
commit
b73348e0cd
6 changed files with 79 additions and 35 deletions
|
|
@ -5,6 +5,7 @@
|
|||
### Major New features
|
||||
* Restconf RFC 8040 increased feature compliance
|
||||
* RESTCONF "insert" and "point" query parameters supported
|
||||
* Applies to ordered-by-user leaf and leaf-lists
|
||||
* RESTCONF PUT/POST erroneously returned 200 OK. Instead restconf now returns:
|
||||
* `201 Created` for created resources
|
||||
* `204 No Content` for replaced resources.
|
||||
|
|
@ -22,6 +23,9 @@
|
|||
* The main example explains how to implement a Yang extension in a backend plugin.
|
||||
|
||||
### API changes on existing features (you may need to change your code)
|
||||
* Netconf edit-config "operation" attribute namespace check is enforced
|
||||
* This is enforced: `<a xmlns="uri:example" nc:operation="merge" xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
|
||||
* This was previously allowed: `<a xmlns="uri:example" operation="merge">
|
||||
* RESTCONF PUT/POST erroneously returned 200 OK. Instead restconf now returns:
|
||||
* `201 Created` for created resources
|
||||
* `204 No Content` for replaced resources.
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ Clixon interaction is best done posting issues, pull requests, or joining the
|
|||
Clixon provides a core system and can be used as-is using available
|
||||
Yang specifications. However, an application very quickly needs to
|
||||
specialize functions. Clixon is extended by writing
|
||||
plugins for cli and backend. Extensions for netconf and restconf
|
||||
are also available.
|
||||
plugins for cli, backend, netconf and restconf.
|
||||
|
||||
Plugins are written in C and easiest is to look at
|
||||
[example](example/README.md) or consulting the [FAQ](doc/FAQ.md).
|
||||
|
|
@ -100,12 +99,12 @@ However, the following YANG syntax modules are not implemented (reference to RFC
|
|||
- action (7.15)
|
||||
- augment in a uses sub-clause (7.17) (module-level augment is implemented)
|
||||
- require-instance
|
||||
- instance-identifier type
|
||||
- instance-identifier type (9.13)
|
||||
- status (7.21.2)
|
||||
- YIN (13)
|
||||
- Yang extended Xpath functions: re-match(), deref)(), derived-from(), derived-from-or-self(), enum-value(), bit-is-set() (10.2-10.6)
|
||||
- Default values on leaf-lists are not supported (7.7.2)
|
||||
- instance-identifier type
|
||||
- Lists without keys (non-config lists may lack keys)
|
||||
|
||||
### Yang patterns
|
||||
Yang type patterns use regexps defined in [W3C XML XSD](http://www.w3.org/TR/2004/REC-xmlschema-2-20041028). XSD regexp:s are
|
||||
|
|
|
|||
|
|
@ -558,6 +558,22 @@ restconf_terminate(clicon_handle h)
|
|||
* @param[in] qvec Query parameters (eg where insert/point should be)
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* A difficulty is that RESTCONF 'point' is a complete identity-identifier encoded
|
||||
* as an uri-path
|
||||
* wheras NETCONF key and value are:
|
||||
* The value of the "key" attribute is the key predicates of the full instance identifier
|
||||
* the "value" attribute MUST also be used to specify an existing entry in the
|
||||
* leaf-list.
|
||||
* This means that api-path is first translated to xpath, and then strip everything
|
||||
* except the key values (or leaf-list values).
|
||||
* Example:
|
||||
* RESTCONF URI: point=%2Fexample-jukebox%3Ajukebox%2Fplaylist%3DFoo-One%2Fsong%3D1
|
||||
* Leaf example:
|
||||
* instance-id: /ex:system/ex:service[ex:name='foo'][ex:enabled='']
|
||||
* NETCONF: yang:key="[ex:name='foo'][ex:enabled='']
|
||||
* Leaf-list example:
|
||||
* instance-id: /ex:system/ex:service[.='foo']
|
||||
* NETCONF: yang:value="foo"
|
||||
*/
|
||||
int
|
||||
restconf_insert_attributes(cxobj *xdata,
|
||||
|
|
@ -570,6 +586,10 @@ restconf_insert_attributes(cxobj *xdata,
|
|||
yang_stmt *y;
|
||||
char *attrname;
|
||||
int ret;
|
||||
char *xpath = NULL;
|
||||
char *namespace = NULL;
|
||||
cbuf *cb = NULL;
|
||||
char *p;
|
||||
|
||||
y = xml_spec(xdata);
|
||||
if ((instr = cvec_find_str(qvec, "insert")) != NULL){
|
||||
|
|
@ -591,9 +611,6 @@ restconf_insert_attributes(cxobj *xdata,
|
|||
goto done;
|
||||
}
|
||||
if ((pstr = cvec_find_str(qvec, "point")) != NULL){
|
||||
char *xpath = NULL;
|
||||
char *namespace = NULL;
|
||||
cbuf *cb = NULL;
|
||||
if (y == NULL){
|
||||
clicon_err(OE_YANG, 0, "Cannot yang resolve %s", xml_name(xdata));
|
||||
goto done;
|
||||
|
|
@ -614,16 +631,36 @@ restconf_insert_attributes(cxobj *xdata,
|
|||
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||
goto done;
|
||||
}
|
||||
cprintf(cb, "/%s", xpath); /* XXX: also prefix/namespace? */
|
||||
if (yang_keyword_get(y) == Y_LIST){
|
||||
/* translate /../x[] --> []*/
|
||||
if ((p = rindex(xpath,'/')) == NULL)
|
||||
p = xpath;
|
||||
p = index(p, '[');
|
||||
cprintf(cb, "%s", p);
|
||||
}
|
||||
else{ /* LEAF_LIST */
|
||||
/* translate /../x[.='x'] --> x */
|
||||
if ((p = rindex(xpath,'\'')) == NULL){
|
||||
clicon_err(OE_YANG, 0, "Translated api->xpath %s->%s not on leaf-list canonical form: ../[.='x']", pstr, xpath);
|
||||
goto done;
|
||||
}
|
||||
*p = '\0';
|
||||
if ((p = rindex(xpath,'\'')) == NULL){
|
||||
clicon_err(OE_YANG, 0, "Translated api->xpath %s->%s not on leaf-list canonical form: ../[.='x']", pstr, xpath);
|
||||
goto done;
|
||||
}
|
||||
p++;
|
||||
cprintf(cb, "%s", p);
|
||||
}
|
||||
if (xml_value_set(xa, cbuf_get(cb)) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (xpath)
|
||||
free(xpath);
|
||||
if (cb)
|
||||
cbuf_free(cb);
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -487,6 +487,15 @@ xml_search(cxobj *xp,
|
|||
* @param[in] key_val Key if LIST and ins is before/after, val if LEAF_LIST
|
||||
* @retval i Order where xn should be inserted into xp:s children
|
||||
* @retval -1 Error
|
||||
* LIST: RFC 7950 7.8.6:
|
||||
* The value of the "key" attribute is the key predicates of the
|
||||
* full instance identifier (see Section 9.13) for the list entry.
|
||||
* This means the value can be [x='a'] but the full instance-id should be prepended,
|
||||
* such as /ex:system/ex:services[x='a']
|
||||
*
|
||||
* LEAF-LIST: RFC7950 7.7.9
|
||||
* yang:insert="after"
|
||||
* yang:value="3des-cbc">blowfish-cbc</cipher>)
|
||||
*/
|
||||
|
||||
static int
|
||||
|
|
@ -501,7 +510,6 @@ xml_insert_userorder(cxobj *xp,
|
|||
int i;
|
||||
cxobj *xc;
|
||||
yang_stmt *yc;
|
||||
char *kludge = ""; /* Cant get instance-id generic of [.. and /.. case */
|
||||
|
||||
switch (ins){
|
||||
case INS_FIRST:
|
||||
|
|
@ -534,7 +542,7 @@ xml_insert_userorder(cxobj *xp,
|
|||
else{
|
||||
switch (yang_keyword_get(yn)){
|
||||
case Y_LEAF_LIST:
|
||||
if ((xc = xpath_first(xp, "%s", key_val)) == NULL)
|
||||
if ((xc = xpath_first(xp, "%s[.='%s']", xml_name(xn),key_val)) == NULL)
|
||||
clicon_err(OE_YANG, 0, "bad-attribute: value, missing-instance: %s", key_val);
|
||||
else {
|
||||
if ((i = xml_child_order(xp, xc)) < 0)
|
||||
|
|
@ -544,10 +552,8 @@ xml_insert_userorder(cxobj *xp,
|
|||
}
|
||||
break;
|
||||
case Y_LIST:
|
||||
if (strlen(key_val) && key_val[0] == '[')
|
||||
kludge = xml_name(xn);
|
||||
if ((xc = xpath_first(xp, "%s%s", kludge, key_val)) == NULL)
|
||||
clicon_err(OE_YANG, 0, "bad-attribute: key, missing-instance: %s%s", xml_name(xn), key_val);
|
||||
if ((xc = xpath_first(xp, "%s%s", xml_name(xn), key_val)) == NULL)
|
||||
clicon_err(OE_YANG, 0, "bad-attribute: key, missing-instance: %s", key_val);
|
||||
else {
|
||||
if ((i = xml_child_order(xp, xc)) < 0)
|
||||
clicon_err(OE_YANG, 0, "internal error xpath found but not in child list");
|
||||
|
|
|
|||
|
|
@ -324,17 +324,17 @@ expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></s
|
|||
|
||||
# before and after and value attribute
|
||||
new "add one leaf-list entry 71 before b"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"before\" yang:value=\"y0[.='b']\">71</y0></config></edit-config></rpc>]]>]]>"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"before\" yang:value=\"b\">71</y0></config></edit-config></rpc>]]>]]>"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$XML" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "add one entry 42 after b"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:value=\"y0[.='b']\">42</y0></config></edit-config></rpc>]]>]]>"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:value=\"b\">42</y0></config></edit-config></rpc>]]>]]>"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$XML" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
# XXX actually not right error message, should be as RFC7950 Sec 15.7
|
||||
new "add one entry 99 after Q (not found, error)"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:value=\"y0[.='Q']\">99</y0></config></edit-config></rpc>]]>]]>"
|
||||
RES="^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>bad-attribute: value, missing-instance: y0\[.='Q'\]</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
XML="<rpc><edit-config><target><candidate/></target><config><y0 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:value=\"Q\">99</y0></config></edit-config></rpc>]]>]]>"
|
||||
RES="^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>bad-attribute: value, missing-instance: Q</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "$XML" "$RES"
|
||||
|
||||
new "check ordered-by-user: e,a,71,b,42,c,d"
|
||||
|
|
@ -384,7 +384,7 @@ expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></
|
|||
|
||||
# XXX actually not right error message, should be as RFC7950 Sec 15.7
|
||||
new "add one entry key 99 after Q (not found, error)"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config><y2 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:key=\"[k='Q']\"><k>99</k><a>bar</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>bad-attribute: key, missing-instance: y2\[k='Q'\]</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc><edit-config><target><candidate/></target><config><y2 xmlns=\"urn:example:order\" xmlns:yang=\"urn:ietf:params:xml:ns:yang:1\" yang:insert=\"after\" yang:key=\"Q\"><k>99</k><a>bar</a></y2></config></edit-config></rpc>]]>]]>" "^<rpc-reply><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>bad-attribute: key, missing-instance: Q</error-message></rpc-error></rpc-reply>]]>]]>$"
|
||||
|
||||
new "check ordered-by-user: e,a,71,b,42,c,d"
|
||||
expecteof "$clixon_netconf -qf $cfg" 0 '<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>' '^<rpc-reply><data><y2 xmlns="urn:example:order"><k>e</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>a</k><a>foo</a></y2><y2 xmlns="urn:example:order"><k>71</k><a>fie</a></y2><y2 xmlns="urn:example:order"><k>b</k><a>bar</a></y2><y2 xmlns="urn:example:order"><k>42</k><a>fum</a></y2><y2 xmlns="urn:example:order"><k>c</k><a>foo</a></y2><y2 xmlns="urn:example:order"><k>d</k><a>fie</a></y2></data></rpc-reply>]]>]]>$'
|
||||
|
|
|
|||
|
|
@ -360,11 +360,11 @@ expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
|
|||
|
||||
new 'B.3.4. "insert" Parameter'
|
||||
JSON="{\"example-jukebox:song\":[{\"index\":1,\"id\":\"/example-jukebox:jukebox/library/artist[name='Foo Fighters']/album[name='Wasting Light']/song[name='Rope']\"}]}"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=first -d "$JSON")" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=first -d "$JSON")" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One/song=1'
|
||||
|
||||
new 'B.3.4. "insert" Parameter first (RFC example says after)'
|
||||
JSON="{\"example-jukebox:song\":[{\"index\":0,\"id\":\"/example-jukebox:jukebox/library/artist[name='Foo Fighters']/album[name='Wasting Light']/song[name='Bridge Burning']\"}]}"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=first -d "$JSON")" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=first -d "$JSON")" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One/song=0'
|
||||
|
||||
new 'B.3.4. "insert" Parameter check order'
|
||||
RES="<playlist xmlns=\"http://example.com/ns/example-jukebox\"><name>Foo-One</name><song><index>0</index><id>/example-jukebox:jukebox/library/artist\[name='Foo Fighters'\]/album\[name='Wasting Light'\]/song\[name='Bridge Burning'\]</id></song><song><index>1</index><id>/example-jukebox:jukebox/library/artist\[name='Foo Fighters'\]/album\[name='Wasting Light'\]/song\[name='Rope'\]</id></song></playlist>"
|
||||
|
|
@ -372,14 +372,12 @@ expectpart "$(curl -s -i -X GET http://localhost/restconf/data/example-jukebox:j
|
|||
|
||||
new 'B.3.5. "point" Parameter (before for more interesting order: 0,2,1)'
|
||||
JSON="{\"example-jukebox:song\":[{\"index\":2,\"id\":\"/example-jukebox:jukebox/library/artist[name='Foo Fighters']/album[name='Wasting Light']/song[name='Bridge Burning']\"}]}"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' -d "$JSON" http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=before\&point=%2Fexample-jukebox%3Ajukebox%2Fplaylist%3DFoo-One%2Fsong%3D1 )" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' -d "$JSON" http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One?insert=before\&point=%2Fexample-jukebox%3Ajukebox%2Fplaylist%3DFoo-One%2Fsong%3D1 )" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One/song=2'
|
||||
|
||||
new 'B.3.5. "point" check order (0,2,1)'
|
||||
RES="<playlist xmlns=\"http://example.com/ns/example-jukebox\"><name>Foo-One</name><song><index>0</index><id>/example-jukebox:jukebox/library/artist\[name='Foo Fighters'\]/album\[name='Wasting Light'\]/song\[name='Bridge Burning'\]</id></song><song><index>2</index><id>/example-jukebox:jukebox/library/artist\[name='Foo Fighters'\]/album\[name='Wasting Light'\]/song\[name='Bridge Burning'\]</id></song><song><index>1</index><id>/example-jukebox:jukebox/library/artist\[name='Foo Fighters'\]/album\[name='Wasting Light'\]/song\[name='Rope'\]</id></song></playlist>"
|
||||
expectpart "$(curl -s -i -X GET http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One -H 'Accept: application/yang-data+xml')" 0 'HTTP/1.1 200 OK' "$RES"
|
||||
|
||||
#XXX 'Location: https://example.com/restconf/data/example-jukebox:jukebox/playlist=Foo-One/song=2'
|
||||
|
||||
new 'B.3.5. "point" Parameter 3 after 2 (using PUT)'
|
||||
JSON="{\"example-jukebox:song\":[{\"index\":3,\"id\":\"/example-jukebox:jukebox/library/artist[name='Foo Fighters']/album[name='Wasting Light']/song[name='Something else']\"}]}"
|
||||
expectpart "$(curl -s -i -X PUT -H 'Content-Type: application/yang-data+json' -d "$JSON" http://localhost/restconf/data/example-jukebox:jukebox/playlist=Foo-One/song=3?insert=after\&point=%2Fexample-jukebox%3Ajukebox%2Fplaylist%3DFoo-One%2Fsong%3D2 )" 0 "HTTP/1.1 201 Created"
|
||||
|
|
@ -392,23 +390,23 @@ new "restconf DELETE whole datastore"
|
|||
expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 ""
|
||||
|
||||
new 'B.3.4. "insert/point" leaf-list 3 (not in RFC)'
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"3"}')" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"3"}')" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:extra=3'
|
||||
|
||||
new 'B.3.4. "insert/point" leaf-list 2 first'
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=first -d '{"example-jukebox:extra":"2"}')" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=first -d '{"example-jukebox:extra":"2"}')" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:extra=2'
|
||||
|
||||
new 'B.3.4. "insert/point" leaf-list 1 last'
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"1"}')" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"1"}')" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:extra=1'
|
||||
|
||||
#new 'B.3.4. "insert/point" move leaf-list 1 last'
|
||||
#- restconf cannot move a leaf-list(list?) item
|
||||
#expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"1"}')" 0 "HTTP/1.1 201 Created"
|
||||
#expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' http://localhost/restconf/data?insert=last -d '{"example-jukebox:extra":"1"}')" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:extra=1'
|
||||
|
||||
new 'B.3.5. "insert/point" leaf-list check order (2,3,1)'
|
||||
expectpart "$(curl -s -i -X GET http://localhost/restconf/data/example-jukebox:extra -H 'Accept: application/yang-data+xml')" 0 'HTTP/1.1 200 OK' '<extra xmlns="http://example.com/ns/example-jukebox">2</extra><extra xmlns="http://example.com/ns/example-jukebox">3</extra><extra xmlns="http://example.com/ns/example-jukebox">1</extra>'
|
||||
|
||||
new 'B.3.5. "point" Parameter leaf-list 4 before 3'
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' -d '{"example-jukebox:extra":"4"}' http://localhost/restconf/data?insert=before\&point=%2Fexample-jukebox%3Aextra%3D3 )" 0 "HTTP/1.1 201 Created"
|
||||
expectpart "$(curl -s -i -X POST -H 'Content-Type: application/yang-data+json' -d '{"example-jukebox:extra":"4"}' http://localhost/restconf/data?insert=before\&point=%2Fexample-jukebox%3Aextra%3D3 )" 0 "HTTP/1.1 201 Created" 'Location: http://localhost/restconf/data/example-jukebox:extra=4'
|
||||
|
||||
new 'B.3.5. "insert/point" leaf-list check order (2,4,3,1)'
|
||||
expectpart "$(curl -s -i -X GET http://localhost/restconf/data/example-jukebox:extra -H 'Accept: application/yang-data+xml')" 0 'HTTP/1.1 200 OK' '<extra xmlns="http://example.com/ns/example-jukebox">2</extra><extra xmlns="http://example.com/ns/example-jukebox">4</extra><extra xmlns="http://example.com/ns/example-jukebox">3</extra><extra xmlns="http://example.com/ns/example-jukebox">1</extra>'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue