three-valued return values for datastore text_modify
This commit is contained in:
parent
32ea957a52
commit
6c48165340
4 changed files with 63 additions and 37 deletions
|
|
@ -285,7 +285,7 @@ candidate_commit(clicon_handle h,
|
||||||
|
|
||||||
/* Optionally write (potentially modified) tree back to candidate */
|
/* Optionally write (potentially modified) tree back to candidate */
|
||||||
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){
|
if (clicon_option_bool(h, "CLICON_TRANSACTION_MOD")){
|
||||||
if ((ret = xmldb_put(h, candidate, OP_REPLACE, td->td_target, NULL)) < 0)
|
if ((ret = xmldb_put(h, candidate, OP_REPLACE, td->td_target, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
|
|
@ -572,7 +572,10 @@ text_get(xmldb_handle xh,
|
||||||
* @param[in] x0p Parent of x0
|
* @param[in] x0p Parent of x0
|
||||||
* @param[in] x1 xml tree which modifies base
|
* @param[in] x1 xml tree which modifies base
|
||||||
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
||||||
* @param[out] cbret Initialized cligen buffer. Contains return XML or "".
|
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
||||||
|
* @retval -1 Error
|
||||||
|
* @retval 0 Failed (cbret set)
|
||||||
|
* @retval 1 OK
|
||||||
* Assume x0 and x1 are same on entry and that y is the spec
|
* Assume x0 and x1 are same on entry and that y is the spec
|
||||||
* @see text_modify_top
|
* @see text_modify_top
|
||||||
*/
|
*/
|
||||||
|
|
@ -598,6 +601,7 @@ text_modify(struct text_handle *th,
|
||||||
yang_stmt *yc; /* yang child */
|
yang_stmt *yc; /* yang child */
|
||||||
cxobj **x0vec = NULL;
|
cxobj **x0vec = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
assert(x1 && xml_type(x1) == CX_ELMNT);
|
assert(x1 && xml_type(x1) == CX_ELMNT);
|
||||||
assert(y0);
|
assert(y0);
|
||||||
|
|
@ -613,7 +617,7 @@ text_modify(struct text_handle *th,
|
||||||
if (x0){
|
if (x0){
|
||||||
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
|
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_NONE: /* fall thru */
|
case OP_NONE: /* fall thru */
|
||||||
case OP_MERGE:
|
case OP_MERGE:
|
||||||
|
|
@ -658,7 +662,7 @@ text_modify(struct text_handle *th,
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_REMOVE: /* fall thru */
|
case OP_REMOVE: /* fall thru */
|
||||||
if (x0){
|
if (x0){
|
||||||
|
|
@ -675,7 +679,7 @@ text_modify(struct text_handle *th,
|
||||||
if (x0){
|
if (x0){
|
||||||
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
|
if (netconf_data_exists(cbret, "Data already exists; cannot create new resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_REPLACE: /* fall thru */
|
case OP_REPLACE: /* fall thru */
|
||||||
if (x0){
|
if (x0){
|
||||||
|
|
@ -738,18 +742,18 @@ text_modify(struct text_handle *th,
|
||||||
while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL) {
|
while ((x1c = xml_child_each(x1, x1c, CX_ELMNT)) != NULL) {
|
||||||
x1cname = xml_name(x1c);
|
x1cname = xml_name(x1c);
|
||||||
yc = yang_find_datanode(y0, x1cname);
|
yc = yang_find_datanode(y0, x1cname);
|
||||||
if (text_modify(th, x0vec[i++], (yang_node*)yc, x0, x1c, op, cbret) < 0)
|
if ((ret = text_modify(th, x0vec[i++], (yang_node*)yc, x0, x1c, op, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
||||||
if (cbuf_len(cbret))
|
if (ret == 0)
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (x0==NULL){
|
if (x0==NULL){
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
case OP_REMOVE: /* fall thru */
|
case OP_REMOVE: /* fall thru */
|
||||||
if (x0)
|
if (x0)
|
||||||
|
|
@ -760,21 +764,26 @@ text_modify(struct text_handle *th,
|
||||||
} /* CONTAINER switch op */
|
} /* CONTAINER switch op */
|
||||||
} /* else Y_CONTAINER */
|
} /* else Y_CONTAINER */
|
||||||
xml_sort(x0p, NULL);
|
xml_sort(x0p, NULL);
|
||||||
ok:
|
retval = 1;
|
||||||
retval = 0;
|
|
||||||
done:
|
done:
|
||||||
if (x0vec)
|
if (x0vec)
|
||||||
free(x0vec);
|
free(x0vec);
|
||||||
return retval;
|
return retval;
|
||||||
|
fail: /* cbret set */
|
||||||
|
retval = 0;
|
||||||
|
goto done;
|
||||||
} /* text_modify */
|
} /* text_modify */
|
||||||
|
|
||||||
/*! Modify a top-level base tree x0 with modification tree x1
|
/*! Modify a top-level base tree x0 with modification tree x1
|
||||||
* @param[in] th text handle
|
* @param[in] th text handle
|
||||||
* @param[in] x0 Base xml tree (can be NULL in add scenarios)
|
* @param[in] x0 Base xml tree (can be NULL in add scenarios)
|
||||||
* @param[in] x1 xml tree which modifies base
|
* @param[in] x1 xml tree which modifies base
|
||||||
* @param[in] yspec Top-level yang spec (if y is NULL)
|
* @param[in] yspec Top-level yang spec (if y is NULL)
|
||||||
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
* @param[in] op OP_MERGE, OP_REPLACE, OP_REMOVE, etc
|
||||||
* @param[out] cbret Initialized cligen buffer. Contains return XML or "".
|
* @param[out] cbret Initialized cligen buffer. Contains return XML if retval is 0.
|
||||||
|
* @retval -1 Error
|
||||||
|
* @retval 0 Failed (cbret set)
|
||||||
|
* @retval 1 OK
|
||||||
* @see text_modify
|
* @see text_modify
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
|
|
@ -792,6 +801,7 @@ text_modify_top(struct text_handle *th,
|
||||||
yang_stmt *yc; /* yang child */
|
yang_stmt *yc; /* yang child */
|
||||||
yang_stmt *ymod;/* yang module */
|
yang_stmt *ymod;/* yang module */
|
||||||
char *opstr;
|
char *opstr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* Assure top-levels are 'config' */
|
/* Assure top-levels are 'config' */
|
||||||
assert(x0 && strcmp(xml_name(x0),"config")==0);
|
assert(x0 && strcmp(xml_name(x0),"config")==0);
|
||||||
|
|
@ -820,7 +830,7 @@ text_modify_top(struct text_handle *th,
|
||||||
case OP_DELETE:
|
case OP_DELETE:
|
||||||
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
if (netconf_data_missing(cbret, "Data does not exist; cannot delete resource") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -849,21 +859,24 @@ text_modify_top(struct text_handle *th,
|
||||||
if (yc == NULL){
|
if (yc == NULL){
|
||||||
if (netconf_unknown_element(cbret, "application", x1cname, "Unassigned yang spec") < 0)
|
if (netconf_unknown_element(cbret, "application", x1cname, "Unassigned yang spec") < 0)
|
||||||
goto done;
|
goto done;
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
/* See if there is a corresponding node in the base tree */
|
/* See if there is a corresponding node in the base tree */
|
||||||
if (match_base_child(x0, x1c, &x0c, yc) < 0)
|
if (match_base_child(x0, x1c, &x0c, yc) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, cbret) < 0)
|
if ((ret = text_modify(th, x0c, (yang_node*)yc, x0, x1c, op, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
||||||
if (cbuf_len(cbret))
|
if (ret == 0)
|
||||||
goto ok;
|
goto fail;
|
||||||
}
|
}
|
||||||
ok:
|
// ok:
|
||||||
retval = 0;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
|
fail: /* cbret set */
|
||||||
|
retval = 0;
|
||||||
|
goto done;
|
||||||
} /* text_modify_top */
|
} /* text_modify_top */
|
||||||
|
|
||||||
/*! For containers without presence and no children(except attrs), remove
|
/*! For containers without presence and no children(except attrs), remove
|
||||||
|
|
@ -923,14 +936,11 @@ text_put(xmldb_handle xh,
|
||||||
yang_spec *yspec;
|
yang_spec *yspec;
|
||||||
cxobj *x0 = NULL;
|
cxobj *x0 = NULL;
|
||||||
struct db_element *de = NULL;
|
struct db_element *de = NULL;
|
||||||
int cbretlocal = 0; /* Set if cbret is NULL on entry */
|
int ret;
|
||||||
|
|
||||||
if (cbret == NULL){
|
if (cbret == NULL){
|
||||||
if ((cbret = cbuf_new()) == NULL){
|
clicon_err(OE_XML, EINVAL, "cbret is NULL");
|
||||||
clicon_err(OE_XML, errno, "cbuf_new");
|
goto done;
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
cbretlocal++;
|
|
||||||
}
|
}
|
||||||
if ((yspec = th->th_yangspec) == NULL){
|
if ((yspec = th->th_yangspec) == NULL){
|
||||||
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
clicon_err(OE_YANG, ENOENT, "No yang spec");
|
||||||
|
|
@ -991,10 +1001,10 @@ text_put(xmldb_handle xh,
|
||||||
* Modify base tree x with modification x1. This is where the
|
* Modify base tree x with modification x1. This is where the
|
||||||
* new tree is made.
|
* new tree is made.
|
||||||
*/
|
*/
|
||||||
if (text_modify_top(th, x0, x1, yspec, op, cbret) < 0)
|
if ((ret = text_modify_top(th, x0, x1, yspec, op, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
/* If xml return - ie netconf error xml tree, then stop and return OK */
|
||||||
if (cbuf_len(cbret))
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Remove NONE nodes if all subs recursively are also NONE */
|
/* Remove NONE nodes if all subs recursively are also NONE */
|
||||||
|
|
@ -1047,8 +1057,6 @@ text_put(xmldb_handle xh,
|
||||||
goto done;
|
goto done;
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
if (cbretlocal && cbret)
|
|
||||||
cbuf_free(cbret);
|
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (dbfile)
|
if (dbfile)
|
||||||
|
|
@ -1408,6 +1416,8 @@ main(int argc,
|
||||||
char *yangmod; /* yang file */
|
char *yangmod; /* yang file */
|
||||||
yang_spec *yspec = NULL;
|
yang_spec *yspec = NULL;
|
||||||
clicon_handle h;
|
clicon_handle h;
|
||||||
|
cbuf *cbret = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if ((h = clicon_handle_init()) == NULL)
|
if ((h = clicon_handle_init()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -1456,13 +1466,21 @@ main(int argc,
|
||||||
op = OP_REMOVE;
|
op = OP_REMOVE;
|
||||||
else
|
else
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
if (xmldb_put(h, db, op, NULL, xn, NULL) < 1)
|
if ((cbret = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
if ((ret = xmldb_put(h, db, op, NULL, xn, cbret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
fprintf(stderr, "%s\n", cbuf_get(cbret));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
done:
|
done:
|
||||||
|
if (cbret)
|
||||||
|
cbuf_free(cbret);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -260,6 +260,7 @@ example_reset(clicon_handle h,
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
cbuf *cbret = NULL;
|
||||||
|
|
||||||
if (xml_parse_string("<config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface>"
|
if (xml_parse_string("<config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface>"
|
||||||
"<name>lo</name><type>ex:loopback</type>"
|
"<name>lo</name><type>ex:loopback</type>"
|
||||||
|
|
@ -268,15 +269,22 @@ example_reset(clicon_handle h,
|
||||||
/* Replace parent w first child */
|
/* Replace parent w first child */
|
||||||
if (xml_rootchild(xt, 0, &xt) < 0)
|
if (xml_rootchild(xt, 0, &xt) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if ((cbret = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
/* Merge user reset state */
|
/* Merge user reset state */
|
||||||
if ((ret = xmldb_put(h, (char*)db, OP_MERGE, xt, NULL)) < 0)
|
if ((ret = xmldb_put(h, (char*)db, OP_MERGE, xt, cbret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
clicon_err(OE_XML, 0, "Error when writing to XML database");
|
clicon_err(OE_XML, 0, "Error when writing to XML database: %s",
|
||||||
|
cbuf_get(cbret));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
if (cbret)
|
||||||
|
cbuf_free(cbret);
|
||||||
if (xt != NULL)
|
if (xt != NULL)
|
||||||
xml_free(xt);
|
xml_free(xt);
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ xmldb_get(clicon_handle h,
|
||||||
* @param[in] db running or candidate
|
* @param[in] db running or candidate
|
||||||
* @param[in] op Top-level operation, can be superceded by other op in tree
|
* @param[in] op Top-level operation, can be superceded by other op in tree
|
||||||
* @param[in] xt xml-tree. Top-level symbol is dummy
|
* @param[in] xt xml-tree. Top-level symbol is dummy
|
||||||
* @param[out] cbret Initialized cligen buffer or NULL. On exit contains XML or "".
|
* @param[out] cbret Initialized cligen buffer. On exit contains XML if retval == 0
|
||||||
* @retval 1 OK
|
* @retval 1 OK
|
||||||
* @retval 0 Failed, cbret contains error xml message
|
* @retval 0 Failed, cbret contains error xml message
|
||||||
* @retval -1 Error
|
* @retval -1 Error
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue