Browse Source

Merge branch 'master' of ssh://src.libcode.org/pkun/klish-plugin-sysrepo

Serj Kalichev 3 months ago
parent
commit
f4ffc2cb5a
5 changed files with 178 additions and 23 deletions
  1. 20 8
      bin/srp_load.c
  2. 34 0
      src/klish_plugin_sysrepo.h
  3. 12 0
      src/plugin.c
  4. 90 13
      src/syms.c
  5. 22 2
      xml/sysrepo.xml

+ 20 - 8
bin/srp_load.c

@@ -20,12 +20,14 @@
 
 #define DEFAULT_USER "root"
 #define DEFAULT_DATASTORE SR_DS_CANDIDATE
+#define DEFAULT_OP 's'
 
 typedef struct cmd_opts_s {
 	char *cfg; // Configuration options
 	char *file; // File to load
 	char *user; // NACM user
 	char *current_path; // Current sysrepo path
+	char op; // Operation to execute 's'(set)/'d'(del)
 	bool_t verbose;
 	bool_t stop_on_error;
 	sr_datastore_t datastore;
@@ -78,7 +80,7 @@ int main(int argc, char **argv)
 		faux_argv_parse(cur_path, cmd_opts->current_path);
 	}
 
-	ret = srp_mass_set(fd, cmd_opts->datastore, cur_path,
+	ret = srp_mass_op(cmd_opts->op, fd, cmd_opts->datastore, cur_path,
 		&opts, cmd_opts->user, cmd_opts->stop_on_error);
 
 out:
@@ -104,7 +106,8 @@ static cmd_opts_t *cmd_opts_init(void)
 	opts->stop_on_error = BOOL_FALSE;
 	opts->cfg = NULL;
 	opts->file = NULL;
-	opts->user = NULL;
+	opts->user = faux_str_dup(DEFAULT_USER);
+	opts->op = DEFAULT_OP;
 	opts->datastore = DEFAULT_DATASTORE;
 	opts->current_path = NULL;
 
@@ -127,7 +130,7 @@ static void cmd_opts_free(cmd_opts_t *opts)
 
 static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts)
 {
-	static const char *shortopts = "hf:veu:d:p:";
+	static const char *shortopts = "hf:veu:d:p:o:";
 	static const struct option longopts[] = {
 		{"conf",		1, NULL, 'f'},
 		{"help",		0, NULL, 'h'},
@@ -136,6 +139,7 @@ static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts)
 		{"stop-on-error",	0, NULL, 'e'},
 		{"datastore",		1, NULL, 'd'},
 		{"current-path",	1, NULL, 'p'},
+		{"operation",		1, NULL, 'o'},
 		{NULL,			0, NULL, 0}
 	};
 
@@ -165,6 +169,15 @@ static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts)
 			faux_str_free(opts->cfg);
 			opts->cfg = faux_str_dup(optarg);
 			break;
+		case 'o':
+			opts->op = optarg[0];
+			if ((opts->op != 's') && (opts->op != 'd')) {
+				fprintf(stderr, "Error: Illegal operation '%c'\n",
+					opts->op);
+				help(-1, argv[0]);
+				_exit(-1);
+			}
+			break;
 		case 'd':
 			if (!kly_str2ds(optarg, strlen(optarg), &opts->datastore))
 				return BOOL_FALSE;
@@ -186,10 +199,6 @@ static int cmd_opts_parse(int argc, char *argv[], cmd_opts_t *opts)
 		opts->file = faux_str_dup(argv[optind]);
 	}
 
-	// Validate options
-	if (!opts->user)
-		opts->user = faux_str_dup(DEFAULT_USER);
-
 	return 0;
 }
 
@@ -221,7 +230,10 @@ static void help(int status, const char *argv0)
 		printf("\t-e, --stop-on-error Stop script execution on error\n");
 		printf("\t-u <name>, --user=<name> NACM user name\n");
 		printf("\t-f <path>, --conf=<path> Config file with parsing settings\n");
-		printf("\t-d <ds>, --datastore=<ds> Datastore (Default is 'candidate'\n");
+		printf("\t-o <op>, --operation=<op> Operation to perform\n");
+		printf("\t\t's' Set (default)\n");
+		printf("\t\t'd' Delete\n");
+		printf("\t-d <ds>, --datastore=<ds> Datastore (Default is 'candidate')\n");
 		printf("\t-p <sr-path>, --current-path=<sr-path> Current sysrepo path\n");
 	}
 }

+ 34 - 0
src/klish_plugin_sysrepo.h

@@ -64,6 +64,7 @@ typedef enum {
 	PT_DEL =
 		PAT_CONTAINER |
 		PAT_LIST_KEY |
+		PAT_LIST_KEY_INCOMPLETED |
 		PAT_LEAF |
 		PAT_LEAF_EMPTY |
 		PAT_LEAFLIST |
@@ -114,6 +115,29 @@ typedef enum {
 		PAT_LEAFLIST |
 		PAT_LEAFLIST_VALUE,
 
+	PT_SHOW =
+		PAT_CONTAINER |
+		PAT_LIST |
+		PAT_LIST_KEY |
+		PAT_LIST_KEY_INCOMPLETED |
+		PAT_LEAF |
+		PAT_LEAF_EMPTY |
+		PAT_LEAFLIST |
+		PAT_LEAFLIST_VALUE,
+
+	PT_NOT_SHOW =
+		PAT_LEAF_VALUE,
+
+	PT_COMPL_SHOW =
+		PAT_CONTAINER |
+		PAT_LIST |
+		PAT_LIST_KEY |
+		PAT_LIST_KEY_INCOMPLETED |
+		PAT_LEAF |
+		PAT_LEAF_EMPTY |
+		PAT_LEAFLIST |
+		PAT_LEAFLIST_VALUE,
+
 } pt_e;
 
 
@@ -225,6 +249,8 @@ int srp_PLINE_EDIT(kcontext_t *context);
 int srp_PLINE_EDIT_ABS(kcontext_t *context);
 int srp_PLINE_INSERT_FROM(kcontext_t *context);
 int srp_PLINE_INSERT_TO(kcontext_t *context);
+int srp_PLINE_SHOW(kcontext_t *context);
+int srp_PLINE_SHOW_ABS(kcontext_t *context);
 
 // Completion/Help/Prompt
 int srp_compl(kcontext_t *context);
@@ -243,6 +269,10 @@ int srp_compl_insert_to(kcontext_t *context);
 int srp_help_insert_to(kcontext_t *context);
 int srp_prompt_edit_path(kcontext_t *context);
 int srp_compl_xpath(kcontext_t *context);
+int srp_compl_show(kcontext_t *context);
+int srp_compl_show_abs(kcontext_t *context);
+int srp_help_show(kcontext_t *context);
+int srp_help_show_abs(kcontext_t *context);
 
 // Operations
 int srp_set(kcontext_t *context);
@@ -262,6 +292,10 @@ int srp_deactivate(kcontext_t *context);
 // Service functions
 int srp_mass_set(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
 	const pline_opts_t *opts, const char *user, bool_t stop_on_error);
+int srp_mass_del(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
+	const pline_opts_t *opts, const char *user, bool_t stop_on_error);
+int srp_mass_op(char op, int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
+	const pline_opts_t *opts, const char *user, bool_t stop_on_error);
 
 // Plugin's user-data service functions
 pline_opts_t *srp_udata_opts(kcontext_t *context);

+ 12 - 0
src/plugin.c

@@ -70,6 +70,10 @@ int kplugin_sysrepo_init(kcontext_t *context)
 		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
 	kplugin_add_syms(plugin, ksym_new_ext("PLINE_INSERT_TO", srp_PLINE_INSERT_TO,
 		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("PLINE_SHOW", srp_PLINE_SHOW,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("PLINE_SHOW_ABS", srp_PLINE_SHOW_ABS,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
 
 	// Completion/Help/Prompt
 	kplugin_add_syms(plugin, ksym_new_ext("srp_compl", srp_compl,
@@ -104,6 +108,14 @@ int kplugin_sysrepo_init(kcontext_t *context)
 		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
 	kplugin_add_syms(plugin, ksym_new_ext("srp_compl_xpath", srp_compl_xpath,
 		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("srp_compl_show", srp_compl_show,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("srp_compl_show_abs", srp_compl_show_abs,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("srp_help_show", srp_help_show,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("srp_help_show_abs", srp_help_show_abs,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
 
 	// Operations
 	kplugin_add_syms(plugin, ksym_new_ext("srp_set", srp_set,

+ 90 - 13
src/syms.c

@@ -195,6 +195,30 @@ int srp_help_insert(kcontext_t *context)
 }
 
 
+int srp_compl_show(kcontext_t *context)
+{
+	return srp_compl_or_help(context, BOOL_FALSE, PT_COMPL_SHOW, BOOL_TRUE, BOOL_TRUE);
+}
+
+
+int srp_compl_show_abs(kcontext_t *context)
+{
+	return srp_compl_or_help(context, BOOL_FALSE, PT_COMPL_SHOW, BOOL_FALSE, BOOL_TRUE);
+}
+
+
+int srp_help_show(kcontext_t *context)
+{
+	return srp_compl_or_help(context, BOOL_TRUE, PT_COMPL_SHOW, BOOL_TRUE, BOOL_TRUE);
+}
+
+
+int srp_help_show_abs(kcontext_t *context)
+{
+	return srp_compl_or_help(context, BOOL_TRUE, PT_COMPL_SHOW, BOOL_FALSE, BOOL_TRUE);
+}
+
+
 int srp_prompt_edit_path(kcontext_t *context)
 {
 	faux_argv_t *cur_path = NULL;
@@ -289,6 +313,18 @@ int srp_PLINE_INSERT_FROM(kcontext_t *context)
 }
 
 
+int srp_PLINE_SHOW(kcontext_t *context)
+{
+	return srp_check_type(context, PT_NOT_SHOW, 1, BOOL_TRUE);
+}
+
+
+int srp_PLINE_SHOW_ABS(kcontext_t *context)
+{
+	return srp_check_type(context, PT_NOT_SHOW, 1, BOOL_FALSE);
+}
+
+
 static faux_argv_t *assemble_insert_to(sr_session_ctx_t *sess, const kpargv_t *pargv,
 	faux_argv_t *cur_path, const char *candidate_value, pline_opts_t *opts)
 {
@@ -920,7 +956,7 @@ static int show(kcontext_t *context, sr_datastore_t ds,
 			fprintf(stderr, ERRORMSG "Can't get expression\n");
 			goto err;
 		}
-		if (!(expr->pat & PT_EDIT)) {
+		if (!(expr->pat & PT_SHOW)) {
 			fprintf(stderr, ERRORMSG "Illegal expression for 'show' operation\n");
 			goto err;
 		}
@@ -1184,10 +1220,8 @@ int srp_compl_xpath(kcontext_t *context)
 }
 
 
-// Function for mass config strings load. It can load stream of KPath strings
-// (without "set" command, only path and value). Function doesn't use
-// pre-connected session because it can be executed within FILTER or utility.
-int srp_mass_set(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
+// Function for mass operations.
+int srp_mass_op(char op, int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
 	const pline_opts_t *opts, const char *user, bool_t stop_on_error)
 {
 	int ret = -1;
@@ -1254,15 +1288,38 @@ int srp_mass_set(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
 
 			iter = faux_list_head(pline->exprs);
 			while ((expr = (pexpr_t *)faux_list_each(&iter))) {
-				if (!(expr->pat & PT_SET)) {
-					err_num++;
-					fprintf(stderr, "Error: Illegal expression for set operation\n");
-					break;
-				}
-				if (sr_set_item_str(sess, expr->xpath, expr->value, NULL, 0) !=
-					SR_ERR_OK) {
+				// Set
+				if (op == 's') {
+					if (!(expr->pat & PT_SET)) {
+						err_num++;
+						fprintf(stderr, "Error: Illegal expression"
+							" for set operation\n");
+						break;
+					}
+					if (sr_set_item_str(sess, expr->xpath,
+						expr->value, NULL, 0) != SR_ERR_OK) {
+						err_num++;
+						fprintf(stderr, "Error: Can't set data\n");
+						break;
+					}
+				// Del
+				} else if (op == 'd') {
+					if (!(expr->pat & PT_DEL)) {
+						err_num++;
+						fprintf(stderr, "Error: Illegal expression"
+							" for del operation\n");
+						break;
+					}
+					if (sr_delete_item(sess, expr->xpath, 0) !=
+						SR_ERR_OK) {
+						err_num++;
+						fprintf(stderr, "Error: Can't del data\n");
+						break;
+					}
+				} else {
 					err_num++;
-					fprintf(stderr, "Error: Can't set data\n");
+					fprintf(stderr, "Error: Illegal operation '%c'\n",
+						op);
 					break;
 				}
 			}
@@ -1294,3 +1351,23 @@ out:
 
 	return ret;
 }
+
+
+// Function for mass config strings load. It can load stream of KPath strings
+// (without "set" command, only path and value). Function doesn't use
+// pre-connected session because it can be executed within FILTER or utility.
+int srp_mass_set(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
+	const pline_opts_t *opts, const char *user, bool_t stop_on_error)
+{
+	return srp_mass_op('s', fd, ds, cur_path, opts, user, stop_on_error);
+}
+
+
+// Function for mass config strings deletion. It can get stream of KPath strings
+// (without "del" command, only path). Function doesn't use
+// pre-connected session because it can be executed within FILTER or utility.
+int srp_mass_del(int fd, sr_datastore_t ds, const faux_argv_t *cur_path,
+	const pline_opts_t *opts, const char *user, bool_t stop_on_error)
+{
+	return srp_mass_op('d', fd, ds, cur_path, opts, user, stop_on_error);
+}

+ 22 - 2
xml/sysrepo.xml

@@ -79,6 +79,26 @@
 	<ACTION sym="PLINE_INSERT_TO@sysrepo"/>
 </PTYPE>
 
+<PTYPE name="PLINE_SHOW">
+	<COMPL>
+		<ACTION sym="srp_compl_show@sysrepo"/>
+	</COMPL>
+	<HELP>
+		<ACTION sym="srp_help_show@sysrepo"/>
+	</HELP>
+	<ACTION sym="PLINE_SHOW@sysrepo"/>
+</PTYPE>
+
+<PTYPE name="PLINE_SHOW_ABS">
+	<COMPL>
+		<ACTION sym="srp_compl_show_abs@sysrepo"/>
+	</COMPL>
+	<HELP>
+		<ACTION sym="srp_help_show_abs@sysrepo"/>
+	</HELP>
+	<ACTION sym="PLINE_SHOW_ABS@sysrepo"/>
+</PTYPE>
+
 
 <VIEW name="main">
 
@@ -88,7 +108,7 @@
 
 	<COMMAND name="show" help="Show" mode="switch">
 		<COMMAND name="running" help="Show running-config">
-			<PARAM name="path" ptype="/PLINE_EDIT_ABS" min="0" max="100"/>
+			<PARAM name="path" ptype="/PLINE_SHOW_ABS" min="0" max="100"/>
 			<ACTION sym="srp_show_abs@sysrepo">running</ACTION>
 		</COMMAND>
 	</COMMAND>
@@ -168,7 +188,7 @@
 	</COMMAND>
 
 	<COMMAND name="show" help="Show data hierarchy">
-		<PARAM name="path" ptype="/PLINE_EDIT" min="0" max="100"/>
+		<PARAM name="path" ptype="/PLINE_SHOW" min="0" max="100"/>
 		<ACTION sym="srp_show@sysrepo"/>
 	</COMMAND>