Ongoing: xmldb datastore plugin framework
This commit is contained in:
parent
05edace630
commit
4169bd8d30
18 changed files with 2588 additions and 1924 deletions
|
|
@ -29,6 +29,8 @@
|
||||||
#
|
#
|
||||||
# ***** END LICENSE BLOCK *****
|
# ***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
- Ongoiing: xmldb datastore plugin framework
|
||||||
|
|
||||||
- cli_copy_config added as generic cli command
|
- cli_copy_config added as generic cli command
|
||||||
- cli_show_config added as generic cli command
|
- cli_show_config added as generic cli command
|
||||||
Replace all show_confv*() and show_conf*() with cli_show_config()
|
Replace all show_confv*() and show_conf*() with cli_show_config()
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ LIBS = @LIBS@
|
||||||
INCLUDES = -I. -I@srcdir@ @INCLUDES@
|
INCLUDES = -I. -I@srcdir@ @INCLUDES@
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
SUBDIRS = lib apps include etc
|
SUBDIRS = lib apps include etc datastore
|
||||||
|
|
||||||
.PHONY: doc all clean depend $(SUBDIRS) install loc TAGS .config.status docker
|
.PHONY: doc all clean depend $(SUBDIRS) install loc TAGS .config.status docker
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
#include "backend_handle.h"
|
#include "backend_handle.h"
|
||||||
|
|
||||||
/* Command line options to be passed to getopt(3) */
|
/* Command line options to be passed to getopt(3) */
|
||||||
#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc:rg:pty:"
|
#define BACKEND_OPTS "hD:f:d:Fzu:P:1IRCc:rg:pty:x:"
|
||||||
|
|
||||||
/*! Terminate. Cannot use h after this */
|
/*! Terminate. Cannot use h after this */
|
||||||
static int
|
static int
|
||||||
|
|
@ -143,7 +143,8 @@ usage(char *argv0, clicon_handle h)
|
||||||
" -p \t\tPrint database yang specification\n"
|
" -p \t\tPrint database yang specification\n"
|
||||||
" -t \t\tPrint alternate spec translation (eg if YANG print KEY, if KEY print YANG)\n"
|
" -t \t\tPrint alternate spec translation (eg if YANG print KEY, if KEY print YANG)\n"
|
||||||
" -g <group>\tClient membership required to this group (default: %s)\n"
|
" -g <group>\tClient membership required to this group (default: %s)\n"
|
||||||
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n",
|
"\t-y <file>\tOverride yang spec file (dont include .yang suffix)\n"
|
||||||
|
"\t-x <plugin>\tXMLDB plugin\n",
|
||||||
argv0,
|
argv0,
|
||||||
plgdir ? plgdir : "none",
|
plgdir ? plgdir : "none",
|
||||||
confsock ? confsock : "none",
|
confsock ? confsock : "none",
|
||||||
|
|
@ -314,6 +315,7 @@ main(int argc, char **argv)
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
char *sock;
|
char *sock;
|
||||||
int sockfamily;
|
int sockfamily;
|
||||||
|
char *xmldb_plugin;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & syslog and debug flag set later */
|
/* In the startup, logs to stderr & syslog and debug flag set later */
|
||||||
|
|
||||||
|
|
@ -437,6 +439,10 @@ main(int argc, char **argv)
|
||||||
clicon_option_str_set(h, "CLICON_YANG_DIR", strdup(dir));
|
clicon_option_str_set(h, "CLICON_YANG_DIR", strdup(dir));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'x' :{ /* xmldb plugin */
|
||||||
|
clicon_option_str_set(h, "CLICON_XMLDB_PLUGIN", optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
usage(argv[0], h);
|
usage(argv[0], h);
|
||||||
break;
|
break;
|
||||||
|
|
@ -502,6 +508,13 @@ main(int argc, char **argv)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((xmldb_plugin = clicon_xmldb_plugin(h)) == NULL){
|
||||||
|
clicon_log(LOG_ERR, "No xmldb plugin given (specify option CLICON_XMLDB_PLUGIN).\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (xmldb_plugin_load(xmldb_plugin) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* Parse db spec file */
|
/* Parse db spec file */
|
||||||
if (yang_spec_main(h, stdout, printspec) < 0)
|
if (yang_spec_main(h, stdout, printspec) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
4
configure
vendored
4
configure
vendored
|
|
@ -4315,7 +4315,7 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile lib/Makefile lib/src/Makefile lib/clixon/Makefile apps/Makefile apps/cli/Makefile apps/backend/Makefile apps/netconf/Makefile apps/restconf/Makefile apps/dbctrl/Makefile include/Makefile etc/Makefile etc/clixonrc example/Makefile example/docker/Makefile docker/Makefile docker/cli/Makefile docker/cli/Dockerfile docker/backend/Makefile docker/backend/Dockerfile docker/netconf/Makefile docker/netconf/Dockerfile doc/Makefile"
|
ac_config_files="$ac_config_files Makefile lib/Makefile lib/src/Makefile lib/clixon/Makefile apps/Makefile apps/cli/Makefile apps/backend/Makefile apps/netconf/Makefile apps/restconf/Makefile apps/dbctrl/Makefile include/Makefile etc/Makefile etc/clixonrc example/Makefile example/docker/Makefile docker/Makefile docker/cli/Makefile docker/cli/Dockerfile docker/backend/Makefile docker/backend/Dockerfile docker/netconf/Makefile docker/netconf/Dockerfile datastore/Makefile datastore/keyvalue/Makefile doc/Makefile"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
|
|
@ -5030,6 +5030,8 @@ do
|
||||||
"docker/backend/Dockerfile") CONFIG_FILES="$CONFIG_FILES docker/backend/Dockerfile" ;;
|
"docker/backend/Dockerfile") CONFIG_FILES="$CONFIG_FILES docker/backend/Dockerfile" ;;
|
||||||
"docker/netconf/Makefile") CONFIG_FILES="$CONFIG_FILES docker/netconf/Makefile" ;;
|
"docker/netconf/Makefile") CONFIG_FILES="$CONFIG_FILES docker/netconf/Makefile" ;;
|
||||||
"docker/netconf/Dockerfile") CONFIG_FILES="$CONFIG_FILES docker/netconf/Dockerfile" ;;
|
"docker/netconf/Dockerfile") CONFIG_FILES="$CONFIG_FILES docker/netconf/Dockerfile" ;;
|
||||||
|
"datastore/Makefile") CONFIG_FILES="$CONFIG_FILES datastore/Makefile" ;;
|
||||||
|
"datastore/keyvalue/Makefile") CONFIG_FILES="$CONFIG_FILES datastore/keyvalue/Makefile" ;;
|
||||||
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
|
"doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
|
||||||
|
|
||||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
|
||||||
|
|
|
||||||
|
|
@ -201,6 +201,8 @@ AC_OUTPUT(Makefile
|
||||||
docker/backend/Dockerfile
|
docker/backend/Dockerfile
|
||||||
docker/netconf/Makefile
|
docker/netconf/Makefile
|
||||||
docker/netconf/Dockerfile
|
docker/netconf/Dockerfile
|
||||||
|
datastore/Makefile
|
||||||
|
datastore/keyvalue/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
78
datastore/Makefile.in
Normal file
78
datastore/Makefile.in
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
#
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||||
|
#
|
||||||
|
# This file is part of CLIXON
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
# in which case the provisions of the GPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of the GPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of Apache License version 2,
|
||||||
|
# indicate your decision by deleting the provisions above and replace them with
|
||||||
|
# the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
VPATH = @srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
CC = @CC@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
SUBDIRS = keyvalue
|
||||||
|
|
||||||
|
.PHONY: all clean depend install $(SUBDIRS)
|
||||||
|
|
||||||
|
all: $(SUBDIRS)
|
||||||
|
|
||||||
|
depend:
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i; $(MAKE) $(MFLAGS) $@); done
|
||||||
|
|
||||||
|
$(SUBDIRS):
|
||||||
|
(cd $@; $(MAKE) $(MFLAGS) all)
|
||||||
|
|
||||||
|
install-include:
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i ; $(MAKE) $(MFLAGS) $@); done;
|
||||||
|
|
||||||
|
install:
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i; $(MAKE) $(MFLAGS) $@); done
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i; $(MAKE) $(MFLAGS) $@); done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i; $(MAKE) $(MFLAGS) $@); done
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile *~ .depend
|
||||||
|
for i in $(SUBDIRS); \
|
||||||
|
do (cd $$i; $(MAKE) $(MFLAGS) $@); done
|
||||||
|
|
||||||
|
tags:
|
||||||
|
find $(srcdir) -name '*.[chyl]' -print | etags -
|
||||||
100
datastore/keyvalue/Makefile.in
Normal file
100
datastore/keyvalue/Makefile.in
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
#
|
||||||
|
# ***** BEGIN LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
# Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||||
|
#
|
||||||
|
# This file is part of CLIXON
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# Alternatively, the contents of this file may be used under the terms of
|
||||||
|
# the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
# in which case the provisions of the GPL are applicable instead
|
||||||
|
# of those above. If you wish to allow use of your version of this file only
|
||||||
|
# under the terms of the GPL, and not to allow others to
|
||||||
|
# use your version of this file under the terms of Apache License version 2,
|
||||||
|
# indicate your decision by deleting the provisions above and replace them with
|
||||||
|
# the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
# the provisions above, a recipient may use your version of this file under
|
||||||
|
# the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
#
|
||||||
|
# ***** END LICENSE BLOCK *****
|
||||||
|
#
|
||||||
|
prefix = @prefix@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
bindir = @bindir@
|
||||||
|
libdir = @libdir@
|
||||||
|
dbdir = @prefix@/db
|
||||||
|
mandir = @mandir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
CC = @CC@
|
||||||
|
CFLAGS = @CFLAGS@ -rdynamic -fPIC
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
DATASTORE = keyvalue
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
|
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
|
||||||
|
|
||||||
|
PLUGIN = $(DATASTORE).so
|
||||||
|
|
||||||
|
SRC = clixon_keyvalue.c clixon_qdb.c
|
||||||
|
|
||||||
|
OBJS = $(SRC:.c=.o)
|
||||||
|
|
||||||
|
all: $(PLUGIN)
|
||||||
|
|
||||||
|
-include $(DESTDIR)$(datarootdir)/clixon/clixon.mk
|
||||||
|
|
||||||
|
#grideye_sysinfo.so.1: grideye_sysinfo.c
|
||||||
|
# $(CC) $(CFLAGS) -shared -o $@ -lc $^ -lm
|
||||||
|
|
||||||
|
$(PLUGIN): $(SRC)
|
||||||
|
$(CC) $(CPPFLAGS) $(INCLUDES) $(CFLAGS) -shared -o $@ -lc $^ $(LIBS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(PLUGIN) $(OBJS) *.core
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile *~ .depend
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .c .o
|
||||||
|
|
||||||
|
.c.o: $(SRC)
|
||||||
|
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
install: $(PLUGIN)
|
||||||
|
install -d $(DESTDIR)$(clixon_LIBDIR)/xmldb
|
||||||
|
install $(PLUGIN) $(DESTDIR)$(clixon_LIBDIR)/xmldb;
|
||||||
|
|
||||||
|
install-include:
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -rf $(DESTDIR)$(clixon_LIBDIR)/xmldb/$(PLUGIN);
|
||||||
|
|
||||||
|
TAGS:
|
||||||
|
find . -name '*.[chyl]' -print | etags -
|
||||||
|
|
||||||
|
depend:
|
||||||
|
$(CC) $(DEPENDFLAGS) @DEFS@ $(INCLUDES) $(CFLAGS) -MM $(SRC) > .depend
|
||||||
|
|
||||||
|
#include .depend
|
||||||
|
|
||||||
1746
datastore/keyvalue/clixon_keyvalue.c
Normal file
1746
datastore/keyvalue/clixon_keyvalue.c
Normal file
File diff suppressed because it is too large
Load diff
56
datastore/keyvalue/clixon_keyvalue.h
Normal file
56
datastore/keyvalue/clixon_keyvalue.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
***** BEGIN LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Copyright (C) 2009-2017 Olof Hagsand and Benny Holmgren
|
||||||
|
|
||||||
|
This file is part of CLIXON.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of
|
||||||
|
the GNU General Public License Version 3 or later (the "GPL"),
|
||||||
|
in which case the provisions of the GPL are applicable instead
|
||||||
|
of those above. If you wish to allow use of your version of this file only
|
||||||
|
under the terms of the GPL, and not to allow others to
|
||||||
|
use your version of this file under the terms of Apache License version 2,
|
||||||
|
indicate your decision by deleting the provisions above and replace them with
|
||||||
|
the notice and other provisions required by the GPL. If you do not delete
|
||||||
|
the provisions above, a recipient may use your version of this file under
|
||||||
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
|
Key-value store
|
||||||
|
*/
|
||||||
|
#ifndef _CLIXON_KEYVALUE_H
|
||||||
|
#define _CLIXON_KEYVALUE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prototypes
|
||||||
|
*/
|
||||||
|
int kv_get(clicon_handle h, char *db, char *xpath,
|
||||||
|
cxobj **xtop, cxobj ***xvec, size_t *xlen);
|
||||||
|
int kv_put(clicon_handle h, char *db, enum operation_type op,
|
||||||
|
char *api_path, cxobj *xt);
|
||||||
|
int kv_dump(FILE *f, char *dbfilename, char *rxkey);
|
||||||
|
int kv_copy(clicon_handle h, char *from, char *to);
|
||||||
|
int kv_lock(clicon_handle h, char *db, int pid);
|
||||||
|
int kv_unlock(clicon_handle h, char *db, int pid);
|
||||||
|
int kv_unlock_all(clicon_handle h, int pid);
|
||||||
|
int kv_islocked(clicon_handle h, char *db);
|
||||||
|
int kv_exists(clicon_handle h, char *db);
|
||||||
|
int kv_delete(clicon_handle h, char *db);
|
||||||
|
int kv_init(clicon_handle h, char *db);
|
||||||
|
|
||||||
|
#endif /* _CLIXON_KEYVALUE_H */
|
||||||
|
|
@ -93,6 +93,7 @@ char *clicon_clispec_dir(clicon_handle h);
|
||||||
char *clicon_netconf_dir(clicon_handle h);
|
char *clicon_netconf_dir(clicon_handle h);
|
||||||
char *clicon_restconf_dir(clicon_handle h);
|
char *clicon_restconf_dir(clicon_handle h);
|
||||||
char *clicon_archive_dir(clicon_handle h);
|
char *clicon_archive_dir(clicon_handle h);
|
||||||
|
char *clicon_xmldb_plugin(clicon_handle h);
|
||||||
int clicon_sock_family(clicon_handle h);
|
int clicon_sock_family(clicon_handle h);
|
||||||
char *clicon_sock(clicon_handle h);
|
char *clicon_sock(clicon_handle h);
|
||||||
int clicon_sock_port(clicon_handle h);
|
int clicon_sock_port(clicon_handle h);
|
||||||
|
|
|
||||||
|
|
@ -30,18 +30,83 @@
|
||||||
the terms of any one of the Apache License version 2 or the GPL.
|
the terms of any one of the Apache License version 2 or the GPL.
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
|
|
||||||
* XML support functions.
|
|
||||||
*/
|
*/
|
||||||
#ifndef _CLIXON_XML_DB_H
|
#ifndef _CLIXON_XML_DB_H
|
||||||
#define _CLIXON_XML_DB_H
|
#define _CLIXON_XML_DB_H
|
||||||
|
|
||||||
|
/* Version of clixon datastore plugin API. */
|
||||||
|
#define XMLDB_API_VERSION 1
|
||||||
|
|
||||||
|
/* Magic to ensure plugin sanity. */
|
||||||
|
#define XMLDB_API_MAGIC 0xf386f730
|
||||||
|
|
||||||
|
/* Name of plugin init function (must be called this) */
|
||||||
|
#define XMLDB_PLUGIN_INIT_FN "clixon_xmldb_plugin_init"
|
||||||
|
|
||||||
|
/* Type of plugin init function */
|
||||||
|
typedef void * (plugin_init_t)(int version);
|
||||||
|
|
||||||
|
/* Type of plugin exit function */
|
||||||
|
typedef int (plugin_exit_t)(void);
|
||||||
|
|
||||||
|
/* Type of xmldb get function */
|
||||||
|
typedef int (xmldb_get_t)(clicon_handle h, char *db, char *xpath,
|
||||||
|
cxobj **xtop, cxobj ***xvec, size_t *xlen);
|
||||||
|
|
||||||
|
/* Type of xmldb put function */
|
||||||
|
typedef int (xmldb_put_t)(clicon_handle h, char *db, enum operation_type op,
|
||||||
|
char *api_path, cxobj *xt);
|
||||||
|
|
||||||
|
/* Type of xmldb dump function */
|
||||||
|
typedef int (xmldb_dump_t)(FILE *f, char *dbfilename, char *rxkey);
|
||||||
|
|
||||||
|
/* Type of xmldb copy function */
|
||||||
|
typedef int (xmldb_copy_t)(clicon_handle h, char *from, char *to);
|
||||||
|
|
||||||
|
/* Type of xmldb lock function */
|
||||||
|
typedef int (xmldb_lock_t)(clicon_handle h, char *db, int pid);
|
||||||
|
|
||||||
|
/* Type of xmldb unlock function */
|
||||||
|
typedef int (xmldb_unlock_t)(clicon_handle h, char *db, int pid);
|
||||||
|
|
||||||
|
/* Type of xmldb unlock_all function */
|
||||||
|
typedef int (xmldb_unlock_all_t)(clicon_handle h, int pid);
|
||||||
|
|
||||||
|
/* Type of xmldb islocked function */
|
||||||
|
typedef int (xmldb_islocked_t)(clicon_handle h, char *db);
|
||||||
|
|
||||||
|
/* Type of xmldb exists function */
|
||||||
|
typedef int (xmldb_exists_t)(clicon_handle h, char *db);
|
||||||
|
|
||||||
|
/* Type of xmldb delete function */
|
||||||
|
typedef int (xmldb_delete_t)(clicon_handle h, char *db);
|
||||||
|
|
||||||
|
/* Type of xmldb init function */
|
||||||
|
typedef int (xmldb_init_t)(clicon_handle h, char *db);
|
||||||
|
|
||||||
|
/* grideye agent plugin init struct for the api */
|
||||||
|
struct xmldb_api{
|
||||||
|
int xa_version;
|
||||||
|
int xa_magic;
|
||||||
|
plugin_init_t *xa_plugin_init_fn; /* XMLDB_PLUGIN_INIT_FN */
|
||||||
|
plugin_exit_t *xa_plugin_exit_fn;
|
||||||
|
xmldb_get_t *xa_get_fn;
|
||||||
|
xmldb_put_t *xa_put_fn;
|
||||||
|
xmldb_dump_t *xa_dump_fn;
|
||||||
|
xmldb_copy_t *xa_copy_fn;
|
||||||
|
xmldb_lock_t *xa_lock_fn;
|
||||||
|
xmldb_unlock_t *xa_unlock_fn;
|
||||||
|
xmldb_unlock_all_t *xa_unlock_all_fn;
|
||||||
|
xmldb_islocked_t *xa_islocked_fn;
|
||||||
|
xmldb_exists_t *xa_exists_fn;
|
||||||
|
xmldb_delete_t *xa_delete_fn;
|
||||||
|
xmldb_init_t *xa_init_fn;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prototypes
|
* Prototypes
|
||||||
*/
|
*/
|
||||||
int yang2xmlkeyfmt(yang_stmt *ys, int inclkey, char **xkfmt);
|
int xmldb_plugin_load(char *filename);
|
||||||
int xmlkeyfmt2key(char *xkfmt, cvec *cvv, char **xk);
|
|
||||||
int xmlkeyfmt2xpath(char *xkfmt, cvec *cvv, char **xk);
|
|
||||||
|
|
||||||
int xmldb_get(clicon_handle h, char *db, char *xpath,
|
int xmldb_get(clicon_handle h, char *db, char *xpath,
|
||||||
cxobj **xtop, cxobj ***xvec, size_t *xlen);
|
cxobj **xtop, cxobj ***xvec, size_t *xlen);
|
||||||
|
|
|
||||||
|
|
@ -61,5 +61,8 @@ int xml_diff(yang_spec *yspec, cxobj *xt1, cxobj *xt2,
|
||||||
cxobj ***first, size_t *firstlen,
|
cxobj ***first, size_t *firstlen,
|
||||||
cxobj ***second, size_t *secondlen,
|
cxobj ***second, size_t *secondlen,
|
||||||
cxobj ***changed1, cxobj ***changed2, size_t *changedlen);
|
cxobj ***changed1, cxobj ***changed2, size_t *changedlen);
|
||||||
|
int yang2xmlkeyfmt(yang_stmt *ys, int inclkey, char **xkfmt);
|
||||||
|
int xmlkeyfmt2key(char *xkfmt, cvec *cvv, char **xk);
|
||||||
|
int xmlkeyfmt2xpath(char *xkfmt, cvec *cvv, char **xk);
|
||||||
|
|
||||||
#endif /* _CLIXON_XML_MAP_H_ */
|
#endif /* _CLIXON_XML_MAP_H_ */
|
||||||
|
|
|
||||||
|
|
@ -61,12 +61,11 @@ CPPFLAGS = @CPPFLAGS@
|
||||||
|
|
||||||
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
|
INCLUDES = -I. @INCLUDES@ -I$(top_srcdir)/lib/clixon -I$(top_srcdir)/include -I$(top_srcdir)
|
||||||
|
|
||||||
SRC = clixon_sig.c clixon_qdb.c clixon_log.c clixon_err.c clixon_event.c \
|
SRC = clixon_sig.c clixon_log.c clixon_err.c clixon_event.c \
|
||||||
clixon_chunk.c clixon_proc.c \
|
clixon_chunk.c clixon_proc.c \
|
||||||
clixon_string.c clixon_handle.c \
|
clixon_string.c clixon_handle.c \
|
||||||
clixon_xml.c clixon_xml_map.c clixon_file.c \
|
clixon_xml.c clixon_xml_map.c clixon_file.c \
|
||||||
clixon_json.c \
|
clixon_json.c clixon_yang.c clixon_yang_type.c \
|
||||||
clixon_yang.c clixon_yang_type.c \
|
|
||||||
clixon_hash.c clixon_options.c clixon_plugin.c \
|
clixon_hash.c clixon_options.c clixon_plugin.c \
|
||||||
clixon_proto.c clixon_proto_client.c \
|
clixon_proto.c clixon_proto_client.c \
|
||||||
clixon_xsl.c clixon_sha1.c clixon_xml_db.c
|
clixon_xsl.c clixon_sha1.c clixon_xml_db.c
|
||||||
|
|
|
||||||
|
|
@ -237,6 +237,10 @@ clicon_option_sanity(clicon_hash_t *copt)
|
||||||
clicon_err(OE_UNIX, 0, "CLICON_ARCHIVE_DIR not defined in config file");
|
clicon_err(OE_UNIX, 0, "CLICON_ARCHIVE_DIR not defined in config file");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (!hash_lookup(copt, "CLICON_XMLDB_DIR")){
|
||||||
|
clicon_err(OE_UNIX, 0, "CLICON_XMLDB_DIR not defined in config file");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (!hash_lookup(copt, "CLICON_SOCK")){
|
if (!hash_lookup(copt, "CLICON_SOCK")){
|
||||||
clicon_err(OE_UNIX, 0, "CLICON_SOCK not defined in config file");
|
clicon_err(OE_UNIX, 0, "CLICON_SOCK not defined in config file");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
@ -453,6 +457,12 @@ clicon_archive_dir(clicon_handle h)
|
||||||
return clicon_option_str(h, "CLICON_ARCHIVE_DIR");
|
return clicon_option_str(h, "CLICON_ARCHIVE_DIR");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
clicon_xmldb_plugin(clicon_handle h)
|
||||||
|
{
|
||||||
|
return clicon_option_str(h, "CLICON_XMLDB_PLUGIN");
|
||||||
|
}
|
||||||
|
|
||||||
/* get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */
|
/* get family of backend socket: AF_UNIX, AF_INET or AF_INET6 */
|
||||||
int
|
int
|
||||||
clicon_sock_family(clicon_handle h)
|
clicon_sock_family(clicon_handle h)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -66,6 +66,7 @@
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
/* cligen */
|
/* cligen */
|
||||||
#include <cligen/cligen.h>
|
#include <cligen/cligen.h>
|
||||||
|
|
@ -89,9 +90,6 @@
|
||||||
/* Something to do with reverse engineering of junos syntax? */
|
/* Something to do with reverse engineering of junos syntax? */
|
||||||
#undef SPECIAL_TREATMENT_OF_NAME
|
#undef SPECIAL_TREATMENT_OF_NAME
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A node is a leaf if it contains a body.
|
* A node is a leaf if it contains a body.
|
||||||
*/
|
*/
|
||||||
|
|
@ -791,3 +789,288 @@ xml_diff(yang_spec *yspec,
|
||||||
done:
|
done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Construct an xml key format from yang statement using wildcards for keys
|
||||||
|
* Recursively construct it to the top.
|
||||||
|
* Example:
|
||||||
|
* yang: container a -> list b -> key c -> leaf d
|
||||||
|
* xpath: /a/b/%s/d
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] inclkey If inclkey then include key leaf (eg last leaf d in ex)
|
||||||
|
* @param[out] cbuf keyfmt
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
yang2xmlkeyfmt_1(yang_stmt *ys,
|
||||||
|
int inclkey,
|
||||||
|
cbuf *cb)
|
||||||
|
{
|
||||||
|
yang_node *yp; /* parent */
|
||||||
|
yang_stmt *ykey;
|
||||||
|
int i;
|
||||||
|
cvec *cvk = NULL; /* vector of index keys */
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
yp = ys->ys_parent;
|
||||||
|
if (yp != NULL &&
|
||||||
|
yp->yn_keyword != Y_MODULE &&
|
||||||
|
yp->yn_keyword != Y_SUBMODULE){
|
||||||
|
if (yang2xmlkeyfmt_1((yang_stmt *)yp, 1, cb) < 0)
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (inclkey){
|
||||||
|
if (ys->ys_keyword != Y_CHOICE && ys->ys_keyword != Y_CASE)
|
||||||
|
cprintf(cb, "/%s", ys->ys_argument);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (ys->ys_keyword == Y_LEAF && yp && yp->yn_keyword == Y_LIST){
|
||||||
|
if (yang_key_match(yp, ys->ys_argument) == 0)
|
||||||
|
cprintf(cb, "/%s", ys->ys_argument); /* Not if leaf and key */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (ys->ys_keyword != Y_CHOICE && ys->ys_keyword != Y_CASE)
|
||||||
|
cprintf(cb, "/%s", ys->ys_argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ys->ys_keyword){
|
||||||
|
case Y_LIST:
|
||||||
|
if ((ykey = yang_find((yang_node*)ys, Y_KEY, NULL)) == NULL){
|
||||||
|
clicon_err(OE_XML, errno, "%s: List statement \"%s\" has no key",
|
||||||
|
__FUNCTION__, ys->ys_argument);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* The value is a list of keys: <key>[ <key>]* */
|
||||||
|
if ((cvk = yang_arg2cvec(ykey, " ")) == NULL)
|
||||||
|
goto done;
|
||||||
|
if (cvec_len(cvk))
|
||||||
|
cprintf(cb, "=");
|
||||||
|
/* Iterate over individual keys */
|
||||||
|
for (i=0; i<cvec_len(cvk); i++){
|
||||||
|
if (i)
|
||||||
|
cprintf(cb, ",");
|
||||||
|
cprintf(cb, "%%s");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Y_LEAF_LIST:
|
||||||
|
cprintf(cb, "=%%s");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cvk)
|
||||||
|
cvec_free(cvk);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Construct an xml key format from yang statement using wildcards for keys
|
||||||
|
* Recursively construct it to the top.
|
||||||
|
* Example:
|
||||||
|
* yang: container a -> list b -> key c -> leaf d
|
||||||
|
* xpath: /a/b=%s/d
|
||||||
|
* @param[in] ys Yang statement
|
||||||
|
* @param[in] inclkey If !inclkey then dont include key leaf
|
||||||
|
* @param[out] xkfmt XML key format. Needs to be freed after use.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
yang2xmlkeyfmt(yang_stmt *ys,
|
||||||
|
int inclkey,
|
||||||
|
char **xkfmt)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (yang2xmlkeyfmt_1(ys, inclkey, cb) < 0)
|
||||||
|
goto done;
|
||||||
|
if ((*xkfmt = strdup(cbuf_get(cb))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! Transform an xml key format and a vector of values to an XML key
|
||||||
|
* Used for actual key, eg in clicon_rpc_change(), xmldb_put_xkey()
|
||||||
|
* Example:
|
||||||
|
* xmlkeyfmt: /aaa/%s
|
||||||
|
* cvv: key=17
|
||||||
|
* xmlkey: /aaa/17
|
||||||
|
* @param[in] xkfmt XML key format, eg /aaa/%s
|
||||||
|
* @param[in] cvv cligen variable vector, one for every wildchar in xkfmt
|
||||||
|
* @param[out] xk XML key, eg /aaa/17. Free after use
|
||||||
|
* @note first and last elements of cvv are not used,..
|
||||||
|
* @see cli_dbxml where this function is called
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlkeyfmt2key(char *xkfmt,
|
||||||
|
cvec *cvv,
|
||||||
|
char **xk)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char c;
|
||||||
|
int esc=0;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
char *str;
|
||||||
|
char *strenc=NULL;
|
||||||
|
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
#if 1
|
||||||
|
j = 0; /* Count % */
|
||||||
|
for (i=0; i<strlen(xkfmt); i++)
|
||||||
|
if (xkfmt[i] == '%')
|
||||||
|
j++;
|
||||||
|
if (j+2 < cvec_len(cvv)) {
|
||||||
|
clicon_log(LOG_WARNING, "%s xmlkey format string mismatch(j=%d, cvec_len=%d): %s",
|
||||||
|
xkfmt,
|
||||||
|
j,
|
||||||
|
cvec_len(cvv),
|
||||||
|
cv_string_get(cvec_i(cvv, 0)));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
j = 1; /* j==0 is cli string */
|
||||||
|
for (i=0; i<strlen(xkfmt); i++){
|
||||||
|
c = xkfmt[i];
|
||||||
|
if (esc){
|
||||||
|
esc = 0;
|
||||||
|
if (c!='s')
|
||||||
|
continue;
|
||||||
|
if ((str = cv2str_dup(cvec_i(cvv, j++))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if ((strenc = curl_easy_escape(NULL, str, 0)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "curl_easy_escape");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, "%s", strenc);
|
||||||
|
curl_free(strenc);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (c == '%')
|
||||||
|
esc++;
|
||||||
|
else
|
||||||
|
cprintf(cb, "%c", c);
|
||||||
|
}
|
||||||
|
if ((*xk = strdup(cbuf_get(cb))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Transform an xml key format and a vector of values to an XML path
|
||||||
|
* Used to input xmldb_get() or xmldb_get_vec
|
||||||
|
* Add .* in last %s position.
|
||||||
|
* Example:
|
||||||
|
* xmlkeyfmt: /interface/%s/address/%s OLDXXX
|
||||||
|
* xmlkeyfmt: /interface=%s/address=%s
|
||||||
|
* cvv: name=eth0
|
||||||
|
* xmlkey: /interface/[name=eth0]/address
|
||||||
|
* Example2:
|
||||||
|
* xmlkeyfmt: /ip/me/%s (if key)
|
||||||
|
* cvv: -
|
||||||
|
* xmlkey: /ipv4/me/a
|
||||||
|
* @param[in] xkfmt XML key format
|
||||||
|
* @param[in] cvv cligen variable vector, one for every wildchar in xkfmt
|
||||||
|
* @param[out] xk XPATH
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlkeyfmt2xpath(char *xkfmt,
|
||||||
|
cvec *cvv,
|
||||||
|
char **xk)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
char c;
|
||||||
|
int esc=0;
|
||||||
|
cbuf *cb = NULL;
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
char *str;
|
||||||
|
cg_var *cv;
|
||||||
|
int skip = 0;
|
||||||
|
|
||||||
|
/* Sanity check: count '%' */
|
||||||
|
#if 1
|
||||||
|
j = 0; /* Count % */
|
||||||
|
for (i=0; i<strlen(xkfmt); i++)
|
||||||
|
if (xkfmt[i] == '%')
|
||||||
|
j++;
|
||||||
|
if (j < cvec_len(cvv)-1) {
|
||||||
|
clicon_log(LOG_WARNING, "%s xmlkey format string mismatch(j=%d, cvec_len=%d): %s",
|
||||||
|
xkfmt,
|
||||||
|
j,
|
||||||
|
cvec_len(cvv),
|
||||||
|
cv_string_get(cvec_i(cvv, 0)));
|
||||||
|
// goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((cb = cbuf_new()) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cbuf_new");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
j = 1; /* j==0 is cli string */
|
||||||
|
for (i=0; i<strlen(xkfmt); i++){
|
||||||
|
c = xkfmt[i];
|
||||||
|
if (esc){
|
||||||
|
esc = 0;
|
||||||
|
if (c!='s')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (j == cvec_len(cvv)) /* last element */
|
||||||
|
//skip++;
|
||||||
|
;
|
||||||
|
else{
|
||||||
|
cv = cvec_i(cvv, j++);
|
||||||
|
if ((str = cv2str_dup(cv)) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
cprintf(cb, "[%s=%s]", cv_name_get(cv), str);
|
||||||
|
free(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* regular char */
|
||||||
|
if (c == '%')
|
||||||
|
esc++;
|
||||||
|
else{
|
||||||
|
if (skip)
|
||||||
|
skip=0;
|
||||||
|
else
|
||||||
|
if ((c == '=' || c == ',') && xkfmt[i+1]=='%')
|
||||||
|
; /* skip */
|
||||||
|
else
|
||||||
|
cprintf(cb, "%c", c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((*xk = strdup4(cbuf_get(cb))) == NULL){
|
||||||
|
clicon_err(OE_UNIX, errno, "strdup");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
if (cb)
|
||||||
|
cbuf_free(cb);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue