* A new "hello world" example is added
* The directory `docker/system` has been moved to `docker/main`
This commit is contained in:
parent
d46ca41c8b
commit
14d319dd9b
21 changed files with 382 additions and 11 deletions
167
example/hello/Makefile.in
Normal file
167
example/hello/Makefile.in
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
#
|
||||
# Copyright (C) 2009-2019 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@
|
||||
prefix = @prefix@
|
||||
bindir = @bindir@
|
||||
includedir = @includedir@
|
||||
datarootdir = @datarootdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
datarootdir = @datarootdir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @exec_prefix@/lib
|
||||
|
||||
APPNAME = hello
|
||||
|
||||
# Here is where example yang appears
|
||||
CLIXON_DATADIR = @CLIXON_DATADIR@
|
||||
# Install here if you want default clixon location:
|
||||
CLIXON_DEFAULT_CONFIG = @CLIXON_DEFAULT_CONFIG@
|
||||
|
||||
CC = @CC@
|
||||
CFLAGS = @CFLAGS@ -rdynamic -fPIC
|
||||
INSTALLFLAGS = @INSTALLFLAGS@
|
||||
with_restconf = @with_restconf@
|
||||
|
||||
INCLUDES = -I$(includedir) @INCLUDES@
|
||||
CPPFLAGS = @CPPFLAGS@ -fPIC
|
||||
|
||||
BE_PLUGIN = $(APPNAME)_backend.so
|
||||
CLI_PLUGIN = $(APPNAME)_cli.so
|
||||
NETCONF_PLUGIN = $(APPNAME)_netconf.so
|
||||
RESTCONF_PLUGIN = $(APPNAME)_restconf.so
|
||||
|
||||
PLUGINS = $(BE_PLUGIN) $(CLI_PLUGIN) $(NETCONF_PLUGIN)
|
||||
ifeq ($(with_restconf),yes)
|
||||
PLUGINS += $(RESTCONF_PLUGIN)
|
||||
endif
|
||||
|
||||
.PHONY: all clean depend install
|
||||
|
||||
all: $(PLUGINS)
|
||||
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
# implicit rule
|
||||
.c.o:
|
||||
$(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c $<
|
||||
|
||||
CLISPECS = $(APPNAME)_cli.cli
|
||||
|
||||
YANGSPECS = clixon-hello@2019-04-17.yang
|
||||
|
||||
# CLI frontend plugin (see also install rule)
|
||||
#CLI_SRC = $(APPNAME)_cli.c
|
||||
CLI_OBJ = $(CLI_SRC:%.c=%.o)
|
||||
$(CLI_PLUGIN): $(CLI_OBJ)
|
||||
$(CC) -Wall -shared -o $@ -lc $^
|
||||
|
||||
# Backend plugin (see also install rule)
|
||||
#BE_SRC = $(APPNAME)_backend.c
|
||||
BE_OBJ = $(BE_SRC:%.c=%.o)
|
||||
$(BE_PLUGIN): $(BE_OBJ)
|
||||
$(CC) -Wall -shared -o $@ -lc $<
|
||||
|
||||
# NETCONF frontend plugin (see also install rule)
|
||||
#NETCONF_SRC = $(APPNAME)_netconf.c
|
||||
NETCONF_OBJ = $(NETCONF_SRC:%.c=%.o)
|
||||
$(NETCONF_PLUGIN): $(NETCONF_OBJ)
|
||||
$(CC) -Wall -shared -o $@ -lc $^
|
||||
|
||||
# See configure.ac for disabling restconf
|
||||
# RESTCONF frontend plugin (see also install rule)
|
||||
#RESTCONF_SRC = $(APPNAME)_restconf.c
|
||||
RESTCONF_OBJ = $(RESTCONF_SRC:%.c=%.o)
|
||||
$(RESTCONF_PLUGIN): $(RESTCONF_OBJ)
|
||||
$(CC) -Wall -shared -o $@ -lc $^
|
||||
|
||||
SRC = $(BE_SRC) $(CLI_SRC) $(NETCONF_SRC)
|
||||
SRC += $(RESTCONF_SRC)
|
||||
|
||||
OBJS = $(BE_OBJ) $(CLI_OBJ) $(NETCONF_OBJ)
|
||||
OBJS += $(RESTCONF_OBJ)
|
||||
|
||||
clean:
|
||||
rm -f $(PLUGINS) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *~ .depend
|
||||
|
||||
|
||||
install: $(YANGSPECS) $(CLISPECS) $(PLUGINS) $(APPNAME).xml
|
||||
install -m 0644 $(APPNAME).xml $(DESTDIR)$(CLIXON_DEFAULT_CONFIG)
|
||||
install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)
|
||||
install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/clispec
|
||||
install -m 0644 $(CLISPECS) $(DESTDIR)$(libdir)/$(APPNAME)/clispec
|
||||
install -d -m 0755 $(DESTDIR)$(datarootdir)/$(APPNAME)/yang
|
||||
install -m 0644 $(YANGSPECS) $(DESTDIR)$(DESTDIR)$(CLIXON_DATADIR)
|
||||
install -d -m 0755 $(DESTDIR)$(localstatedir)/$(APPNAME)
|
||||
|
||||
# Uncomment for installing config file in /usr/local/etc instead
|
||||
# install -d -m 0755 $(DESTDIR)$(sysconfdir)
|
||||
# install -m 0644 $(APPNAME).xml $(DESTDIR)$(sysconfdir)
|
||||
|
||||
# Uncomment for installing cli plugin (see CLI_SRC)
|
||||
# install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/cli
|
||||
# install -m 0644 $(INSTALLFLAGS) $(CLI_PLUGIN) $(DESTDIR)$(libdir)/$(APPNAME)/cli
|
||||
|
||||
# Uncomment for installing backend plugin (see BE_SRC)
|
||||
# install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/backend
|
||||
# install -m 0644 $(INSTALLFLAGS) $(BE_PLUGIN) $(DESTDIR)$(libdir)/$(APPNAME)/backend
|
||||
|
||||
# Uncomment for installing netconf plugin (see NETCONF_SRC)
|
||||
# install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/netconf
|
||||
# install -m 0644 $(INSTALLFLAGS) $(NETCONF_PLUGIN) $(DESTDIR)$(libdir)/$(APPNAME)/netconf
|
||||
|
||||
# Uncomment for installing restconf plugin (see RESTCONF_SRC). The conditional is
|
||||
# because it is an option to disable restconf
|
||||
#ifeq ($(with_restconf),yes)
|
||||
# install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/restconf
|
||||
# install -m 0644 $(INSTALLFLAGS) $(RESTCONF_PLUGIN) $(DESTDIR)$(libdir)/$(APPNAME)/restconf
|
||||
#endif
|
||||
|
||||
uninstall:
|
||||
rm -rf $(DESTDIR)$(CLIXON_DEFAULT_CONFIG)
|
||||
rm -rf $(DESTDIR)$(libdir)/$(APPNAME)
|
||||
rm -rf $(DESTDIR)$(localstatedir)/$(APPNAME)
|
||||
rm -rf $(DESTDIR)$(datarootdir)/$(APPNAME)
|
||||
|
||||
|
||||
install-include:
|
||||
|
||||
depend:
|
||||
$(CC) $(DEPENDFLAGS) $(INCLUDES) $(CFLAGS) -MM $(SRC) > .depend
|
||||
|
||||
#include .depend
|
||||
|
||||
111
example/hello/README.md
Normal file
111
example/hello/README.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# Clixon hello world example
|
||||
|
||||
* [Content](#content)
|
||||
* [Compile and run](#compile)
|
||||
* [Using the CLI](#using-the-cli)
|
||||
* [Netconf](#netconf)
|
||||
* [Restconf](#restconf)
|
||||
* [Next steps](#next-steps)
|
||||
|
||||
## Content
|
||||
|
||||
This directory contains a Clixon example which includes a simple example. It contains the following files:
|
||||
* `hello.xml` The configuration file. See [yang/clixon-config@<date>.yang](../../yang/clixon-config@2019-03-05.yang) for the documentation of all available fields.
|
||||
* `clixon-hello@2019-04-17.yang` The yang spec of the example.
|
||||
* `hello_cli.cli` CLIgen specification.
|
||||
* `Makefile.in` Example makefile where plugins are built and installed
|
||||
* `README.md` This file
|
||||
|
||||
|
||||
## Compile and run
|
||||
|
||||
Before you start,
|
||||
* Make [group setup](../../doc/FAQ.md#do-i-need-to-setup-anything-important)
|
||||
|
||||
```
|
||||
make && sudo make install
|
||||
```
|
||||
Start backend in the background:
|
||||
```
|
||||
sudo clixon_backend
|
||||
```
|
||||
Start cli:
|
||||
```
|
||||
clixon_cli
|
||||
```
|
||||
|
||||
## Using the CLI
|
||||
|
||||
The example CLI allows you to modify and view the data model using `set`, `delete` and `show` via generated code.
|
||||
|
||||
The following example shows how to add a very simple configuration `hello world` using the generated CLI. The config is added to the candidate database, shown, committed to running, and then deleted.
|
||||
```
|
||||
olof@vandal> clixon_cli
|
||||
cli> set <?>
|
||||
hello
|
||||
cli> set hello world
|
||||
cli> show configuration
|
||||
hello world;
|
||||
cli> commit
|
||||
cli> delete <?>
|
||||
all Delete whole candidate configuration
|
||||
hello
|
||||
cli> delete hello
|
||||
cli> show configuration
|
||||
cli> commit
|
||||
cli> quit
|
||||
olof@vandal>
|
||||
```
|
||||
|
||||
## Netconf
|
||||
|
||||
Clixon also provides a Netconf interface. The following example starts a netconf client form the shell, adds the hello world config, commits it, and shows it:
|
||||
```
|
||||
olof@vandal> clixon_netconf -q
|
||||
<rpc><edit-config><target><candidate/></target><config><hello xmlns="urn:example:hello"><world/></hello></config></edit-config></rpc>]]>]]>
|
||||
<rpc-reply><ok/></rpc-reply>]]>]]>
|
||||
<rpc><commit/></rpc>]]>]]>
|
||||
<rpc-reply><ok/></rpc-reply>]]>]]>
|
||||
<rpc><get-config><source><running/></source></get-config></rpc>]]>]]>
|
||||
<rpc-reply><data><hello xmlns="urn:example:hello"><world/></hello></data></rpc-reply>]]>]]>
|
||||
olof@vandal>
|
||||
```
|
||||
|
||||
## Restconf
|
||||
|
||||
Clixon also provides a Restconf interface. A reverse proxy needs to be configured. There are [instructions how to setup Nginx](../../doc/FAQ.md#how-do-i-use-restconf) for Clixon.
|
||||
|
||||
Start restconf daemon
|
||||
```
|
||||
sudo su -c "/www-data/clixon_restconf" -s /bin/sh www-data &
|
||||
```
|
||||
|
||||
Start sending restconf commands (using Curl):
|
||||
```
|
||||
olof@vandal> curl -X POST http://localhost/restconf/data -d '{"clixon-hello:hello":{"world":null}}'
|
||||
olof@vandal> curl -X GET http://localhost/restconf/data
|
||||
{
|
||||
"data": {
|
||||
"clixon-hello:hello": {
|
||||
"world": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
The hello world example only has a Yang spec and a template CLI
|
||||
spec. For more advanced applications, customized backend, cli, netconf
|
||||
and restconf code callbacks becomes necessary.
|
||||
|
||||
Further, you may want to add upgrade, RPC:s, state data, notification
|
||||
streams, authentication and authorization. The [main example](../main)
|
||||
contains examples for such capabilities.
|
||||
|
||||
There are also [container examples](../../docker) and lots more.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14
example/hello/clixon-hello@2019-04-17.yang
Normal file
14
example/hello/clixon-hello@2019-04-17.yang
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
module clixon-hello {
|
||||
yang-version 1.1;
|
||||
namespace "urn:example:hello";
|
||||
prefix he;
|
||||
revision 2019-04-17 {
|
||||
description
|
||||
"Clixon hello world example";
|
||||
}
|
||||
container hello{
|
||||
container world{
|
||||
presence true;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
example/hello/hello.xml
Normal file
13
example/hello/hello.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<clixon-config xmlns="http://clicon.org/config">
|
||||
<CLICON_CONFIGFILE>/usr/local/etc/example.xml</CLICON_CONFIGFILE>
|
||||
<CLICON_FEATURE>*:*</CLICON_FEATURE>
|
||||
<CLICON_YANG_DIR>/usr/local/share/clixon</CLICON_YANG_DIR>
|
||||
<CLICON_YANG_MODULE_MAIN>clixon-hello</CLICON_YANG_MODULE_MAIN>
|
||||
<CLICON_CLI_MODE>hello</CLICON_CLI_MODE>
|
||||
<CLICON_CLISPEC_DIR>/usr/local/lib/hello/clispec</CLICON_CLISPEC_DIR>
|
||||
<CLICON_SOCK>/usr/local/var/hello.sock</CLICON_SOCK>
|
||||
<CLICON_BACKEND_PIDFILE>/usr/local/var/hello.pidfile</CLICON_BACKEND_PIDFILE>
|
||||
<CLICON_XMLDB_DIR>/usr/local/var/hello</CLICON_XMLDB_DIR>
|
||||
<CLICON_STARTUP_MODE>init</CLICON_STARTUP_MODE>
|
||||
<CLICON_MODULE_LIBRARY_RFC7895>false</CLICON_MODULE_LIBRARY_RFC7895>
|
||||
</clixon-config>
|
||||
54
example/hello/hello_cli.cli
Normal file
54
example/hello/hello_cli.cli
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
# Common CLI syntax for both server and PMNode operatio mode
|
||||
CLICON_MODE="hello";
|
||||
CLICON_PROMPT="cli> ";
|
||||
|
||||
# Reference generated data model
|
||||
set @datamodel, cli_set();
|
||||
merge @datamodel, cli_merge();
|
||||
create @datamodel, cli_create();
|
||||
delete("Delete a configuration item") @datamodel, cli_del();
|
||||
|
||||
validate("Validate changes"), cli_validate();
|
||||
commit("Commit the changes"), cli_commit();
|
||||
quit("Quit"), cli_quit();
|
||||
delete("Delete a configuration item") all("Delete whole candidate configuration"), delete_all("candidate");
|
||||
|
||||
startup("Store running as startup config"), db_copy("running", "startup");
|
||||
no("Negate or remove") debug("Debugging parts of the system"), cli_debug_cli((int32)0);
|
||||
debug("Debugging parts of the system"), cli_debug_cli((int32)1);{
|
||||
level("Set debug level: 1..n") <level:int32>("Set debug level (0..n)"), cli_debug_backend();
|
||||
}
|
||||
discard("Discard edits (rollback 0)"), discard_changes();
|
||||
compare("Compare running and candidate"), compare_dbs((int32)1);
|
||||
|
||||
show("Show a particular state of the system"){
|
||||
xpath("Show configuration") <xpath:string>("XPATH expression"), show_conf_xpath("candidate");
|
||||
version("Show version"), cli_show_version("candidate", "text", "/");
|
||||
compare("Compare candidate and running databases"), compare_dbs((int32)0);{
|
||||
xml("Show comparison in xml"), compare_dbs((int32)0);
|
||||
text("Show comparison in text"), compare_dbs((int32)1);
|
||||
}
|
||||
configuration("Show configuration"), cli_show_config("candidate", "text", "/");{
|
||||
xml("Show configuration as XML"), cli_show_config("candidate", "xml", "/");{
|
||||
@datamodel, cli_show_auto("candidate", "xml");
|
||||
}
|
||||
cli("Show configuration as CLI commands"), cli_show_config("candidate", "cli", "/");{
|
||||
@datamodel, cli_show_auto("candidate", "cli");
|
||||
}
|
||||
netconf("Show configuration as netconf edit-config operation"), cli_show_config("candidate", "netconf", "/");{
|
||||
@datamodel, cli_show_auto("candidate", "netconf");
|
||||
}
|
||||
text("Show configuration as text"), cli_show_config("candidate","text","/");{
|
||||
@datamodel, cli_show_auto("candidate", "text");
|
||||
}
|
||||
json("Show configuration as JSON"), cli_show_config("candidate", "json", "/");{
|
||||
@datamodel, cli_show_auto("candidate", "json");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save("Save candidate configuration to XML file") <filename:string>("Filename (local filename)"), save_config_file("candidate","filename");
|
||||
load("Load configuration from XML file") <filename:string>("Filename (local filename)"),load_config_file("filename", "replace");{
|
||||
replace("Replace candidate with file contents"), load_config_file("filename", "replace");
|
||||
merge("Merge file with existent candidate"), load_config_file("filename", "merge");
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue