├── .gitignore
├── .vscode
└── settings.json
├── README.md
├── _config.yml
├── bad-interfaces.yang
├── clixon
├── Makefile
├── interfaces.xml
├── interfaces_cli.cli
├── interfaces_fake_plugin.c
└── startup_db
├── docs
├── clixon.md
├── example-yang-data-model.md
├── figures
│ ├── clixon-architecture.jpg
│ ├── mgsoft-netconf-browser-choose-yang-file.png
│ ├── mgsoft-netconf-browser-config-tree.png
│ ├── mgsoft-netconf-browser-config-xml.png
│ ├── mgsoft-netconf-browser-connect-to-server.png
│ ├── mgsoft-netconf-browser-connected.png
│ ├── mgsoft-netconf-browser-edit-config-details.png
│ ├── mgsoft-netconf-browser-edit-config.png
│ ├── mgsoft-netconf-browser-expand-entire-subtree.png
│ ├── mgsoft-netconf-browser-first-time.png
│ ├── mgsoft-netconf-browser-get-config.png
│ ├── mgsoft-netconf-browser-icon.png
│ ├── mgsoft-netconf-browser-interfaces-subtree.png
│ ├── mgsoft-netconf-browser-message-id.png
│ ├── mgsoft-netconf-browser-module-in-panel.png
│ ├── mgsoft-netconf-browser-startup.png
│ ├── mgsoft-netconf-browser-validate.png
│ ├── mgsoft-netconf-simulator-need-java.png
│ ├── mgsoft-yang-designer-components-tab.png
│ ├── mgsoft-yang-designer-create-new-project.png
│ ├── mgsoft-yang-designer-edit-module.png
│ ├── mgsoft-yang-designer-empty-module.png
│ ├── mgsoft-yang-designer-errors.png
│ ├── mgsoft-yang-designer-first-time.png
│ ├── mgsoft-yang-designer-icon.png
│ ├── mgsoft-yang-designer-module-details.png
│ ├── mgsoft-yang-designer-new-module-button.png
│ ├── mgsoft-yang-designer-project-details-2.png
│ ├── mgsoft-yang-designer-project-details.png
│ ├── mgsoft-yang-designer-source-code.png
│ ├── mgsoft-yang-explorer-choose-yang-file.png
│ ├── mgsoft-yang-explorer-dependencies.png
│ ├── mgsoft-yang-explorer-find-nodes.png
│ ├── mgsoft-yang-explorer-first-time.png
│ ├── mgsoft-yang-explorer-icon.png
│ ├── mgsoft-yang-explorer-interface-model-details.png
│ ├── mgsoft-yang-explorer-interface-model-expanded-subtree.png
│ ├── mgsoft-yang-explorer-interface-model-source.png
│ ├── mgsoft-yang-explorer-interface-model-text-tree.png
│ ├── mgsoft-yang-explorer-show-in-yang-tree.png
│ ├── mgsoft-yang-explorer-startup.png
│ ├── mgsoft-yang-explorer-uml-class-diagram.png
│ ├── pyang-jstree-diagram.png
│ ├── pyang-uml-diagram.png
│ ├── yang-validator-home.png
│ ├── yang-validator-validation-bad.png
│ ├── yang-validator-validation-good.png
│ ├── yuma-pro-client-execute-error-1.png
│ ├── yuma-pro-client-execute-error-2.png
│ ├── yuma-pro-client-execute-error-3.png
│ ├── yuma-pro-client-execute-error-4.png
│ ├── yuma-pro-html-file.png
│ ├── yuma-pro-sdk-basic-components.png
│ ├── yuma-pro-sdk-components.png
│ ├── yuma-pro-sdk-feature-comparison.png
│ ├── yumabench-add-2nd-interface.png
│ ├── yumabench-add-device.png
│ ├── yumabench-add-interface.png
│ ├── yumabench-add-session.png
│ ├── yumabench-add-user.png
│ ├── yumabench-notifications.png
│ ├── yumabench-operational-state.png
│ ├── yumabench-select-devices.png
│ ├── yumabench-session-window.png
│ └── yumabench-startup.png
├── mg-soft-browser.md
├── mg-soft-designer.md
├── mg-soft-explorer.md
├── mg-soft-simulator.md
├── ncclient.md
├── netopeer2.md
├── pyang.md
├── references.md
├── tail-f-confd.md
├── tutorial-install.md
├── yang-validator.md
├── yanglint.md
├── yuma-pro-client.md
├── yuma-pro-sdk.md
└── yumabench.md
├── interfaces.yang
├── ncclient
├── __pycache__
│ └── netconf_server_info.cpython-39.pyc
├── demo_client.py
├── edit_config.py
├── netconf_server_info.py
├── show_capabilities.py
└── show_config.py
├── requirements.txt
└── yanglint
├── bad-data.xml
└── data.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Python
2 | venv/
3 | *.pyc
4 |
5 | # C
6 | *.o
7 | *.so
8 | .depend
9 |
10 | # Files created when the user follows tutorial instructions
11 | **/interfaces.html
12 | **/interfaces.uml
13 | **/img/
14 | interfaces/
15 |
16 | # Log files
17 | *.log
18 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "workbench.colorTheme": "Visual Studio Light",
3 | "editor.minimap.enabled": false,
4 | "editor.rename.enablePreview": false,
5 | "git.confirmSync": false,
6 | "workbench.editor.enablePreview": false,
7 | "diffEditor.ignoreTrimWhitespace": false,
8 | "files.trimTrailingWhitespace": true,
9 | "editor.renderWhitespace": "all",
10 | "editor.rulers": [
11 | 100
12 | ],
13 | "window.zoomLevel": 1,
14 | "cSpell.words": [
15 | "appcmn",
16 | "Bierman",
17 | "dpkg",
18 | "Ersue",
19 | "etag",
20 | "getbulk",
21 | "GETCB",
22 | "gnutls",
23 | "ianach",
24 | "inet",
25 | "intf",
26 | "libcurl",
27 | "libfcgi",
28 | "libncurses",
29 | "libssh",
30 | "Mehmet",
31 | "mgrload",
32 | "multitail",
33 | "nacm",
34 | "ncwd",
35 | "ncxserver",
36 | "ncxsock",
37 | "NETCONF",
38 | "netconfd",
39 | "parms",
40 | "randomart",
41 | "rcmon",
42 | "RESTCONF",
43 | "rpcs",
44 | "sget",
45 | "timefilter",
46 | "topsecret",
47 | "Wijnen",
48 | "Wireshark",
49 | "yangcli",
50 | "yanglib",
51 | "ybulk",
52 | "ypatch",
53 | "ysys",
54 | "ytemp",
55 | "yumapro",
56 | "yumaworks",
57 | "ywapp",
58 | "ywes"
59 | ],
60 | "python.linting.pylintEnabled": true,
61 | "python.formatting.provider": "black",
62 | "python.linting.pylintArgs": [
63 | "--load-plugins=pylint_django",
64 | "--django-settings-module=settings.py"
65 | ],
66 | "[python]": {
67 | "editor.formatOnType": true,
68 | "editor.formatOnSave": true,
69 | },
70 | "html.format.enable": false,
71 | "gitlens.currentLine.enabled": false,
72 | "gitlens.hovers.currentLine.over": "line",
73 | "gitlens.codeLens.enabled": false,
74 | }
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | --== **A WORK IN PROGRESS** ==--
2 |
3 | # A scenic tour through the YANG ecosystem
4 |
5 | # Introduction
6 |
7 | This is a hands-on tutorial for the YANG ecosystem.
8 |
9 | YANG is a data modeling language that is used for managing devices.
10 | It is quite popular for managing networking devices such as routers, switches, firewalls,
11 | load balancers, etc.
12 | But in principle, YANG could be used to manage any device such as
13 | washing machines, satellites, robots, storage arrays, whatever.
14 |
15 | A YANG data model describes what the configurable and operational attributes of the device are.
16 | A configuration attribute is an attribute that can be set by the operator, such as the temperature
17 | for a washing machine (hot, warm, cold).
18 | An operational attribute is an attribute that can only be read by the operator, such as the
19 | remaining time for the cycle of a washing machine.
20 | The YANG data model can also describe actions (e.g. start a washing cycle) and notifications
21 | (e.g. the washing cycle has been completed).
22 |
23 | The YANG data model is used to generate a management interface for the device.
24 | One example of such a management interface is the command line interface (CLI) which is a
25 | an interface intended for humans to configure and monitor the device.
26 | Other examples of management interfaces are NETCONF and RESTCONF. These are intended to be used
27 | by network management systems (NMSs) or software defined networking (SDN) controllers to configure
28 | and monitor the device.
29 |
30 | In this tutorial we won't spend much time on the theory of what YANG, CLI, NETCONF, or RESTCONF
31 | are.
32 | Instead, we will take a very hands-on approach and dive right in. We will define a toy YANG
33 | data model for a router; it models only the IPv4 addresses on a set of interfaces.
34 |
35 | Then, we will "take a tour through the YANG ecosystem". We will explore various open source and
36 | commercial tools that do something with our toy YANG data model. Some tools allow us to validate
37 | the correctness of the YANG data model. Other tools allow us to generate the code that would run
38 | on the managed network devices: the CLI/NETCONF/RESTCONF server code that actually reflects
39 | changes in the configuration onto the actual hardware. And other tools yet again allow us to
40 | generate the code that runs in the network management system, i.e. the NETCONF/RESTCONF client
41 | code.
42 |
43 | We take a very hands-on approach for each tool that we explore: we explain how to install the tool
44 | and how to use it to do something practically useful.
45 |
46 | For a list of links to standards and tutorials related to YANG, NETCONF, RESTCONF, etc. see the
47 | [references page](docs/references.md).
48 |
49 | # Getting started
50 |
51 | This tutorial is written in such a way that you can follow along and run each example yourself.
52 | For instructions on how to go to install the necessary software see the
53 | [setting up the environment for this tutorial](docs/tutorial-install.md) page.
54 |
55 | # A very simple example YANG data model: interfaces.yang
56 |
57 | Throughout this tutorial we will be using a simple example YANG data model called
58 | `interfaces.yang` which is described in detail in the
59 | [example YANG data model](docs/example-yang-data-model.md) page.
60 |
61 | # YANG data model visualization, validation and transformation tools
62 |
63 | These tools validate YANG data models for correctness and transform YANG data models into other
64 | formats such as a text summary, an HTML summary, a UML diagram, etc.
65 |
66 | Open source:
67 | * [Pyang](docs/pyang.md)
68 | * [Yanglint](docs/yanglint.md)
69 |
70 | Online:
71 | * [YANG Validator](docs/yang-validator.md)
72 |
73 | Commercial:
74 | * [MG-SOFT YANG Explorer Professional Edition](docs/mg-soft-explorer.md)
75 | * [YumaWorks YumaPro Client](docs/yuma-pro-client.md)
76 |
77 | TODO: Move some of the graphical YANG model browsers from down below to here.
78 |
79 | # NETCONF / RESTCONF servers
80 |
81 | NETCONF / RESTCONF servers are intended to implement the on-device management plane for
82 | hardware devices. They typically provide the following functionality:
83 |
84 | * They provide a north-bound (server-side) NETCONF and RESTCONF interface for clients.
85 |
86 | * They often also provide other north-bound (server-side) interface such as gNMI, SNMP, and/or
87 | a command-line interface (CLI).
88 |
89 | * They provide a software development kit (SDK) that allows the developers of the software on the
90 | device to map abstract YANG operations to concrete operations on the device hardware.
91 | Typically, the developers implement callback functions that get called when a configuration
92 | attribute needs to be validated, when a configuration attribute is set to a different value, when
93 | an operational attribute value is retrieved, when a transaction is committed, when an action is
94 | executed, when a notification needs to be generated, etc. etc. Different implementations support
95 | different programming languages.
96 |
97 | * They provide the backend implementation for the YANG data models that manage the NETCONF /
98 | RESTCONF server functionality itself, e.g.
99 | [RFC8525: YANG library](https://datatracker.ietf.org/doc/rfc8525/).
100 |
101 | Open source:
102 | * [Clixon](docs/clixon.md) (IN PROGRESS)
103 | * [Netopeer2](docs/netopeer2.md) (IN PROGRESS)
104 | * [Sysrepo](https://github.com/sysrepo/sysrepo) (TODO)
105 |
106 | Commercial:
107 | * [Cisco Tail-f ConfD](docs/confd.md) (TODO)
108 | * [MG-SOFT NETCONF Simulator](docs/mg-soft-simulator.md)
109 | * [YumaWorks YumaPro SDK](docs/yuma-pro-sdk.md)
110 |
111 | # NETCONF / RESTCONF clients
112 |
113 | NETCONF / RESTCONF clients are executable tools that allow a client-side user to manage devices
114 | that offer a server-side NETCONF / RESTCONF interface.
115 | They typically provide the following functionality:
116 |
117 | * They can dynamically discover which YANG modules the device supports and download the
118 | corresponding YANG data model from the device. (Or alternatively, you can manually load YANG
119 | data models into the client).
120 |
121 | * They can create, edit, and delete configuration attributes.
122 |
123 | * They can retrieve operational attributes.
124 |
125 | * They can invoke actions.
126 |
127 | * They can receive notifications.
128 |
129 | * Some tools offer a terminal-based command-line interface.
130 | Other tools offer a graphical user interface (GUI).
131 |
132 | Commercial:
133 | * [MG-SOFT NetConf Browser Professional Edition](docs/mg-soft-browser.md) (IN PROGRESS)
134 | * [YumaWorks YumaBench](docs/yumabench.md)
135 |
136 | # NETCONF / RESTCONF client libraries
137 |
138 | These tools are libraries or modules in a particular programming language (e.g. C, C++)
139 | that provide NETCONF and/or RESTCONF client functionality to software developers:
140 |
141 | Open source:
142 | * [Libyang](https://netopeer.liberouter.org/doc/libyang/devel/html/) (C) (TODO)
143 | * [Ncclient](docs/ncclient.md) (Python)
144 | * [Yangson](https://yangson.labs.nic.cz/) (Python) (TODO)
145 |
146 | Commercial:
147 | * [MG-SOFT NETCONF/YANG Python Scripting System](https://www.mg-soft.si/mgNetConfScripting.html) (TODO)
148 |
149 | # YANG authoring tools
150 |
151 | YANG authoring tools provide an integrated development environment (IDE) that help you author and
152 | manage YANG data models.
153 |
154 | Commercial:
155 | * [MG-SOFT Visual YANG Designer Professional Edition](docs/mg-soft-designer.md)
156 |
157 | # Other
158 |
159 | I still have to look at the following tools and classify them:
160 |
161 | * [YANG Development Kit](https://ydkgen.readthedocs.io/en/latest/index.html) (TODO)
162 | * [Cisco Tail-f YANG Suite](https://developer.cisco.com/yangsuite/)
163 | * [JetConf](https://github.com/CZ-NIC/jetconf)
164 | * https://github.com/choppsv1/netconf
165 |
166 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | title: A Scenic Tour Through the YANG Ecosystem
2 | name: Bruno Rijsman
3 | description: by Bruno Rijsman
4 | google_analytics: UA-31532124-6
5 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/bad-interfaces.yang:
--------------------------------------------------------------------------------
1 | module bad-interfaces {
2 |
3 | namespace "http://remoteautonomy.com/yang-schemas/bad-interfaces";
4 | prefix intf;
5 |
6 | organisation
7 | "Remote Autonomy";
8 |
9 | contact
10 | "Bruno Rijsman
11 | brunorijsman@remoteautonomy.com";
12 |
13 | description
14 | "A simplistic tutorial data model for interfaces on a device.";
15 |
16 | revision 2022-03-12 {
17 | description
18 | "Initial revision.";
19 | }
20 |
21 | container interfaces {
22 | description
23 | "Interface parameters.";
24 |
25 | list interface {
26 | key "name";
27 | description
28 | "The list of interfaces on the device.";
29 |
30 | leaf name {
31 | type string;
32 | description
33 | "The name of the interface.";
34 | }
35 |
36 | leaf ipv4-address {
37 | type string {
38 | pattern
39 | '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
40 | + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
41 | }
42 | description
43 | "The IPv4 address of the interface.";
44 | }
45 |
46 | leaf sent-packets {
47 | type uint46;
48 | config false;
49 | description
50 | "The number of IPv4 packets sent out over this interface";
51 | }
52 |
53 | leaf received-packets {
54 | type uint64;
55 | config false;
56 | description
57 | "The number of IPv4 packets received over this interface";
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/clixon/Makefile:
--------------------------------------------------------------------------------
1 | srcdir = .
2 | top_srcdir = ../..
3 | prefix = /usr/local
4 | bindir = ${exec_prefix}/bin
5 | includedir = ${prefix}/include
6 | datarootdir = ${prefix}/share
7 | sysconfdir = ${prefix}/etc
8 | datarootdir = ${prefix}/share
9 | localstatedir = ${prefix}/var
10 | libdir = ${prefix}/lib
11 |
12 | APPNAME = interfaces
13 |
14 | CC = gcc
15 | CFLAGS = -O2 -Wall -fPIC
16 | INSTALLFLAGS = -s
17 |
18 | INCLUDES =
19 | CPPFLAGS = -DHAVE_CONFIG_H -fPIC
20 |
21 | YANG_INSTALLDIR = /usr/local/share/clixon
22 |
23 | YANGSPECS = ../interfaces.yang
24 |
25 | PLUGIN = $(APPNAME)_fake_plugin.so
26 | PLUGIN_SRC = $(APPNAME)_fake_plugin.c
27 | PLUGIN_OBJ = $(PLUGIN_SRC:%.c=%.o)
28 |
29 | .SUFFIXES: .c .o
30 |
31 | .c.o:
32 | $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -c $<
33 |
34 | .PHONY: all clean depend install
35 |
36 | all: $(PLUGIN)
37 |
38 | $(PLUGIN): $(PLUGIN_OBJ)
39 | $(CC) -Wall -shared $(LDFLAGS) -o $@ -lc $< -lclixon -lclixon_backend
40 |
41 | CLISPECS = $(APPNAME)_cli.cli
42 |
43 | clean:
44 |
45 | distclean: clean
46 | rm -f Makefile *~ .depend
47 |
48 | install: $(CLISPECS) $(APPNAME).xml $(PLUGIN)
49 | install -d -m 0755 $(DESTDIR)$(sysconfdir)
50 | install -m 0644 $(APPNAME).xml $(DESTDIR)$(sysconfdir)
51 | install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)
52 | install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/clispec
53 | install -d -m 0755 $(DESTDIR)$(libdir)/$(APPNAME)/backend
54 | install -m 0644 $(CLISPECS) $(DESTDIR)$(libdir)/$(APPNAME)/clispec
55 | install -d -m 0755 $(DESTDIR)$(localstatedir)
56 | install -d -m 0755 $(DESTDIR)$(localstatedir)/$(APPNAME)
57 | install -m 0644 startup_db $(DESTDIR)$(localstatedir)/$(APPNAME)/
58 | install -d -m 0755 $(DESTDIR)$(YANG_INSTALLDIR)
59 | install -m 0644 $(YANGSPECS) $(DESTDIR)$(YANG_INSTALLDIR)
60 | install -m 0644 $(INSTALLFLAGS) $(PLUGIN) $(DESTDIR)$(libdir)/$(APPNAME)/backend
61 |
62 | uninstall:
63 | rm -rf $(DESTDIR)$(sysconfdir)/$(APPNAME).xml
64 | rm -rf $(DESTDIR)$(libdir)/$(APPNAME)
65 | rm -rf $(DESTDIR)$(localstatedir)/$(APPNAME)
66 | for i in $(YANGSPEC) ; \
67 | do rm $(DESTDIR)$(YANG_INSTALLDIR)/$$i; done
68 |
69 | depend:
70 | $(CC) $(DEPENDFLAGS) $(INCLUDES) $(CFLAGS) -MM $(PLUGIN_SRC) > .depend
71 |
72 | #include .depend
73 |
--------------------------------------------------------------------------------
/clixon/interfaces.xml:
--------------------------------------------------------------------------------
1 |
2 | /usr/local/etc/interfaces.xml
3 | ietf-netconf:startup
4 | clixon-restconf:allow-auth-none
5 | /usr/local/share/clixon
6 | interfaces
7 | interfaces
8 | /usr/local/lib/interfaces/clispec
9 | /usr/local/lib/interfaces/backend
10 | /usr/local/var/interfaces.sock
11 | /usr/local/var/interfaces.pidfile
12 | true
13 | /usr/local/var/interfaces
14 | init
15 | false
16 | false
17 | clicon
18 | www-data
19 | drop_perm
20 |
21 | true
22 | none
23 | false
24 | 0
25 | file
26 |
27 | default
28 | 0.0.0.0
29 | 80
30 | false
31 |
32 |
33 |
34 | false
35 |
36 | include interfaces yang
37 | enable
38 | interfaces*
39 |
40 |
41 | compress
42 | compress
43 | container
44 | list
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/clixon/interfaces_cli.cli:
--------------------------------------------------------------------------------
1 | CLICON_MODE="interfaces";
2 | CLICON_PROMPT="%W> ";
3 |
4 | edit("Edit a configuration subtree") @datamodel, cli_auto_edit("datamodel");
5 | up("Move one level up in the configuration"), cli_auto_up("datamodel");
6 | top("Move to the top level in the configuration"), cli_auto_top("datamodel");
7 | set("Set a configuration item value") @datamodel, cli_auto_set();
8 | merge("Merge configuration items") @datamodel, cli_auto_merge();
9 | create("Create a configuration item") @datamodel, cli_auto_create();
10 | delete("Delete a configuration item") {
11 | @datamodel, cli_auto_del();
12 | all("Delete whole candidate configuration"), delete_all("candidate");
13 | }
14 | validate("Validate changes"), cli_validate();
15 | commit("Commit the changes"), cli_commit();
16 | quit("Quit"), cli_quit();
17 |
18 | startup("Store running as startup config"), db_copy("running", "startup");
19 | no("Negate or remove") debug("Debugging parts of the system"), cli_debug_cli((int32)0);
20 | debug("Debugging parts of the system"), cli_debug_cli((int32)1);{
21 | level("Set debug level: 1..n") ("Set debug level (0..n)"), cli_debug_backend();
22 | }
23 | discard("Discard edits (rollback 0)"), discard_changes();
24 | compare("Compare running and candidate"), compare_dbs((int32)1);
25 |
26 | show("Show a particular state of the system"){
27 | xpath("Show configuration") ("XPATH expression") ("Namespace"), show_conf_xpath("candidate");
28 | version("Show version"), cli_show_version("candidate", "text", "/");
29 | options("Show CLI options"), cli_show_options();
30 | compare("Compare candidate and running databases"), compare_dbs((int32)0);{
31 | xml("Show comparison in xml"), compare_dbs((int32)0);
32 | text("Show comparison in text"), compare_dbs((int32)1);
33 | }
34 | configuration("Show configuration"), cli_show_config("candidate", "text", "/");{
35 | xml("Show configuration as XML"), cli_show_config("candidate", "xml", "/");{
36 | @datamodel, cli_show_auto("candidate", "xml");
37 | }
38 | cli("Show configuration as CLI commands"), cli_show_config("candidate", "cli", "/");{
39 | @datamodel, cli_show_auto("candidate", "cli");
40 | }
41 | netconf("Show configuration as netconf edit-config operation"), cli_show_config("candidate", "netconf", "/");{
42 | @datamodel, cli_show_auto("candidate", "netconf");
43 | }
44 | text("Show configuration as text"), cli_show_config("candidate","text","/");{
45 | @datamodel, cli_show_auto("candidate", "text");
46 | }
47 | json("Show configuration as JSON"), cli_show_config("candidate", "json", "/");{
48 | @datamodel, cli_show_auto("candidate", "json");
49 | }
50 | }
51 | state("Show configuration and state"), cli_auto_show("datamodel", "running", "text", true, true); {
52 | xml("Show configuration and state as XML"), cli_auto_show("datamodel", "running", "xml", true, true);
53 | }
54 | }
55 |
56 | save("Save candidate configuration to XML file") ("Filename (local filename)"), save_config_file("candidate","filename");
57 | load("Load configuration from XML file") ("Filename (local filename)"),load_config_file("filename", "replace");{
58 | replace("Replace candidate with file contents"), load_config_file("filename", "replace");
59 | merge("Merge file with existent candidate"), load_config_file("filename", "merge");
60 | }
61 |
--------------------------------------------------------------------------------
/clixon/interfaces_fake_plugin.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #define LOG_TAG "interfaces_fake_plugin"
9 | #define MAX_INDENT 128
10 |
11 | char* indent_str(size_t indent) {
12 | static char str[MAX_INDENT + 1];
13 | assert(indent <= MAX_INDENT);
14 | for (int i=0; i
2 |
3 | true
4 | none
5 | false
6 | 0
7 | file
8 |
9 | default
10 | 0.0.0.0
11 | 80
12 | false
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/clixon.md:
--------------------------------------------------------------------------------
1 | # Clixon
2 |
3 | ## Introduction
4 |
5 | [Clixon](https://github.com/clicon/clixon) can generate a server from a YANG data model.
6 |
7 | The generated server provides multiple north-bound interfaces based on the YANG data model:
8 | * A command line interface (CLI).
9 | * A NETCONF interface.
10 | * A RESTCONF interface.
11 |
12 | Clixon also provides a software development kit (SDK) that allows you to develop plugins
13 | that implement the backend of the YANG data model, such as:
14 | * Retrieve the values for operational attributes from the underlying hardware when a
15 | NETCONF get / RESTCONF get / CLI show operation is performed.
16 | * Make the values for configuration attributes take effect in the underlying hardware when a
17 | NETCONF set / RESTCONF put / CLI set operation is performed.
18 |
19 | The following figure shows the clixon architecture:
20 |
21 | 
22 |
23 | Clixon is an open source project implemented in C.
24 | You can think of Clixon as being the open source equivalent of the commercial
25 | [CONFD](https://www.tail-f.com/management-agent/) product from [Tail-F](https://www.tail-f.com/)
26 | or the YumaPro product suite from [YumaWorks](https://www.yumaworks.com/).
27 |
28 | ## Install clixon
29 |
30 | [Clixon](https://github.com/clicon/clixon) is an open source project written in C that offers a
31 | YANG-based configuration data store with plugin APIs for configuration consuming applications and
32 | with CLI, NETCONF, and RESTCONF frontend interfaces.
33 |
34 | Install the dependencies for `clixon`:
35 |
36 |
37 | $ sudo apt-get install flex bison
38 |
39 |
40 | Add `clixon` and `clicon` user groups and add users to them
41 | (replace __ with your username):
42 |
43 |
51 |
52 |
53 | Log out and log in again, to make the new user group settings take effect.
54 |
55 | Clone, build, and install the `cligen` GitHub repository:
56 |
57 |
58 | $ cd ~
59 | $ git clone https://github.com/clicon/cligen.git
60 | $ cd cligen
61 | $ ./configure
62 | $ make
63 | $ sudo make install
64 |
65 |
66 |
67 | Clone, build, and install the `clixon` GitHub repository:
68 |
69 |
70 | $ cd ~
71 | $ git clone https://github.com/clicon/clixon.git
72 | $ cd clixon
73 | $ ./configure
74 | $ make
75 | $ sudo make install
76 |
77 |
78 | We will explain how to start the clixon backend server and the clixon frontend servers for the
79 | CLI, for NETCONF, and for RESTCONF in the main body of the tutorial.
80 |
81 | ## Build the clixon backend server
82 |
83 | We will now explain how to build the clixon backend server for the `interfaces.yang` data model
84 | that we introduced earlier in this tutorial.
85 |
86 | First install clixon following the
87 | [clixon installation instructions](#clixon-installation-instructions)
88 | at the end of this tutorial.
89 |
90 | Change the current directory to the `clixon` directory in this repository:
91 |
92 |
93 | $ cd ~/yang-tutorial/clixon
94 |
95 |
96 | This directory contains the following:
97 |
98 |
106 |
107 | These files have the following functions:
108 | * File `interfaces.xml` is the the configuration file for the Clixon backend daemon.
109 | * File `interfaces_cli.cli` is the configuration file for the Clixon CLI daemon.
110 | * File `startup_db` contains startup configuration datastore.
111 | * Directory `plugins` contains tutorial code for the backend plugins (we will get to this later).
112 | * File `Makefile` contains the rules for building and installing Clixon.
113 |
114 | We will first run clixon without any plugins.
115 | Since there are no plugins yet, we don't have to compile any code.
116 | For now, the only thing we have to do is to install the clixon configuration files in the proper
117 | directories.
118 | This is achieved by running `make install` as a super user:
119 |
120 |
133 |
134 | ## Start the clixon backend server daemon
135 |
136 | Start the clixon backend daemon. The minimal command to start the clixon server is:
137 |
138 |
161 |
162 | If you ever want to restart the clixon backend daemon, you first have to stop the old daemon first
163 | using the `-z` command line option (don't do this now):
164 |
165 |
166 | $ sudo clixon_backend -f interfaces.xml -z
167 | Mar 16 15:50:42: Killing old daemon with pid: 47277
168 |
169 |
170 | ## Start the clixon CLI frontend
171 |
172 | Start the clixon command line interface (CLI) frontend:
173 |
174 |
178 |
179 | ## Use the clixon CLI
180 |
181 | The `cli>` prompt indicates that we are now in the clixon CLI that was automatically generated from
182 | `interfaces.yang` data model in combination with the `interfaces_cli.cli` configuration file.
183 |
184 | Type `?` to get a list of available CLI commands:
185 |
186 |
187 | cli> ?
188 | commit Commit the changes
189 | compare Compare running and candidate
190 | create Create a configuration item
191 | debug Debugging parts of the system
192 | delete Delete a configuration item
193 | discard Discard edits (rollback 0)
194 | load Load configuration from XML file
195 | merge Merge configuration items
196 | mode Enter a configuration mode
197 | no Negate or remove
198 | quit Quit
199 | save Save candidate configuration to XML file
200 | set Set a configuration item value
201 | show Show a particular state of the system
202 | startup Store running as startup config
203 | top Move to the top level in the configuration
204 | up Move one level up in the configuration
205 | validate Validate changes
206 | cli>
207 |
208 |
209 | If we do a `show configuration` at this point, we get no output because we have not yet configured
210 | any interfaces:
211 |
212 |
213 | cli> show configuration
214 | cli>
215 |
216 |
217 | Configure IPv4 address `10.0.0.99` on the loopback interface `lo`:
218 |
219 |
220 | cli> set interfaces interface lo ipv4-address 10.0.0.99
221 | cli>
222 |
223 |
224 | The configuration that we just added has not yet taken effect:
225 | at this point it is just a candidate configuration and not yet a running configuration.
226 |
227 | Use the commit command to make the configuration take effect, in other words to make the
228 | candidate configuration the running configuration
229 | (later, when we implement the backend plugin we will see that committing the configuration
230 | causes the IPv4 address on the real interface to change):
231 |
232 |
233 | cli> commit
234 | cli>
235 |
236 |
237 | If you try to configure some attribute that is not defined in the YANG data model
238 | (`ipv6-address` in this example),
239 | you get an error. This is the simplest example of configuration validation based on the YANG data model:
240 |
241 |
242 | cli> set interfaces interface lo ipv6-address ::10
243 | CLI syntax error: "set interfaces interface lo ipv6-address ::10": Unknown command
244 |
245 |
246 | If you try to configure an invalid IPv4 address, you also get an error.
247 |
248 |
249 | cli> set interfaces interface lo ipv4-address ::10
250 | CLI syntax error: "set interfaces interface lo ipv4-address ::10": "::10" is invalid input for cli command: ipv4-address
251 |
252 |
253 | This is more sophisticated example of configuration validation based on the YANG data model.
254 | In this example, the invalid IPv4 address `::10` is rejected by the CLI because it does not match
255 | the regular expression in the YANG data model:
256 |
257 |
258 | leaf ipv4-address {
259 | type string {
260 | pattern
261 | '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
262 | + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
263 | }
264 | description
265 | "The IPv4 address of the interface.";
266 | }
267 |
268 |
269 |
270 | Now configure the IPv4 address of a second interface `eth0`.
271 | In this case, instead of specifying the full path of the configured attribute in the `set` command,
272 | we navigate to the desired attribute using the `mode` command:
273 |
274 |
281 |
282 | In addition to the `mode` command, we can also use the `up` and `top` commands to navigate through
283 | the levels in the configuration hierarchy:
284 |
285 |
286 | cli> set ?
287 | ipv4-address The IPv4 address of the interface.
288 | cli> up
289 | cli> set ?
290 | interface The list of interfaces on the device.
291 | cli> top
292 | cli> set ?
293 | interfaces Interface parameters.
294 |
295 |
296 | Recall that we have only added this second interface to the candidate configuration;
297 | not yet to the running configuration.
298 |
299 | Before we commit, we can use the `compare` command to see what the difference is between the
300 | candidate configuration and the running configuration, in other words which configuration changes
301 | have not yet been committed:
302 |
303 |
312 |
313 | Note that the comparison looks a bit strange, because the `diff` algorithm in clixon does a simple
314 | text comparison which doesn't understand whether the first `interface {` line or the second
315 | `interface {` line was added.
316 |
317 | Now commit the candidate configuration:
318 |
319 |
320 | cli> commit
321 | cli>
322 |
323 |
324 | Now, when we do `show configuration` we see both configured interfaces:
325 |
326 |
377 |
378 | Use the `quit` command to exit the CLI and return to the Linux shell:
379 |
380 |
381 | cli> quit
382 | $
383 |
384 |
385 | ## Implement a clixon plugin
386 |
387 | Clixon has the concept of plugins. The responsibilities of a plugin include:
388 |
389 | * Validate changes to the data store before they are committed.
390 | Many constraints can be expressed in the YANG data model and can be validated by the clixon
391 | backend server without having to manually write any code.
392 | For example, the `ipv4-address` attribute in our data model enforces that the IPv4 address has
393 | the correct format by using the `pattern` option and a regular expression.
394 | Other constraints cannot be expressed in YANG and those constraints are validated by the
395 | plugin.
396 | In this tutorial we will enforce the (silly) constraint that there cannot be more than two
397 | interfaces starting with the letter x.
398 |
399 | * After each commit that passed the validation phase, process all configuration changes and
400 | make them take effect on the underlying hardware platform.
401 | In our example, when the user adds a new interface with an IPv4 address, the plugin must
402 | interact with the TCP/IP stack to add the IPv4 address. Or when the user modifies the IPv4
403 | address of an existing interface in the data store, the plugin must correspondingly modify the
404 | IPv4 address of the corresponding interface in the TCP/IP stack. Or when the user deletes
405 | an interface from the data store, the plugin must interact with the TCP/IP stack to remove
406 | the IPv4 address from the corresponding interface.
407 |
408 | * When the user retrieves the value of an operational attribute (e.g. using a `show` command the
409 | CLI), the plugin must provide the requested value. For example, when the value of the
410 | `sent-packets` attribute in the YANG data model is requested, the plugin must retrieve the
411 | corresponding counter from the TCP/IP stack.
412 |
413 | We will now implemented a fake plugin.
414 | It is fake in the sense that it will just swallow any configured IPv4 address without applying
415 | it to a real interface,
416 | and it will just return random values for the packet counters instead of reading the real counters
417 | from the real interfaces.
418 | Later, we will convert the fake plugin with a real plugin that configures and reads the real
419 | interfaces.
420 | But for now, we start simple and focus on the APIs provided by clixon.
421 |
422 | TODO: Get rid of the 'fake' terminology.
423 |
424 | The file `interfaces_fake_plugin.c` contains the code for our fake plugin.
425 | We will now walk through the code to explain how it works.
426 |
427 | The first thing we have to do is to register our plugin and its callback functions:
428 |
429 | TODO: write code first
430 |
431 | We register callbacks for validation (`ca_trans_validate`) and for commit (`ca_trans_commit`).
432 | We also register callbacks for the beginning of a transaction (`ca_trans_begin`) and the end
433 | of a transaction (`ca_trans_end`).
434 | We don't do anything in these callbacks, but it is necessary to register for them anyway,
435 | otherwise the validation and commit callback won't get called.
436 | There are additional callbacks that one can register for
437 | including, `ca_trans_complete`, `ca_trans_commit_done`, `ca_trans_revert`, and `ca_trans_abort`.
438 |
439 |
440 | ## References
441 |
442 | * [The clixon GitHub repository](https://github.com/clicon/clixon)
443 |
444 | * [The clixon examples GitHub repository](https://github.com/clicon/clixon-examples)
445 |
446 | * [Clixon documentation](https://clixon-docs.readthedocs.io/en/latest/)
447 |
448 |
--------------------------------------------------------------------------------
/docs/example-yang-data-model.md:
--------------------------------------------------------------------------------
1 | # An example YANG data model
2 |
3 | We are going to start by writing a simple YANG data model that we will use throughout
4 | the remainder of this tutorial.
5 |
6 | Our data model manages the interfaces on a device. It contains a list of interfaces, and each
7 | interface has a name, an IPv4 address, and counters for the number of sent and received
8 | packets.
9 |
10 | In real life, the data models for managing interfaces
11 | ([RFC 8343](https://www.rfc-editor.org/rfc/pdfrfc/rfc8343.txt.pdf))
12 | and for managing IP addresses
13 | ([RFC 8344](https://www.rfc-editor.org/rfc/pdfrfc/rfc8344.txt.pdf))
14 | are way more complex, but we are using a simplistic data model in this tutorial to keep the
15 | example code short and easy to understand.
16 |
17 | Here is our data model (you can find it in this repository in the file `interfaces.yang`):
18 |
19 | ```yang
20 | module interfaces {
21 |
22 | namespace "http://remoteautonomy.com/yang-schemas/interfaces";
23 | prefix intf;
24 |
25 | organization
26 | "Remote Autonomy";
27 |
28 | contact
29 | "Bruno Rijsman
30 | brunorijsman@remoteautonomy.com";
31 |
32 | description
33 | "A simplistic tutorial data model for interfaces on a device.";
34 |
35 | revision 2022-03-12 {
36 | description
37 | "Initial revision.";
38 | }
39 |
40 | container interfaces {
41 | description
42 | "Interface parameters.";
43 |
44 | list interface {
45 | key "name";
46 | description
47 | "The list of interfaces on the device.";
48 |
49 | leaf name {
50 | type string;
51 | description
52 | "The name of the interface.";
53 | }
54 |
55 | leaf ipv4-address {
56 | type string {
57 | pattern
58 | '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
59 | + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
60 | }
61 | description
62 | "The IPv4 address of the interface.";
63 | }
64 |
65 | leaf sent-packets {
66 | type uint64;
67 | config false;
68 | description
69 | "The number of IPv4 packets sent out over this interface";
70 | }
71 |
72 | leaf received-packets {
73 | type uint64;
74 | config false;
75 | description
76 | "The number of IPv4 packets received over this interface";
77 | }
78 | }
79 | }
80 | }
81 | ```
82 |
83 | There is also a file called `bad-interfaces.yang` that contains some errors on purpose so that
84 | we can demonstrate the error messages produced by the various YANG validation tools.
85 |
86 | TODO: Add an RPC to the data model
--------------------------------------------------------------------------------
/docs/figures/clixon-architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/clixon-architecture.jpg
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-choose-yang-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-choose-yang-file.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-config-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-config-tree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-config-xml.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-config-xml.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-connect-to-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-connect-to-server.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-connected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-connected.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-edit-config-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-edit-config-details.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-edit-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-edit-config.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-expand-entire-subtree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-expand-entire-subtree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-first-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-first-time.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-get-config.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-get-config.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-icon.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-interfaces-subtree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-interfaces-subtree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-message-id.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-message-id.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-module-in-panel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-module-in-panel.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-startup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-startup.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-browser-validate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-browser-validate.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-netconf-simulator-need-java.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-netconf-simulator-need-java.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-components-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-components-tab.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-create-new-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-create-new-project.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-edit-module.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-edit-module.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-empty-module.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-empty-module.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-errors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-errors.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-first-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-first-time.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-icon.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-module-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-module-details.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-new-module-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-new-module-button.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-project-details-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-project-details-2.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-project-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-project-details.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-designer-source-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-designer-source-code.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-choose-yang-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-choose-yang-file.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-dependencies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-dependencies.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-find-nodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-find-nodes.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-first-time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-first-time.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-icon.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-interface-model-details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-interface-model-details.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-interface-model-expanded-subtree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-interface-model-expanded-subtree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-interface-model-source.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-interface-model-source.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-interface-model-text-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-interface-model-text-tree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-show-in-yang-tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-show-in-yang-tree.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-startup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-startup.png
--------------------------------------------------------------------------------
/docs/figures/mgsoft-yang-explorer-uml-class-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/mgsoft-yang-explorer-uml-class-diagram.png
--------------------------------------------------------------------------------
/docs/figures/pyang-jstree-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/pyang-jstree-diagram.png
--------------------------------------------------------------------------------
/docs/figures/pyang-uml-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/pyang-uml-diagram.png
--------------------------------------------------------------------------------
/docs/figures/yang-validator-home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yang-validator-home.png
--------------------------------------------------------------------------------
/docs/figures/yang-validator-validation-bad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yang-validator-validation-bad.png
--------------------------------------------------------------------------------
/docs/figures/yang-validator-validation-good.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yang-validator-validation-good.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-client-execute-error-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-client-execute-error-1.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-client-execute-error-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-client-execute-error-2.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-client-execute-error-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-client-execute-error-3.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-client-execute-error-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-client-execute-error-4.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-html-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-html-file.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-sdk-basic-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-sdk-basic-components.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-sdk-components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-sdk-components.png
--------------------------------------------------------------------------------
/docs/figures/yuma-pro-sdk-feature-comparison.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yuma-pro-sdk-feature-comparison.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-add-2nd-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-add-2nd-interface.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-add-device.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-add-device.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-add-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-add-interface.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-add-session.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-add-session.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-add-user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-add-user.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-notifications.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-notifications.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-operational-state.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-operational-state.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-select-devices.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-select-devices.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-session-window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-session-window.png
--------------------------------------------------------------------------------
/docs/figures/yumabench-startup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/docs/figures/yumabench-startup.png
--------------------------------------------------------------------------------
/docs/mg-soft-browser.md:
--------------------------------------------------------------------------------
1 | # MG-SOFT NetConf Browser Professional Edition
2 |
3 | ## Introduction
4 |
5 | [MG-SOFT](https://www.mg-soft.si/) is a company that offers a suite of network management related
6 | products.
7 | One of their products, the
8 | [MG-SOFT NetConf Browser Professional Edition](https://www.mg-soft.si/mgNetConfBrowser.html)
9 | is a client that can connect to a NETCONF or RESTCONF server and that offers a graphical user
10 | interface for exploring and editing the data store in the server.
11 |
12 | ## Download and install
13 |
14 | You can download the MG-SOFT NetConf Browser Professional Edition from the
15 | [download page](https://www.mg-soft.si/download.html?product=netconfbrowser)
16 | on the MG-SOFT website.
17 |
18 | MG-SOFT offers a version of the browser that runs natively on Linux, but I find it more
19 | convenient to run the macOS version of the browser and connect to the NETCONF server that
20 | runs inside my Ubuntu virtual machine over the bridge network.
21 |
22 | To do anything interesting with the MG-SOFT NetConf Browser, you will need to apply a license key.
23 | You can [purchase a license online](https://www.mg-soft.si/mgNetConfBrowser-ordering.html)
24 | or you can [request a 30-day evaluation license online](https://www.mg-soft.si/evalKeyReq.html).
25 | Note: I am not affiliated with MG-SOFT in any way and I don't get any commission.
26 |
27 | ## Start the clixon NETCONF server
28 |
29 | The MG-SOFT NetConf Browser is a NETCONF client, so we need a NETCONF server to be running.
30 | We will use clixon as the NETCONF server.
31 | Refer to the [clixon chapter in this tutorial](clixon.md) for instructions on how install clixon,
32 | how to build clixon, how the start the clixon backend daemon, and how to configure SSH to start
33 | the clixon NETCONF server.
34 |
35 | As a quick sanity check to make sure the NETCONF server is running properly,
36 | manually start an SSH session
37 | (replace username@<vm-ip-address> with the usenname and IP address of the virtual
38 | machine that runs the clixon NETCONF server).
39 | You should see a NETCONF `hello` message from the server:
40 |
41 |
46 |
47 | Type Control-D to exit the SSH session.
48 |
49 | # Start the MG-SOFT NetConf Browser
50 |
51 | Double click on the MG-SOFT NetConf Browser icon in the applications folder.
52 |
53 | 
54 |
55 | When you start the MG-SOFT NetConf Browser for the first time, it will give you the opportunity
56 | to install the evaluation license
57 | (you can also do this later using the Help → Apply License Key... menu item.)
58 |
59 | 
60 |
61 | After installing the license key, you end up in the following screen:
62 |
63 | 
64 |
65 | # Load the YANG data model
66 |
67 | The first thing we have to do is to load our `interfaces.yang` YANG data model into the
68 | MG-SOFT NetConf Browser.
69 | Select the Module → Load Module... menu item, and open the `interfaces.yang` file in this
70 | repository.
71 |
72 | 
73 |
74 | The `interfaces` YANG module appears in the left pane of the MG-SOFT NetConf Browser.
75 |
76 | 
77 |
78 | You can right-click on `interfaces` and choose menu item Expand Entire Subtree.
79 |
80 | 
81 |
82 | This shows an outline of the `interfaces` YANG module.
83 |
84 | 
85 |
86 | # Connect to the NETCONF server
87 |
88 | To connect ot the clixon NETCONF server, select the File → Connect... menu item and enter the
89 | following information (replace 10.211.55.8 with the IP address of the virtual machine that runs
90 | your NETCONF server and replace parallels with the username on the virtual machine).
91 |
92 | 
93 |
94 | Note: until recently clixon had a bug that prevented it from interoperating with clients running
95 | NETCONF version 1.1 (see [clixon issue #314](https://github.com/clicon/clixon/issues/314)).
96 | The symptom is that the clixon server stops responding after the initial hello message.
97 | By the time you are reading this tutorial, that bug should already have been fixed, but if not,
98 | you can work around the issue by selecting NETCONF version → 1.0 in the connect screen.
99 |
100 | If you click on the Session History tab, you can see that the session is connected.
101 |
102 | 
103 |
104 | # Retrieve the configuration
105 |
106 | To retrieve the current candidate configuration (for example), right-click on the interfaces
107 | module, and then select get config (execute) → candidate.
108 |
109 | 
110 |
111 | The retrieved configuration is shown in XML format in the middle pane (which you can make
112 | bigger). Note: this screenshot assumes that two interfaces have been configured in the clixon CLI.
113 |
114 | 
115 |
116 | To display the same configuration in a more convenient graphical tree format, click
117 | on the Output Tree tab:
118 |
119 | 
120 |
121 | # Change the configuration
122 |
123 | To edit the candidate configuration, right-click on the interfaces
124 | module, and then select edit config (compose) → candidate.
125 |
126 | 
127 |
128 | The NETCONF Content Editor window will appear, in which you can change the configuration
129 | (here we changed the IP address for interface eth1 from 2.2.2.2 to 3.3.3.3).
130 |
131 | 
132 |
133 | Note: the nixon NETCONF server does not accept an empty message identified, so you have to enter
134 | some value (any value) for the `message-id`.
135 |
136 | 
137 |
138 | At this point you can validate the new configuration on the server by clicking on the
139 | Validate on Server button (yellow document with green checkmark):
140 |
141 | 
142 |
143 | TODO: This does not work; MG-SOFT NetConf Browser reports an error:
144 |
145 | ```xml
146 |
147 |
148 |
149 | application
150 | operation-failed
151 | error
152 | open(/usr/local/var/interfaces/config_db)
153 |
154 |
155 | ```
156 |
157 | For some reason, clixon tries to open `/usr/local/var/interfaces/config_db` which does not exist:
158 |
159 |
166 |
167 | ## References
168 |
169 | * [The MG-SOFT company homepage](https://www.mg-soft.si/)
170 |
171 | * [The MG-SOFT NetConf Browser Professional Edition product page](https://www.mg-soft.si/mgNetConfBrowser.html)
172 |
--------------------------------------------------------------------------------
/docs/mg-soft-designer.md:
--------------------------------------------------------------------------------
1 | # MG-SOFT Visual YANG Designer Professional Edition
2 |
3 | ## Introduction
4 |
5 | [MG-SOFT](https://www.mg-soft.si/) is a company that offers a suite of network management related
6 | products.
7 | One of their products, the
8 | [MG-SOFT Visual YANG Designer Professional Edition](https://www.mg-soft.si/mgYangDesigner.html)
9 | is a YANG authoring tool that allows you to edit YANG data models in an integrated development
10 | environment (IDE).
11 |
12 | ## Download and install
13 |
14 | You can download the MG-SOFT Visual YANG Designer Professional Edition from the
15 | [download page](https://www.mg-soft.si/download.html?product=yangdesigner&os=java)
16 | on the MG-SOFT website.
17 | The designer is available for Windows, macOS, and several flavors of Linux.
18 | In this tutorial I use the macOS version.
19 |
20 | To do anything interesting with the MG-SOFT Visual YANG Designer, you will need to apply a license key.
21 | You can [purchase a license online](https://www.mg-soft.si/mgYangDesigner-ordering.html)
22 | or you can [request a 30-day evaluation license online](https://www.mg-soft.si/evalKeyReq.html).
23 | The evaluation license does not allow you to save YANG files.
24 | Note: I am not affiliated with MG-SOFT in any way and I don't get any commission.
25 |
26 | ## Start
27 |
28 | Double click on the MG-SOFT Visual YANG Designer icon in the applications folder.
29 |
30 | 
31 |
32 | When you start the MG-SOFT Visual YANG Designer for the first time, it will give you the opportunity
33 | to install the evaluation license
34 | (you can also do this later using the Help → Apply License Key... menu item.)
35 |
36 | 
37 |
38 | ## Create a new project
39 |
40 | After MG-SOFT Visual YANG Designer has been started, choose the Create a new project option:
41 |
42 | 
43 |
44 | and enter the details for the newly created project:
45 |
46 | 
47 |
48 | 
49 |
50 | ## Create a new module
51 |
52 | Click on the new module button:
53 |
54 | 
55 |
56 | and enter the details for the newly created module:
57 |
58 | 
59 |
60 | The newly created empty module is displayed:
61 |
62 | 
63 |
64 | ## Add components to the module
65 |
66 | In the left Project panel click on the tab:
67 |
68 | 
69 |
70 | Drag and drop components from the left Project panel to the middle YANG Tree Preview panel.
71 | As you are dropping the component into the middle YANG Tree Preview panel,
72 | you will see gray lines to indicate where the component is allowed to be dropped.
73 | After a component has been dropped in place, you can enter details for component in the top
74 | right Node Editor panel (in the screenshot below we are entering details for a newly added `burners`
75 | container).
76 | In the bottom right Source panel you can see and edit the source code for the YANG data model as
77 | it is being constructed.
78 |
79 | 
80 |
81 | ## View the module source
82 |
83 | Click on the to see and edit the source code of the YANG data model in a
84 | larger Source panel in the top right:
85 |
86 | 
87 |
88 | ## View errors
89 |
90 | If there are any errors in your YANG data models, you can see them in the
91 | tab in the bottom-right panel, and the offending lines
92 | are marked with a red exclamation mark in the source code:
93 |
94 | 
95 |
96 | ## References
97 |
98 | * [The MG-SOFT company homepage](https://www.mg-soft.si/)
99 |
100 | * [The MG-SOFT Visual YANG Designer Professional Edition product page](https://www.mg-soft.si/mgYangDesigner.html)
101 |
--------------------------------------------------------------------------------
/docs/mg-soft-explorer.md:
--------------------------------------------------------------------------------
1 | # MG-SOFT YANG Explorer Professional Edition
2 |
3 | ## Introduction
4 |
5 | [MG-SOFT](https://www.mg-soft.si/) is a company that offers a suite of network management related
6 | products.
7 | One of their products, the
8 | [MG-SOFT YANG Explorer Professional Edition](https://www.mg-soft.si/mgYangExplorer.html)
9 | allows you to explore, validate, and convert YANG data models.
10 |
11 | ## Download and install
12 |
13 | You can download the MG-SOFT YANG Explorer Professional Edition from the
14 | [download page](https://www.mg-soft.si/download.html?product=yangexplorer&os=java)
15 | on the MG-SOFT website.
16 | The explorer is available for Windows, macOS, and several flavors of Linux.
17 | In this tutorial I use the macOS version.
18 |
19 | To do anything interesting with the MG-SOFT YANG Explorer, you will need to apply a license key.
20 | You can [purchase a license online](https://www.mg-soft.si/mgYangExplorer-ordering.html)
21 | or you can [request a 30-day evaluation license online](https://www.mg-soft.si/evalKeyReq.html).
22 | Note: I am not affiliated with MG-SOFT in any way and I don't get any commission.
23 |
24 | ## Start
25 |
26 | Double click on the MG-SOFT YANG Explorer icon in the applications folder.
27 |
28 | 
29 |
30 | When you start the MG-SOFT YANG Explorer for the first time, it will give you the opportunity
31 | to install the evaluation license
32 | (you can also do this later using the Help → Apply License Key... menu item.)
33 |
34 | 
35 |
36 | After installing the license key, you end up in the following screen.
37 | On the left side you see a list of standard IETF YANG data models that come bundled with the
38 | MG-SOFT YANG Explorer.
39 |
40 | 
41 |
42 | # Load a YANG data model
43 |
44 | The first thing we have to do is to load our `interfaces.yang` YANG data model into the
45 | MG-SOFT YANG Explorer.
46 | Select the Module → Load Module... menu item, and open the `interfaces.yang` file in this
47 | repository.
48 |
49 | 
50 |
51 | # Explore a YANG data model
52 |
53 | The `interfaces` YANG module appears in the left pane; when you click on it, you get the details.
54 |
55 | 
56 |
57 | You can click on the triangle next to the `interfaces` YANG module to expand it one level,
58 | or you can right-click on the module and select Expand Entire Subtree:
59 |
60 | 
61 |
62 | While in the tree pane, you can use menu item Edit → Find Nodes... (⌘F) to search for specific nodes.
63 | In the following screenshot we search for all leaf nodes that contain the word address:
64 |
65 | 
66 |
67 | Clicking the tab displays the textual tree diagram:
68 |
69 | 
70 |
71 | Clicking the tab displays the source code for the YANG data model:
72 |
73 | 
74 |
75 | Our `interfaces` example YANG module is very simple and doesn't import any other modules,
76 | but most real-life modules do.
77 | The following screenshot shows the standard IETF YANG module `ietf-ipv6-unicast-routing`.
78 | On line 15 it imports another YANG module `ietf-inet-types`.
79 | You can right-click on the `import` statement and select Show in YANG Tree to navigate to the
80 | imported module
81 |
82 | 
83 |
84 | ## View UML diagram
85 |
86 | Select menu item View → UML Class Diagram... and click on the 🔧 icon to select a YANG data model
87 | and displays its UML class diagram:
88 |
89 | 
90 |
91 | ## View dependencies
92 |
93 | Select menu item View → YANG Dependencies... and click on the 🔧 icon to select a YANG data model
94 | and displays its YANG dependencies:
95 |
96 | 
97 |
98 | ## References
99 |
100 | * [The MG-SOFT company homepage](https://www.mg-soft.si/)
101 |
102 | * [The MG-SOFT YANG Explorer Professional Edition product page](https://www.mg-soft.si/mgYangExplorer.html)
103 |
--------------------------------------------------------------------------------
/docs/mg-soft-simulator.md:
--------------------------------------------------------------------------------
1 | # MG-SOFT NETCONF Simulator
2 |
3 | ## Introduction
4 |
5 | [MG-SOFT](https://www.mg-soft.si/) is a company that offers a suite of network management related
6 | products.
7 | One of their products, the
8 | [MG-SOFT NETCONF Simulator](https://www.mg-soft.si/mgNetConfSimulator.html)
9 | allows you to simulate network devices that act as NETCONF or RESTCONF servers.
10 |
11 | ## Download and install (attempt)
12 |
13 | You can download the MG-SOFT NETCONF Simulator Edition from the
14 | [download page](https://www.mg-soft.si/download.html?product=netconfsimulator)
15 | on the MG-SOFT website.
16 | The simulator is only available on Microsoft Windows.
17 |
18 | Unfortunately, I don't own any Windows computers.
19 | I tried using Microsoft Windows Server 2019 Base running in a t2.large instance on Amazon Web
20 | Services (AWS), but when I ran the MG-SOFT NETCONF Simulator installer, I got the following
21 | error message about needing a Java Run-time Environment (JRE):
22 |
23 | 
24 |
25 | Downloading and installing "Java for Windows" from
26 | the [Oracle website](https://www.java.com/en/download/) did not solve the problem.
27 | I spent a half hour Googling how to download "64-bit JRE 1.8" but could not figure it out and
28 | eventually gave up.
29 |
30 |
--------------------------------------------------------------------------------
/docs/ncclient.md:
--------------------------------------------------------------------------------
1 | # Ncclient
2 |
3 | ## Introduction
4 |
5 | [Ncclient](https://github.com/ncclient/ncclient) (short for NETCONF client) is an open source
6 | Python module that allows you to develop Python scripts that interact with a NETCONF server.
7 |
8 | One issue with this project is that the
9 | [documentation page](https://ncclient.readthedocs.io/en/latest/)
10 | appears to be broken for some time now (many pages contain lists of empty placeholders).
11 | So, you will have to be comfortable reading
12 | [the source code of `ncclient` on GitHub](https://github.com/ncclient/ncclient/tree/master/ncclient)
13 | as documentation of its API.
14 |
15 | ## Install ncclient
16 |
17 | If you followed the
18 | [instructions for setting up the environment for this tutorial](tutorial-install.md)
19 | then ncclient is already installed.
20 |
21 | Or, use `pip` if you want to install ncclient separately:
22 |
23 |
24 | $ pip install ncclient
25 |
26 |
27 | ## Start the clixon NETCONF server
28 |
29 | The MG-SOFT NetConf browser is a NETCONF client, so we need a NETCONF server to be running.
30 | We will use clixon as the NETCONF server.
31 | Refer to the [clixon chapter in this tutorial](clixon.md) for instructions on how install clixon,
32 | how to build clixon, how the start the clixon backend daemon, and how to configure SSH to start
33 | the clixon NETCONF server.
34 |
35 | As a quick sanity check to make sure the NETCONF server is running properly,
36 | manually start an SSH session. You should see a NETCONF `hello` message from the server:
37 |
38 |
43 |
44 | Type Control-D to exit the SSH session.
45 |
46 | ## Example Python scripts
47 |
48 | This repository contains several example Python scripts that use the `ncclient` Python module.
49 | In the remainder of this chapter we will walk you through those examples.
50 |
51 |
52 | $ cd ~/yang-tutorial/ncclient
53 |
54 | $ ls -1
55 | [TODO] output
56 |
57 |
58 | You may optionally set the following environment variables to configure the address, username,
59 | and password of the NETCONF server:
60 |
61 |
222 |
223 |
--------------------------------------------------------------------------------
/docs/netopeer2.md:
--------------------------------------------------------------------------------
1 | # Netopeer2
2 |
3 | ## Introduction
4 |
5 | [Netopeer2](https://github.com/CESNET/netopeer2)
6 | is an open source NETCONF server developed by
7 | [CESNET](https://www.cesnet.cz/cesnet/?lang=en),
8 | an association of universities of the Czech Republic and the Czech Academy of Sciences.
9 |
10 | ## Installation
11 |
12 | We use an AWS t2.medium instance with 8 GB of disk running Ubuntu server 22.04 LTS.
13 |
14 | Follow the netopeer2 installation instructions documented
15 | [here](https://github.com/CESNET/netopeer2#compilation-and-installation):
16 |
17 | Update `apt`:
18 |
19 |
20 | $ sudo apt update
21 |
22 |
23 | If any of the following steps generates a popup window, use tab and enter to select Ok.
24 |
25 | Install `cmake`:
26 |
27 |
204 |
205 | ## Set a password for user `ubuntu`
206 |
207 | Set the password for user `ubuntu` to `secret` to allows `netopeer2-cli`
208 | (the NETCONF client) to use password authentication (for now) when connecting to
209 | `netopeer2-server` (the NETCONF server):
210 |
211 |
212 | $ sudo passwd ubuntu
213 | New password: secret
214 | Retype new password: secret
215 |
216 |
217 | ## Start the NETCONF server
218 |
219 | Start the `netopeer2-server` NETCONF server as a daemon:
220 |
221 |
20 |
21 | Install `pyang` into your virtual environment:
22 |
23 |
24 | $ pip install pyang
25 |
26 |
27 | Verify that `pyang` is properly installed:
28 |
29 |
30 | $ pyang --version
31 | pyang 2.5.2
32 |
33 |
34 | One of the examples in the tutorial converts the YANG data model into a UML diagram.
35 | This requires [PlantUML](https://plantuml.com/) to be installed:
36 |
37 |
38 | $ sudo apt install -y plantuml
39 |
40 |
41 | ## Pyang: Validating a YANG data model
42 |
43 | The simplest way of using pyang is to validate the correctness of a YANG data model:
44 |
45 |
46 | $ pyang interfaces.yang
47 |
48 |
49 | The fact that we get no output means that the YANG file was correct. In addition, the program
50 | returns status code zero, so you can do something like this:
51 |
52 |
53 | $ if pyang interfaces.yang; then echo "All good"; else "There are errors"; fi
54 | All good
55 |
56 |
57 | Validate YANG data model `bad-interfaces.yang` to see an example of the error messages produced
58 | by `pyang`:
59 |
60 |
61 | $ pyang bad-interfaces.yang
62 | bad-interfaces.yang:7: error: unexpected keyword "organisation"
63 | bad-interfaces.yang:47: error: type "uint46" not found in module "bad-interfaces"
64 |
65 |
66 | ## Pyang: Converting a YANG data model
67 |
68 | YANG data models tend to be very long and verbose. Pyang can produce a summary of the YANG data
69 | model in a tree format:
70 |
71 |
81 |
82 | The command `pyang --tree-help` displays an explanation of the symbols in the tree diagram.
83 |
84 | In addition to producing a tree summary, Pyang can also convert the YANG data model to many other
85 | formats:
86 |
87 |
88 | $ pyang --help
89 | Usage: pyang [options] [<filename>...]
90 |
91 | Validates the YANG module in <filename> (or stdin), and all its dependencies.
92 |
93 | Options:
94 | -h, --help Show this help message and exit
95 | [...]
96 | -f FORMAT, --format=FORMAT
97 | Convert to FORMAT. Supported formats are: yang, yin,
98 | dsdl, omni, tree, jstree, flatten, uml, identifiers,
99 | sample-xml-skeleton, capability, jsonxsl, depend,
100 | jtox, name
101 | [...]
102 |
103 |
104 | We will give just a couple of examples of interesting format conversions.
105 |
106 | Use the following command to produce an HTML file that describes the YANG data model
107 | (`jstree` stands for JavaScript tree):
108 |
109 |
112 |
113 | Use any web browser to view the produced HTML file. Here we assume that you are running Ubuntu and
114 | that you can start `firefox` from command line (on macOS use `open interfaces.html`):
115 |
116 |
117 | $ firefox interfaces.html
118 |
119 |
120 | 
121 |
122 | Another interesting option is to convert the YANG data model into a UML diagram:
123 |
124 |
127 |
128 | You need to have `plantuml` installed (see
129 | [pyang installation instructions](#pyang-installation-instructions)
130 | ) to convert the produced UML text file to a graphical PNG file:
131 |
132 |
133 | $ plantuml interfaces.uml
134 |
135 |
136 | The PNG file can be viewed in a web browser:
137 |
138 |
139 | $ firefox img/interfaces.png
140 |
141 |
142 | 
143 |
144 | ## References
145 |
146 | * [The pyang GitHub repository](https://github.com/mbj4668/pyang)
147 |
148 | * [A pyang tutorial](https://www.ietf.org/slides/slides-edu-pyang-tutorial-01.pdf)
149 |
150 | * [The PlantUML home page](https://plantuml.com/)
151 |
152 |
--------------------------------------------------------------------------------
/docs/references.md:
--------------------------------------------------------------------------------
1 | # References
2 |
3 | ## Standards
4 |
5 | ### YANG
6 |
7 | The most important standards that define the YANG data modeling language are:
8 |
9 | * [RFC 6020: YANG - A Data Modeling Language for the Network Configuration Protocol (NETCONF)](https://datatracker.ietf.org/doc/html/rfc6020)
10 | * [RFC 6244: An Architecture for Network Management Using NETCONF and YANG](https://datatracker.ietf.org/doc/html/rfc6244)
11 | * [RFC 7950: The YANG 1.1 Data Modeling Language](https://datatracker.ietf.org/doc/html/rfc7950)
12 | * [RFC 8407: Guidelines for Authors and Reviewers of Documents Containing YANG Data Models](https://datatracker.ietf.org/doc/html/rfc8407)
13 |
14 | For a complete list of YANG related standards see [IETF NETMOD standards](https://datatracker.ietf.org/wg/netmod/documents/)
15 |
16 | ### NETMOD
17 |
18 | * [The IETF NETMOD working group](https://datatracker.ietf.org/wg/netmod/about/)
19 | * [IETF NETMOD standards](https://datatracker.ietf.org/wg/netmod/documents/)
20 |
21 | ### NETCONF
22 |
23 | * [The IETF NETCONF working group](https://datatracker.ietf.org/wg/netconf/about/)
24 | * [IETF NETCONF standards](https://datatracker.ietf.org/wg/netconf/documents/)
25 |
26 | ### RESTCONF
27 |
28 | TODO
29 |
30 | ### gNMI
31 |
32 | TODO
33 |
34 | ## Tutorials
35 |
36 | * [Learn YANG - Full Tutorial for Beginners (Ultra Config)](https://ultraconfig.com.au/blog/learn-yang-full-tutorial-for-beginners/)
37 |
--------------------------------------------------------------------------------
/docs/tail-f-confd.md:
--------------------------------------------------------------------------------
1 | # Tail-f ConfD
2 |
3 | ## Introduction
4 |
5 | [Tail-f](https://www.tail-f.com/) is a company that specializes in network programmability and
6 | data model driven device management.
7 | Tail-f was acquired by [Cisco](https://www.cisco.com/) in 2014.
8 |
9 | One of their products is ConfD: an on-device network management agent that uses YANG data modeling,
10 | that provides NETCONF and RESTCONF management protocols as well as a command line interface (CLI),
11 | and that provides a centralized transactional configuration database.
12 |
13 | Tail-f ConfD comes in two versions:
14 | [ConfD premium](https://www.tail-f.com/management-agent/) which is a paid version,
15 | and [ConfD basic](https://www.tail-f.com/confd-basic/) which is a free version with a subset
16 | of the features.
17 |
18 | In this tutorial we use the ConfD basic running on Ubuntu.
19 |
20 | TODO: I cannot download ConfD basic. The Tail-f website reports
21 | "ConfD Basic Downloads are temporarily disabled. Please contact confdbasicinfo@cisco.com with any
22 | questions you may have.”
23 |
24 | ## References
25 |
26 | * [The tail-f company homepage (a Cisco company)](https://www.tail-f.com/)
27 |
28 | * [The CONFD basic product homepage](https://www.tail-f.com/confd-basic/)
29 |
30 | * [The CONFD premium product homepage](https://www.tail-f.com/management-agent/)
31 |
--------------------------------------------------------------------------------
/docs/tutorial-install.md:
--------------------------------------------------------------------------------
1 | # Setting up the environment for this tutorial
2 |
3 | ## Cloning and setting up this repository
4 |
5 | Clone this repository:
6 |
7 |
16 |
17 | In the remainder of this tutorial I will assume that you cloned the repository into your home
18 | directory. If not, replace `~` with whatever directory you cloned the repository into.
19 |
20 | ## Setting up a python virtual environment
21 |
22 | Make sure that we have version 3.8 or higher of Python installed:
23 |
24 |
54 |
--------------------------------------------------------------------------------
/docs/yang-validator.md:
--------------------------------------------------------------------------------
1 | # YANG validator
2 |
3 | ## Introduction
4 |
5 | [YANG validator](https://yangcatalog.org/yangvalidator) is a web-based YANG data model validator.
6 | It is part of the [YANG catalog](https://yangcatalog.org/home.html) website.
7 |
8 | The home page of the YANG validator looks like this:
9 |
10 | 
11 |
12 | ## Validate a correct YANG data model
13 |
14 | To validate the `interfaces.yang` data model, click the
15 |
16 | button in the
17 | "I have one or multiple YANG files and I want to validate them"
18 | section, select file `interfaces.yang` and then click the
19 |
20 | button.
21 |
22 | The validation results page reports the following results:
23 |
24 | * Extraction results from [XYM](https://github.com/xym-tool/xym) which is a tool to extract YANG data models
25 | from a file (e.g. an IETF ID or RFC).
26 |
27 | * Validation results from the pyang YANG validator.
28 | See the [pyang page in this tutorial](tutorial/payng.md) for more details on pyang.
29 |
30 | * Validation results from the Cisco Tail-f ConfD YANG compiler.
31 | See the [CONFD page in this tutorial](tutorial/confd.md) (TODO) for more details on ConfD.
32 |
33 | * Validation results from the yanglint YANG validator.
34 | See the [yanglint page in this tutorial](tutorial/yanglint.md) for more details on yanglint.
35 |
36 | * Validation results from the YumaWorks yangdump-pro YANG validator.
37 | See the [yangdump-pro page in this tutorial](tutorial/yangdump-pro.md) (TODO) for more details on yangdump-pro.
38 |
39 | 
40 |
41 | ## Validate an incorrect YANG data model
42 |
43 | The following screenshot shows an example of validating an incorrect YANG data model,
44 | namely `bad-interfaces.yang`.
45 |
46 | 
47 |
48 | ## Validate an IETF internet draft (ID) or request for comment (RFC)
49 |
50 | YANG validator can also validate an IETF internet draft (ID) or request for comment (RFC)
51 | that contains YANG data models (as described in section 3.2 of
52 | [RFC 8407](https://datatracker.ietf.org/doc/rfc8407/)).
53 |
54 | For example, enter [8348](https://datatracker.ietf.org/doc/rfc8348/)
55 | in the field in the
56 | "I know the number of IETF RFC and I want to validate it"
57 | section, then click the
58 |
59 | button, and accept the default values in the "Additional Information Required" window
60 |
61 | ## References
62 |
63 | * [YANG Validator home page](https://yangcatalog.org/yangvalidator)
64 |
65 | * [XYM YANG data model extraction tool](https://github.com/xym-tool/xym)
66 |
--------------------------------------------------------------------------------
/docs/yanglint.md:
--------------------------------------------------------------------------------
1 | # Yanglint
2 |
3 | ## Introduction
4 |
5 | [Yanglint](https://www.mankier.com/1/yanglint)
6 | is command-line tool for validating and converting YANG schemas and YANG modeled data.
7 | It is part of the [libyang](https://github.com/CESNET/libyang) open source project and
8 | implemented in C.
9 |
10 | ## Install Yanglint
11 |
12 | Install `yang-tools` (which includes `yanglint`). On Ubuntu this can be done as follows:
13 |
14 |
15 | $ sudo apt install -y yang-tools
16 |
17 |
18 | Verify that `yanglint` is properly installed:
19 |
20 |
24 |
25 | ## Validate a YANG data model
26 |
27 | The simplest way of using `yanglint` is to validate the correctness of a YANG data model:
28 |
29 |
30 | $ yanglint interfaces.yang
31 |
32 |
33 | The fact that we get no output means that the YANG file was correct. In addition, the program
34 | returns status code zero, so you can do something like this:
35 |
36 |
37 | $ if yanglint interfaces.yang; then echo "All good"; else "There are errors"; fi
38 | All good
39 |
40 |
41 | Validate YANG data model `bad-interfaces.yang` to see an example of the error messages produced
42 | by `yanglint` (note hat unlike `pyang`, `yanglint` stops after the first error).
43 |
44 |
49 |
50 |
51 | ## Convert a YANG data model
52 |
53 | YANG data models tend to be very long and verbose. Yanglint can produce a summary of the YANG data
54 | model in a tree format:
55 |
56 |
66 |
67 | The command `yanglint --tree-help` displays an explanation of the symbols in the tree diagram.
68 |
69 | In addition to producing a tree summary, Yanglint can also convert the YANG data model to
70 | several other formats:
71 |
72 |
73 | $ yanglint --help
74 | Usage:
75 | yanglint [options] [-f { yang | yin | tree | tree-rfc | jsons}] <file>...
76 | Validates the YANG module in <file>, and all its dependencies.
77 |
78 | yanglint [options] [-f { xml | json }] <schema>... <file>...
79 | Validates the YANG modeled data in <file> according to the <schema>.
80 |
81 | yanglint
82 | Starts interactive mode with more features.
83 |
84 | Options:
85 | -h, --help Show this help message and exit.
86 |
87 | [...]
88 |
89 | -f FORMAT, --format=FORMAT
90 | Convert to FORMAT. Supported formats:
91 | yang, yin, tree and jsons (JSON) for schemas,
92 | xml, json for data.
93 |
94 | [...]
95 |
96 |
97 |
98 | As an example, the following example converts the YANG data model to JSON:
99 |
100 |
101 | $ yanglint -f jsons interfaces.yang
102 | {"interfaces":{"namespace":"http://remoteautonomy.com/yang-schemas/interfaces","prefix":"intf","description":{"text":"A simplistic tutorial data model for interfaces on a device."},"organization":{"text":"Remote Autonomy"},"contact":{"text":"Bruno Rijsman\u000Abrunorijsman@remoteautonomy.com"},"yang-version":{"value":"1.0"},"revision":{"2022-03-12":{"description":{"text":"Initial revision."}}},"data":{"interfaces":{"nodetype":"container"}}}}
103 |
104 |
105 | The JSON output is more readable if you pretty print it using [jq](https://manpages.ubuntu.com/manpages/bionic/man1/jq.1.html):
106 |
107 |
160 |
161 | ## Validate and convert instance data
162 |
163 | In addition to validating and converting data models, `yanglint` can also validate that instance
164 | data confirms to a given data model and convert instance data.
165 |
166 | Consider the following instance data in XML format (these are the contents of file
167 | [`yanglint/data.xml`](https://github.com/brunorijsman/yang-tutorial/blob/main/yanglint/data.xml)
168 | in the YANG tutorial repo):
169 |
170 | ```xml
171 |
172 |
173 | eth1
174 | 1.1.1.1
175 |
176 |
177 | eth2
178 | 2.2.2.2
179 |
180 |
181 | ```
182 |
183 | The following sequence of commends in `yanglint` interactive mode validates that the above
184 | instance data confirms to the `interfaces.yang` data model and converts the instance data from
185 | XML to JSON:
186 |
187 |
206 |
207 | Here the `-s` option enables strict validation, the `-t config` option indicates that we are
208 | validating configuration data, and the `-f json` option indicates that the instance data must
209 | be converted to JSON.
210 |
211 | We can also perform the instance data validation and conversion from the command-line:
212 |
213 |
230 |
231 | Now, to demonstration a validation failure,
232 | consider the following instance data in XML format (these are the contents of file
233 | [`yanglint/bad-data.xml`](https://github.com/brunorijsman/yang-tutorial/blob/main/yanglint/bad-data.xml)
234 | in the YANG tutorial repo).
235 | Note that the IPv4 address is invalid (the first byte 300 is not in the range 0-255).
236 |
237 | ```xml
238 |
239 |
240 | eth
241 | 300.1.1.1
242 |
243 |
244 | ```
245 |
246 | Validating this instance data produces the following error message:
247 |
248 |
249 | $ yanglint -s -t config yanglint/bad-data.xml -f json interfaces.yang
250 | err : Value "300.1.1.1" does not satisfy the constraint "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" (range, length, or pattern). (/interfaces:interfaces/interface[name='eth']/ipv4-address)
251 |
252 |
253 | ## References
254 |
255 | * [The yanglint manual page](https://www.mankier.com/1/yanglint)
256 |
257 | * [The libyang GitHub repository](https://github.com/CESNET/libyang)
258 |
259 |
--------------------------------------------------------------------------------
/docs/yuma-pro-client.md:
--------------------------------------------------------------------------------
1 | # YumaPro yangdump-pro from YumaWorks
2 |
3 | ## Introduction
4 |
5 | [YumaWorks](https://www.yumaworks.com/) is a company that offers a suite of network management
6 | and control plane automation tools, with a focus on YANG, NETCONF, and RESTCONF.
7 |
8 | Their product [YumaPro Client](https://www.yumaworks.com/download/yumapro-client-21-10-5-zip/)
9 | consists of three tools:
10 |
11 | 1. yangdump-pro: [TODO] Summary
12 |
13 | 2. yangdiff-pro: [TODO] Summary
14 |
15 | 3. yangcli-pro: [TODO] Summary
16 |
17 |
18 | YumaPro Client also includes an installer for YumaBench, but we discuss YumaBench separately
19 | [here](yumabench.md).
20 |
21 | The YumaPro Client software is free.
22 | The license allows you to use it
23 | "for internal use only, for the sole purpose of defining and managing networking devices
24 | on its own internal (enterprise) network."
25 | Note: I am not affiliated with YumaWorks in any way and I don't get any commission.
26 |
27 | ## Download and install
28 |
29 |
30 | You can download the YumaPro Client software from the
31 | [download page](https://www.yumaworks.com/support/download-yumapro-client/)
32 | It is available for macOS and for several Linux distributions.
33 | I evaluated version 21.10-5 for macOS.
34 |
35 | The installation procedure downloads a zip file with the following contents:
36 |
37 | ```
38 | .
39 | ├── etc
40 | │ └── yumapro
41 | │ ├── yangcli-pro-sample.conf
42 | │ ├── yangdiff-pro-sample.conf
43 | │ └── yangdump-pro-sample.conf
44 | └── usr
45 | └── local
46 | ├── bin
47 | │ ├── yangcli-pro
48 | │ ├── yangdiff-pro
49 | │ ├── yangdump-pro
50 | │ └── yumabench-mac-os-installer
51 | ├── lib
52 | │ ├── libyumapro_mgr.dylib
53 | │ ├── libyumapro_ncx.dylib
54 | │ └── libyumapro_ycli.dylib
55 | └── share
56 | ├── doc
57 | │ └── yumapro
58 | │ ├── AUTHORS
59 | │ ├── README.yumapro-client
60 | │ ├── yumapro-client-user-license.pdf
61 | │ └── yumapro-legal-notices.pdf
62 | ├── man
63 | │ └── man1
64 | │ ├── yangcli-pro.1.gz
65 | │ ├── yangdiff-pro.1.gz
66 | │ ├── yangdump-pro.1.gz
67 | │ └── yumabench-mac-os-installer.1.gz
68 | └── yumapro
69 | └── modules
70 | ├── ietf
71 | │ └── RFC
72 | │ ├── iana-crypt-hash.yang
73 | │ ├── iana-hardware.yang
74 | ... ...
75 | │ └── notifications.yang
76 | ├── mib
77 | │ ├── IANAifType-MIB.yang
78 | │ ├── IF-MIB.yang
79 | ... ...
80 | │ └── yang-smi.yang
81 | ├── netconfcentral
82 | │ ├── toaster.yang
83 | │ ├── yuma-app-common.yang
84 | ... ...
85 | │ └── yuma-xsd.yang
86 | └── yumaworks
87 | ├── example-fan.yang
88 | ├── netconfd-pro.yang
89 | ... ...
90 | └── yumaworks-yp-ha.yang
91 | ```
92 |
93 | ## Getting the executables to run
94 |
95 | The directory `usr/local/bin` in the downloaded zip file contains the executables
96 | `yangcli-pro`, `yangdiff-pro`, and `yangdump-pro`.
97 | When you try to run any of these executables for the first time, you get an error
98 | similar to the following:
99 |
100 | 
101 |
102 | When that happens, click on cancel.
103 | Then open the System Preferences app,
104 | go into the Security & Privacy tab, and click the Allow Anyway button next to the warning
105 | "yangdump-pro" was blocked from use because it is not from an identified developer.
106 | When you run the executable again, click op Open when you get the following warning:
107 |
108 | 
109 |
110 | When you click on Open, you get an error similar to the following:
111 |
112 |
113 | $ ./yangdump-pro
114 | dyld: Library not loaded: libyumapro_ncx.dylib
115 | Referenced from: /Users/brunorijsman/Downloads/yumapro-client-21.10-5/usr/local/bin/./yangdump-pro
116 | Reason: image not found
117 | [1] 31095 abort ./yangdump-pro
118 |
119 |
120 | The next attempt to run the tool complains that the shared library cannot be verified:
121 |
122 | 
123 |
124 | As before, go into System Preferences at click Allow Anyway.
125 |
126 | The next attempt to run the tool complains that it developer of the shared library cannot be
127 | verified:
128 |
129 | 
130 |
131 | Once again, click Open.
132 |
133 | Now you get the following error message:
134 |
135 |
141 |
142 | To work around this error,
143 | (1) add `usr/local/bin` to the PATH,
144 | (2) run the tool from the `usr/local/share/yumapro/modules` directory,
145 | (3) use the `--modpath=.` command line option:
146 |
147 |
165 |
166 | Here is an example output for a YANG file that contains errors:
167 |
168 |
169 | $ yangdump-pro --modpath=. ~/yang-tutorial/bad-interfaces.yang
170 |
171 | Error: Got 'organisation', Expected: module header statement
172 | bad-interfaces.yang:6.5: error(246): wrong token value
173 |
174 | Error: type 'uint46' not found
175 | bad-interfaces.yang:47.17: error(299): unknown data type
176 |
177 | *** /Users/brunorijsman/yang-tutorial/bad-interfaces.yang
178 | *** 2 Errors, 0 Warnings
179 |
180 |
181 | ## Convert a YANG file
182 |
183 | The tool `yangdump-pro` can be used to convert a YANG file to a different format.
184 |
185 | The following command converts a YANG file to HTML:
186 |
187 |
190 |
191 | This produces file `./interfaces@2022-03-12.html` which can be viewed in a browser:
192 |
193 |
194 | $ open interfaces@2022-03-12.html
195 |
196 |
197 | 
198 |
199 | Yangdump-pro can also convert a YANG file to a YIN file:
200 |
201 | ```
202 | $ yangdump-pro --modpath=. --format=yin ~/git-personal/yang-tutorial/interfaces.yang
203 |
204 | *** /Users/brunorijsman/git-personal/yang-tutorial/interfaces.yang
205 | *** 0 Errors, 0 Warnings
206 |
207 |
211 | [...]
212 |
213 |
214 |
215 |
216 | The number of IPv4 packets received over this interface
217 |
218 |
219 |
220 |
221 |
222 | ```
223 |
224 | Yangdump-pro can also generate C code (`--format=c`) and generate a schema for an SQL database
225 | (`--format=sqldb`).
226 |
227 | ## References
228 |
229 | * [The YumaWorks company homepage](https://www.yumaworks.com/)
230 |
231 | * [The YumaPro Client product page](https://www.yumaworks.com/download/yumapro-client-21-10-5-zip/)
232 |
233 | * [YumaPro yangdump-pro and yangdump-sdk manual](https://www.yumaworks.com/pub/docs/latest/html/yangdump/yumapro-yangdump-manual.xhtml)
234 |
--------------------------------------------------------------------------------
/docs/yuma-pro-sdk.md:
--------------------------------------------------------------------------------
1 | # YumaPro SDK from YumaWorks
2 |
3 | ## Introduction
4 |
5 | [YumaWorks](https://www.yumaworks.com/) is a company that offers a suite of network management
6 | and control plane automation tools, with a focus on YANG, NETCONF, and RESTCONF.
7 |
8 | Their product [YumaPro SDK](https://www.yumaworks.com/tools/multi-protocol-server/)
9 | (Software Development Kit), also referred to as the
10 | multi-protocol network management server toolkit or simply the multi-protocol server,
11 | is a network automation management platform that provides developers a framework for developing
12 | device management interfaces.
13 |
14 | YumaPro SDK consists of the following components:
15 |
16 | 
17 |
18 | YumaPro SDK is available in binary and in source code.
19 |
20 | YumaPro SDK Basic offers a subset of the
21 | YumaPro SDK features and can be used for free for internal use subject to restrictions
22 | (see the
23 | [license document](https://www.yumaworks.com/download/yumapro-sdk-basic-license/)
24 | for details):
25 |
26 | 
27 |
28 | 
29 |
30 | In this tutorial we will be using the basic version.
31 |
32 | ## Documentation
33 |
34 | The YumaPro SDK documentation is [online here](https://docs.yumaworks.com/en/latest/).
35 |
36 | ## Installation
37 |
38 | The installation steps described below are based on the YumaWorks
39 | [installation guide](https://www.yumaworks.com/pub/latest/install/yumapro-installation-guide.html)
40 | but deviate in some small details.
41 |
42 | ### Install the dependencies
43 |
44 | Install the dependencies:
45 |
46 |
58 |
59 | ### Download YumaPro SDK
60 |
61 | Download the YumaPro SDK Basic software and documentation from the
62 | [download page](https://www.yumaworks.com/support/download-yumapro-sdk-basic/)
63 | It is available for several Linux distributions; we use Ubuntu 22.04 LTS.
64 |
65 | As of 28 June 2023, this downloads file `yumapro-sdk-basic-21.10-12.u2204.amd64.deb`.
66 |
67 | ### Install YumaPro SDK
68 |
69 | Install the YumaPro SDK Basic software package:
70 |
71 |
74 |
75 | Verify that YumaPro SDK has been installed:
76 |
77 |
78 | $ /usr/sbin/netconfd-pro --version
79 |
80 | Starting netconfd-pro...
81 | Copyright (c) 2008-2012, Andy Bierman, All Rights Reserved.
82 | Copyright (c) 2012-2022, YumaWorks, Inc., All Rights Reserved.
83 |
84 | netconfd-pro version 21.10-12-1fcb
85 |
86 |
87 | ### Configure SSH
88 |
89 | Edit sshd_config, for example using `vi`:
90 |
91 |
92 | sudo vi /etc/ssh/sshd_config
93 |
94 |
95 | The installation guide instructs you to add the following lines:
96 |
97 |
98 | Port 22
99 | Port 830
100 | Subsystem netconf /usr/sbin/netconf-subsystem-pro
101 |
102 |
103 | Using the following `Subsystem` configuration instead will allow you to view the XML messages that
104 | are exchanged over the SSH system (this cannot easily be done with normal packet capture tools such
105 | as Wireshark because they cannot easily decode the encrypted SSH session):
106 |
107 |
110 |
111 | The NETCONF server will write all received XML messages to file `/tmp/netconf-rx.txt` and all
112 | sent XML messages to file `/tmp/netconf-tx.txt`.
113 |
114 | The `multitail` program is handy to monitor both files at the same time.
115 |
116 | Install `multitail`:
117 |
118 |
119 | sudo apt-get install -y multitail
120 |
121 |
122 | Monitor both files at the same time using different colors:
123 |
124 |
127 |
128 | Press `F1` to get help on the interactive keys that multitail supports. Some handy keys are `B` to
129 | scroll back and `N` to clear the window.
130 |
131 | ### Configure SSH
132 |
133 | TODO: Are we actually using a key? It seems that we are using username/password below.
134 |
135 | Use `ssh-keygen` to generate a public-private key pair (accept defaults for all prompts):
136 |
137 |
138 | $ ssh-keygen -t ed25519
139 | Generating public/private ed25519 key pair.
140 | Enter file in which to save the key (/home/ubuntu/.ssh/id_ed25519):
141 | Enter passphrase (empty for no passphrase):
142 | Enter same passphrase again:
143 | Your identification has been saved in /home/ubuntu/.ssh/id_ed25519
144 | Your public key has been saved in /home/ubuntu/.ssh/id_ed25519.pub
145 | The key fingerprint is:
146 | SHA256:e59bSBR6oP/pO+NjJwauL9S1cXQ+8pLa6vPLvLGsoD8 ubuntu@ip-172-31-28-171
147 | The key's randomart image is:
148 | +--[ED25519 256]--+
149 | | . . |
150 | | . o .. .|
151 | | . . o. o |
152 | | . oo....|
153 | | S....++ .|
154 | | ..oo.= . |
155 | | ..o..*.o |
156 | | oEo=@++ |
157 | | .o=+B%^o |
158 | +----[SHA256]-----+
159 |
160 |
161 | Restart SSH to make the keys take effect:
162 |
163 |
164 | sudo service ssh restart
165 |
166 |
167 | ## Set a password
168 |
169 | For this demo, we will be using username and password authentication.
170 |
171 | If you are using an AWS Ubuntu instance, user `ubuntu` does not have a password by default.
172 | Set a password as follows:
173 |
174 |
175 | $ sudo su -
176 | $ passwd ubuntu
177 | New password: topsecret
178 | Retype new password: topsecret
179 | passwd: password updated successfully
180 |
181 |
182 | ## Start the NETCONF server
183 |
184 | Start the `netconfd-pro` server (with maximum debug logging; use `debug` instead of `debug4` to
185 | reduce the verbosity):
186 |
187 |
188 | $ netconfd-pro --log-level=debug4 --access-control=off
189 |
190 | Starting netconfd-pro...
191 | Copyright (c) 2008-2012, Andy Bierman, All Rights Reserved.
192 | Copyright (c) 2012-2022, YumaWorks, Inc., All Rights Reserved.
193 |
194 | ...lots of output...
195 |
196 | netconfd-pro init OK, ready for sessions
197 |
198 | Running netconfd-pro server (21.10-12-1fcb)
199 |
200 | Binding to AF_LOCAL socket /tmp/ncxserver.sock
201 |
202 | agt_ncxserver: listen ncxsock fd: 3
203 |
204 |
205 | ## Start the command line interface (CLI) client
206 |
207 | In a separate Terminal window, start the `yangcli-pro` client:
208 |
209 |
210 | $ yangcli-pro
211 |
212 | yangcli-pro version 21.10-12
213 | libssh2 version 1.8.0
214 |
215 | Copyright (c) 2008-2012, Andy Bierman, All Rights Reserved.
216 | Copyright (c) 2012-2022, YumaWorks, Inc., All Rights Reserved.
217 |
218 | ...more output...
219 |
220 | parallels@localhost>
221 |
222 |
223 | ## Connect the CLI client to the NETCONF server
224 |
225 | Enter the following command in the CLI to connect to the server
226 | (use your Linux username and password, and put the password in quotes if it contains a question mark):
227 |
228 |
229 | parallels@localhost> connect server=localhost user=<username> password=<password>
230 |
231 | NETCONF 1.1 session established for parallels on localhost
232 |
233 | Client Session Id: 1
234 | Server Session Id: 4
235 |
236 | ...more output...
237 |
238 | Protocol version set to: RFC 6241 (base:1.1)
239 | Default target set to:
240 | Save operation mapped to: commit
241 | Default with-defaults behavior: explicit
242 | Additional with-defaults behavior: trim,report-all,report-all-tagged
243 | YANG library set to: 1.0 (RFC 7895)
244 | module-set-id: 4269
245 |
246 |
247 | ## View the NETCONF messages
248 |
249 | In the `multitail` window that we had started in an earlier step, we can see the NETCONF messages
250 | that are being exchanged between the NETCONF client and server.
251 |
252 | The client sends a `hello`:
253 |
254 | ```xml
255 |
256 |
257 | urn:ietf:params:netconf:base:1.0
258 | urn:ietf:params:netconf:base:1.1
259 |
260 |
261 | ```
262 |
263 | Note: throughout these examples, we have used the `xmllint` program to pretty-print the XML in
264 | the NETCONF messages. One side-effect of this is that the XML elements and attributes may appear
265 | in a different order.
266 |
267 | The server responds with a `hello`:
268 |
269 | ```xml
270 |
271 |
272 | urn:ietf:params:netconf:base:1.0
273 | urn:ietf:params:netconf:base:1.1
274 | urn:ietf:params:netconf:capability:candidate:1.0
275 | urn:ietf:params:netconf:capability:confirmed-commit:1.0
276 | urn:ietf:params:netconf:capability:confirmed-commit:1.1
277 | urn:ietf:params:netconf:capability:rollback-on-error:1.0
278 | urn:ietf:params:netconf:capability:validate:1.0
279 | urn:ietf:params:netconf:capability:validate:1.1
280 | urn:ietf:params:netconf:capability:url:1.0?scheme=file
281 | urn:ietf:params:netconf:capability:xpath:1.0
282 | urn:ietf:params:netconf:capability:notification:1.0
283 | urn:ietf:params:netconf:capability:interleave:1.0
284 | urn:ietf:params:netconf:capability:partial-lock:1.0
285 | urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=trim,report-all,report-all-tagged
286 | urn:yumaworks:params:xml:ns:netconf:config-id?id=13
287 | urn:ietf:params:xml:ns:netconf:base:1.0?module=ietf-netconf&revision=2011-06-01&features=candidate,confirmed-commit,rollback-on-error,validate,url,xpath
288 | urn:ietf:params:xml:ns:yang:iana-crypt-hash?module=iana-crypt-hash&revision=2014-08-06&features=crypt-hash-md5,crypt-hash-sha-256,crypt-hash-sha-512
289 | urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2013-07-15
290 | urn:ietf:params:xml:ns:yang:ietf-netconf-acm?module=ietf-netconf-acm&revision=2018-02-14
291 | ...
292 | http://yumaworks.com/ns/yumaworks-types?module=yumaworks-types&revision=2021-05-15
293 | urn:ietf:params:netconf:capability:yang-library:1.0?revision=2016-06-21&module-set-id=4269
294 |
295 | 5
296 |
297 | ```
298 |
299 | The client issues a `get` filtering on subtree `ietf-yang-library`
300 | to retrieve the details of the modules that the server supports
301 | (see [RFC8525](https://datatracker.ietf.org/doc/rfc8525/) for details)
302 | (output truncated):
303 |
304 | ```xml
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 | ```
313 |
314 | The server responds with the requested information (output truncated):
315 |
316 | ```xml
317 |
318 |
319 |
320 | 4269
321 |
322 | ietf-netconf
323 | 2011-06-01
324 | urn:ietf:params:xml:ns:netconf:base:1.0
325 | candidate
326 | confirmed-commit
327 | rollback-on-error
328 | validate
329 | url
330 | xpath
331 | implement
332 |
333 |
334 | iana-crypt-hash
335 | 2014-08-06
336 | http://localhost/restconf/yang/iana-crypt-hash/2014-08-06
337 | urn:ietf:params:xml:ns:yang:iana-crypt-hash
338 | crypt-hash-md5
339 | crypt-hash-sha-256
340 | crypt-hash-sha-512
341 | implement
342 |
343 |
344 | ietf-inet-types
345 | 2013-07-15
346 | http://localhost/restconf/yang/ietf-inet-types/2013-07-15
347 | urn:ietf:params:xml:ns:yang:ietf-inet-types
348 | import
349 |
350 |
351 | ietf-netconf-acm
352 | 2018-02-14
353 | http://localhost/restconf/yang/ietf-netconf-acm/2018-02-14
354 | urn:ietf:params:xml:ns:yang:ietf-netconf-acm
355 | implement
356 |
357 | ...
358 |
359 | yumaworks-types
360 | 2021-05-15
361 | http://localhost/restconf/yang/yumaworks-types/2021-05-15
362 | http://yumaworks.com/ns/yumaworks-types
363 | import
364 |
365 |
366 |
367 |
368 | ```
369 |
370 | ## Issue a command in the CLI client
371 |
372 | In the CLI client, the `show modules` command can be used to view the YANG modules that the
373 | server reports:
374 |
375 |
412 |
413 | ## Retrieve the (empty) configuration
414 |
415 | In the CLI client, issue a `get-config` command to retrieve the running configuration:
416 |
417 |
427 |
428 | In this example, there is no configuration yet (we will add some configuration below).
429 |
430 | The client sends a `get-config`:
431 |
432 | ```xml
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 | ```
441 |
442 | The server responds with the requested configuration:
443 |
444 | ```xml
445 |
446 |
447 |
448 | ```
449 |
450 | ## Retrieve a subtree of the operational state
451 |
452 | In the CLI client, issue an `sget` command to retrieve operational state for the
453 | `/netconf-state/sessions` subtree of the operational state tree (use `/` if you want to see the
454 | whole tree):
455 |
456 |
482 |
483 | The client sends a `get` with the filter for the subtree:
484 |
485 | ```xml
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 | ```
496 |
497 | The server responds with the requested operational state:
498 |
499 | ```xml
500 |
501 |
502 |
503 |
504 |
505 | 5
506 | ncm:netconf-ssh
507 | parallels
508 | 127.0.0.1
509 | 2022-09-09T15:07:13Z
510 | 2
511 | 0
512 | 0
513 | 0
514 |
515 |
516 |
517 |
518 |
519 | ```
520 |
521 | ## Retrieve the YANG schema for a module
522 |
523 | In the CLI client, issue the `get-schema` command to retrieve the YANG schema for a specific
524 | module from the server:
525 |
526 |
527 | parallels@localhost> get-schema identifier=ietf-netconf-notifications
528 |
529 | RPC Data Reply 10 for session 5 [default]:
530 |
531 | rpc-reply {
532 | data '
533 | module ietf-netconf-notifications {
534 |
535 | namespace
536 | "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications";
537 |
538 | prefix ncn;
539 |
540 | import ietf-inet-types { prefix inet; }
541 | import ietf-netconf { prefix nc; }
542 |
543 | organization
544 | "IETF NETCONF (Network Configuration Protocol) Working Group";
545 |
546 | contact
547 | "WG Web: <http://tools.ietf.org/wg/netconf/>
548 | WG List: <mailto:netconf@ietf.org>
549 |
550 | WG Chair: Bert Wijnen
551 | <mailto:bertietf@bwijnen.net>
552 |
553 | WG Chair: Mehmet Ersue
554 | <mailto:mehmet.ersue@nsn.com>
555 |
556 | Editor: Andy Bierman
557 | <mailto:andy@netconfcentral.org>";
558 |
559 | description
560 | "This module defines a YANG data model for use with the
561 | NETCONF protocol that allows the NETCONF client to
562 | receive common NETCONF base event notifications.
563 |
564 | Copyright (c) 2012 IETF Trust and the persons identified as
565 | the document authors. All rights reserved.
566 |
567 | Redistribution and use in source and binary forms, with or
568 | without modification, is permitted pursuant to, and subject
569 | to the license terms contained in, the Simplified BSD License
570 | set forth in Section 4.c of the IETF Trust's Legal Provisions
571 | Relating to IETF Documents
572 | (http://trustee.ietf.org/license-info).
573 |
574 | This version of this YANG module is part of RFC 6470; see
575 | the RFC itself for full legal notices.";
576 |
577 | revision "2012-02-06" {
578 | description
579 | "Initial version. Errata 3957 added.";
580 | reference
581 | "RFC 6470: NETCONF Base Notifications";
582 | }
583 |
584 | grouping common-session-parms {
585 | description
586 | "Common session parameters to identify a
587 | management session.";
588 |
589 | leaf username {
590 | type string;
591 | mandatory true;
592 | description
593 | "Name of the user for the session.";
594 | }
595 |
596 | leaf session-id {
597 | type nc:session-id-or-zero-type;
598 | mandatory true;
599 | description
600 | "Identifier of the session.
601 | A NETCONF session MUST be identified by a non-zero value.
602 | A non-NETCONF session MAY be identified by the value zero.";
603 | }
604 |
605 | ...
606 |
607 | leaf timeout {
608 | when
609 | "../confirm-event = 'start' or ../confirm-event = 'extend'";
610 | type uint32;
611 | units "seconds";
612 | description
613 | "The configured timeout value if the event type
614 | is 'start' or 'extend'. This value represents
615 | the approximate number of seconds from the event
616 | time when the 'timeout' event might occur.";
617 | }
618 | } // notification netconf-confirmed-commit
619 |
620 | }
621 | '
622 | }
623 |
624 |
625 | The client sends a `get-schema` for the module:
626 |
627 | ```xml
628 |
629 |
630 | ietf-netconf-notifications
631 |
632 |
633 | ```
634 |
635 | The server responds with the requested schema:
636 |
637 | ```xml
638 |
639 |
640 | module ietf-netconf-notifications {
641 |
642 | namespace
643 | "urn:ietf:params:xml:ns:yang:ietf-netconf-notifications";
644 |
645 | prefix ncn;
646 |
647 | import ietf-inet-types { prefix inet; }
648 | import ietf-netconf { prefix nc; }
649 |
650 | organization
651 | "IETF NETCONF (Network Configuration Protocol) Working Group";
652 |
653 | contact
654 | "WG Web: <http://tools.ietf.org/wg/netconf/>
655 | WG List: <mailto:netconf@ietf.org>
656 |
657 | WG Chair: Bert Wijnen
658 | <mailto:bertietf@bwijnen.net>
659 |
660 | WG Chair: Mehmet Ersue
661 | <mailto:mehmet.ersue@nsn.com>
662 |
663 | Editor: Andy Bierman
664 | <mailto:andy@netconfcentral.org>";
665 |
666 | description
667 | "This module defines a YANG data model for use with the
668 | NETCONF protocol that allows the NETCONF client to
669 | receive common NETCONF base event notifications.
670 |
671 | Copyright (c) 2012 IETF Trust and the persons identified as
672 | the document authors. All rights reserved.
673 |
674 | Redistribution and use in source and binary forms, with or
675 | without modification, is permitted pursuant to, and subject
676 | to the license terms contained in, the Simplified BSD License
677 | set forth in Section 4.c of the IETF Trust's Legal Provisions
678 | Relating to IETF Documents
679 | (http://trustee.ietf.org/license-info).
680 |
681 | This version of this YANG module is part of RFC 6470; see
682 | the RFC itself for full legal notices.";
683 |
684 | revision "2012-02-06" {
685 | description
686 | "Initial version. Errata 3957 added.";
687 | reference
688 | "RFC 6470: NETCONF Base Notifications";
689 | }
690 |
691 | grouping common-session-parms {
692 | description
693 | "Common session parameters to identify a
694 | management session.";
695 |
696 | leaf username {
697 | type string;
698 | mandatory true;
699 |
700 | description
701 | "Name of the user for the session.";
702 | }
703 |
704 | leaf session-id {
705 | type nc:session-id-or-zero-type;
706 | mandatory true;
707 | description
708 | "Identifier of the session.
709 | A NETCONF session MUST be identified by a non-zero value.
710 | A non-NETCONF session MAY be identified by the value zero.";
711 | }
712 |
713 | ...
714 |
715 | leaf timeout {
716 | when
717 | "../confirm-event = 'start' or ../confirm-event = 'extend'";
718 | type uint32;
719 | units "seconds";
720 | description
721 | "The configured timeout value if the event type
722 | is 'start' or 'extend'. This value represents
723 | the approximate number of seconds from the event
724 | time when the 'timeout' event might occur.";
725 | }
726 | } // notification netconf-confirmed-commit
727 |
728 | }
729 |
730 |
731 | ```
732 |
733 | ## Exit from the CLI client
734 |
735 | Exit from the CLI client:
736 |
737 |
738 | parallels@localhost> quit
739 |
740 |
741 | ## Adding a plugin for your own data model
742 |
743 | We will now add a plugin for our example YANG data model: [interfaces.yang](../interfaces.yang),
744 | following the instructions in the
745 | [YumaPro Developer Manual](https://www.yumaworks.com/pub/latest/dev/yumapro-dev-manual.html)
746 | .
747 |
748 | If you haven't already done so, clone the `yang-tutorial` repo:
749 |
750 |
754 |
755 | By default YumaPro SDK expects the YANG data models to be installed in `~/modules`.
756 | Copy the example YANG data model [interfaces.yang](../interfaces.yang) into `~/modules`:
757 |
758 |
763 |
764 | YumaPro SDK support a few different flavors of plugins.
765 | We will use the SIL flavor, which is dynamically linked into the NETCONF server and which uses
766 | synchronous callbacks.
767 |
768 | We will put our plugin code in the `~/plugins` directory:
769 |
770 |
796 |
797 | The files starting with `u_` (for user) can be edited to customize the behavior of the plugin.
798 | We will edit the stub C code that YumaPro SDK generated to provide values for the operational
799 | state attributes.
800 | There are many other callbacks that can be edited in the stub code, for example to do something
801 | when an interface is added or removed, when an IPv4 address is set, changed, or removed, etc.
802 | For a complete list of all the callbacks that can be customized see the
803 | [YumaPro Developers Manual](https://www.yumaworks.com/pub/latest/dev/yumapro-dev-manual.html#)
804 | .
805 | For now, we will keep it as simple as possible and only implement the callback for providing packet
806 | counter values.
807 |
808 | Edit the generated stub file `u_interfaces.c`:
809 |
810 |
811 | $ vi ~/plugins/interfaces/src/u_interfaces.c
812 |
813 |
814 | Edit function `u_intf_sent_packets_get`:
815 |
816 | ```c
817 | status_t u_intf_sent_packets_get (
818 | getcb_get2_t *get2cb,
819 | const xmlChar *k_intf_name)
820 | {
821 | ...
822 | }
823 | ```
824 |
825 | Change the following lines:
826 |
827 | ```c
828 | /* check if the requested node exists; determined by the
829 | * SIL or SIL-SA callback based on instances in the system
830 | * CHANGE node_exists TO TRUE WHEN VALUE CODE FILLED IN */
831 | boolean node_exists = FALSE;
832 |
833 | if (!node_exists) {
834 | return ERR_NCX_NO_INSTANCE;
835 | }
836 |
837 | obj_template_t *obj = GETCB_GET2_OBJ(get2cb);
838 | status_t res = NO_ERR;
839 |
840 | /* get the real value from the system somehow */
841 | uint64 v_sent_packets = 0;
842 | ```
843 |
844 | Into the following lines (to keep things as simple as possible, we return a random value for the
845 | number of sent packets counter):
846 |
847 | ```c
848 | /* check if the requested node exists; determined by the
849 | * SIL or SIL-SA callback based on instances in the system
850 | * CHANGE node_exists TO TRUE WHEN VALUE CODE FILLED IN */
851 | boolean node_exists = TRUE; // <<< Changed this line
852 |
853 | if (!node_exists) {
854 | return ERR_NCX_NO_INSTANCE;
855 | }
856 |
857 | obj_template_t *obj = GETCB_GET2_OBJ(get2cb);
858 | status_t res = NO_ERR;
859 |
860 | /* get the real value from the system somehow */
861 | uint64 v_sent_packets = rand() % 1000; // <<< Changed this line
862 | ```
863 |
864 | Make a similar change in the function `u_intf_received_packets_get`:
865 |
866 | ```c
867 | /* check if the requested node exists; determined by the
868 | * SIL or SIL-SA callback based on instances in the system
869 | * CHANGE node_exists TO TRUE WHEN VALUE CODE FILLED IN */
870 | boolean node_exists = TRUE;
871 |
872 | if (!node_exists) {
873 | return ERR_NCX_NO_INSTANCE;
874 | }
875 |
876 | obj_template_t *obj = GETCB_GET2_OBJ(get2cb);
877 | status_t res = NO_ERR;
878 |
879 | /* get the real value from the system somehow */
880 | uint64 v_received_packets = rand() % 1000;
881 | ```
882 |
883 | Save the changes.
884 |
885 | Build and install the plugin (the `make` step generates some warnings about unused parameters
886 | which you can ignore for now):
887 |
888 |
889 | $ cd interfaces
890 | $ make
891 | $ sudo make install
892 |
893 |
894 | Go back to the CLI client which we started earlier in this tutorial and issue the following
895 | command to instruct the NETCONF server to load the new YANG module:
896 |
897 |
914 |
915 | Note: instead of issuing CLI commands to load the YANG module into the server and the client, we
916 | can also start the server with a `--module` command line option:
917 |
918 |
990 |
991 |
--------------------------------------------------------------------------------
/docs/yumabench.md:
--------------------------------------------------------------------------------
1 | # YumaWorks YumaBench
2 |
3 | ## Introduction
4 |
5 | [YumaWorks](https://www.yumaworks.com/) is a company that specializes in YANG management tools.
6 |
7 | One of their products,
8 | [YumaBench](https://www.yumaworks.com/tools/yumabench/)
9 | is a
10 | NETCONF client that can connect to a NETCONF server and that offers a graphical user interface
11 | for exploring and editing the data store in the NETCONF server.
12 |
13 | ## Download and install YumaBench
14 |
15 | The
16 | [YumaBench page](https://www.yumaworks.com/tools/yumabench/)
17 | contains links to download the software and installation instructions.
18 | Additional instructions are in the
19 | [user manual](https://www.yumaworks.com/pub/docs/yumabench/yumabench-user-manual.pdf)
20 | .
21 | Downloads are available for Ubuntu/Debian, RedHat/CentOS/Fedora, and macOS.
22 | We used the Ubuntu version.
23 |
24 | ## Start a NETCONF server
25 |
26 | This YumaBench tutorial assumes that there is a NETCONF server running that YumaBench can
27 | connect to.
28 | See the
29 | [YumaPro SDK](yuma-pro-sdk.md)
30 | tutorial for instructions on how to start the YumaWorks NETCONF server and how to load
31 | our simple `interfaces.yang` example YANG module into that server.
32 |
33 | ## Start YumaBench
34 |
35 | To start YumaBench, type the command `yuma-bench` in a terminal window.
36 |
37 | The YumaBench initial startup screen looks as follows:
38 |
39 | 
40 |
41 | ## Initial setup of YumaBench
42 |
43 | We need to configure YumaBench with the device to manage (in this case the NETCONF server running
44 | locally), user credentials (a user name and password in this example, but other authentication
45 | mechanisms are supported as well), and a NETCONF session.
46 |
47 | Add a device by selecting _Devices_ from the dropdown menu and clicking on the +Add button:
48 |
49 | 
50 |
51 | Enter the device details as follows and click the Apply button:
52 |
53 | 
54 |
55 | Add a user by selecting _Users_ from the dropdown menu and clicking on the +Add button.
56 | Enter the user details and click the Apply button:
57 |
58 | 
59 |
60 | Add a session by selecting _Sessions_ from the dropdown menu and clicking on the +Add button.
61 | Enter the session details and click the Apply button:
62 |
63 | 
64 |
65 | ## Start the NETCONF session
66 |
67 | On the same screen where the session was just added, click on the Start "Start session" button.
68 | This brings up the session window:
69 |
70 | 
71 |
72 | We start in the configuration tab, and we see that we can configure event-filters, event-streams,
73 | interfaces (which is the example YANG data model used in this tutorial), nacm, and templates.
74 |
75 | Note that we did not have to configure or import any YANG modules in the YumaBench browser;
76 | instead the browser uses the NETCONF protocol to automatically discover which YANG modules
77 | the device supports and to download the corresponding YANG data models from the device.
78 | This is only possible if the device supports
79 | [RFC 7895 (YANG Library)](https://datatracker.ietf.org/doc/rfc8525/)
80 | (which the YumaPro SDK NETCONF server used
81 | in this example does).
82 |
83 | ## Add some interfaces
84 |
85 | We will now add an interface to our example interfaces YANG module.
86 |
87 | First click on interfaces in the tree to expand it.
88 | A new entry interface appears in the tree; click on this to expand it as well.
89 | The name and ipv4-address fields appear in the tree.
90 | Fill them as follows and click on the Apply button:
91 |
92 | 
93 |
94 | Note that the interface labels change from orange to black after applying the changes to
95 | indicate that the changes have been committed.
96 |
97 | Add another interface, by selecting interface and clicking the Add button.
98 | Fill in the details of the new interface and click Apply.
99 |
100 | 
101 |
102 | ## Change an interface
103 |
104 | To change one or more interface attributes, click on the attribute, and change the value.
105 | You can remove optional attributes by clicking on the attribute an then the remove button.
106 | To remove an entire interface, click on the interface tree node and then on the Remove button.
107 | Click on the Apply button to commit the changes.
108 | If you click on Cancel before committing the change, all edits are undone.
109 |
110 | ## View operational state
111 |
112 | Click on the Monitoring tab to view the operational state.
113 | Click on Refresh to retrieve the most recent operational state.
114 | Expand nodes in the tree to view the operational attributes that you are interested in, in this
115 | case the interfaces:
116 |
117 | 
118 |
119 | ## Notifications
120 |
121 | Click on the Notifications tab to see NETCONF notifications.
122 | In this example, we can see all the configuration changes that we made:
123 |
124 | 
125 |
126 |
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/interfaces.yang:
--------------------------------------------------------------------------------
1 | module interfaces {
2 |
3 | namespace "http://remoteautonomy.com/yang-schemas/interfaces";
4 | prefix intf;
5 |
6 | organization
7 | "Remote Autonomy";
8 |
9 | contact
10 | "Bruno Rijsman
11 | brunorijsman@remoteautonomy.com";
12 |
13 | description
14 | "A simplistic tutorial data model for interfaces on a device.";
15 |
16 | revision 2022-03-12 {
17 | description
18 | "Initial revision.";
19 | }
20 |
21 | container interfaces {
22 | description
23 | "Interface parameters.";
24 |
25 | list interface {
26 | key "name";
27 | description
28 | "The list of interfaces on the device.";
29 |
30 | leaf name {
31 | type string;
32 | description
33 | "The name of the interface.";
34 | }
35 |
36 | leaf ipv4-address {
37 | type string {
38 | pattern
39 | '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
40 | + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
41 | }
42 | description
43 | "The IPv4 address of the interface.";
44 | }
45 |
46 | leaf sent-packets {
47 | type uint64;
48 | config false;
49 | description
50 | "The number of IPv4 packets sent out over this interface";
51 | }
52 |
53 | leaf received-packets {
54 | type uint64;
55 | config false;
56 | description
57 | "The number of IPv4 packets received over this interface";
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/ncclient/__pycache__/netconf_server_info.cpython-39.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brunorijsman/yang-tutorial/4d3b53bb5309f056f8070f7956e02e035a9551fe/ncclient/__pycache__/netconf_server_info.cpython-39.pyc
--------------------------------------------------------------------------------
/ncclient/demo_client.py:
--------------------------------------------------------------------------------
1 | from ncclient import manager
2 |
3 | with manager.connect(host="127.0.0.1",
4 | port=830,
5 | username="parallels",
6 | password="Virtu33l?",
7 | hostkey_verify=False) as m:
8 | c = m.get_config(source='running').data_xml
9 | with open("out.xml", 'w') as f:
10 | f.write(c)
11 |
--------------------------------------------------------------------------------
/ncclient/edit_config.py:
--------------------------------------------------------------------------------
1 | from ncclient import manager
2 | import netconf_server_info
3 |
4 |
5 | with manager.connect(host=netconf_server_info.address(),
6 | port=830,
7 | username=netconf_server_info.username(),
8 | password=netconf_server_info.password(),
9 | hostkey_verify=False) as mgr:
10 |
11 | cfg_interface = """
12 |
13 |
14 |
15 | eth1
16 | 2.2.2.2
17 |
18 |
19 |
20 | """
21 | reply = mgr.edit_config(config=cfg_interface)
22 | assert reply.xpath("/rpc-reply/ok") != []
23 | reply = mgr.commit()
24 | assert reply.xpath("/rpc-reply/ok") != []
25 |
--------------------------------------------------------------------------------
/ncclient/netconf_server_info.py:
--------------------------------------------------------------------------------
1 | import psutil
2 | import os
3 |
4 |
5 | def address():
6 | address = os.getenv('NETCONF_SERVER_ADDRESS')
7 | if address is None:
8 | return '127.0.0.1'
9 | return address
10 |
11 |
12 | def username():
13 | username = os.getenv('NETCONF_SERVER_USERNAME')
14 | if username is None:
15 | return psutil.Process().username()
16 | return username
17 |
18 |
19 | def password():
20 | return os.getenv('NETCONF_SERVER_PASSWORD')
21 |
--------------------------------------------------------------------------------
/ncclient/show_capabilities.py:
--------------------------------------------------------------------------------
1 | from ncclient import manager
2 | from bs4 import BeautifulSoup
3 | import netconf_server_info
4 |
5 |
6 | with manager.connect(host=netconf_server_info.address(),
7 | port=830,
8 | username=netconf_server_info.username(),
9 | password=netconf_server_info.password(),
10 | hostkey_verify=False) as mgr:
11 | print("Client capabilities:")
12 | for capability in mgr.client_capabilities:
13 | print(f" {capability}")
14 | print("Server capabilities:")
15 | for capability in mgr.server_capabilities:
16 | print(f" {capability}")
17 |
--------------------------------------------------------------------------------
/ncclient/show_config.py:
--------------------------------------------------------------------------------
1 | from ncclient import manager
2 | from bs4 import BeautifulSoup
3 | import netconf_server_info
4 |
5 |
6 | with manager.connect(host=netconf_server_info.address(),
7 | port=830,
8 | username=netconf_server_info.username(),
9 | password=netconf_server_info.password(),
10 | hostkey_verify=False) as mgr:
11 | config_xml = mgr.get_config(source='running').data_xml
12 | print(BeautifulSoup(config_xml, 'xml').prettify())
13 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | appdirs==1.4.4
2 | bcrypt==3.2.0
3 | beautifulsoup4==4.10.0
4 | bs4==0.0.1
5 | certifi==2021.10.8
6 | cffi==1.15.0
7 | charset-normalizer==2.0.12
8 | confusable-homoglyphs==3.2.0
9 | cryptography==36.0.1
10 | decorator==5.1.1
11 | Deprecated==1.2.13
12 | Django==2.2.28
13 | django-registration==3.1.2
14 | docutils==0.16
15 | gitdb==4.0.9
16 | GitPython==3.1.27
17 | idna==3.3
18 | Jinja2==2.11.3
19 | lxml==4.8.0
20 | MarkupSafe==2.0.1
21 | ncclient==0.6.12
22 | netmiko==2.3.3
23 | networkx==1.11
24 | packaging==19.0
25 | paramiko==2.10.1
26 | pexpect==4.8.0
27 | psutil==5.9.0
28 | ptyprocess==0.7.0
29 | pyang==2.5.2
30 | pycparser==2.21
31 | PyGithub==1.55
32 | PyJWT==2.3.0
33 | PyNaCl==1.5.0
34 | pyparsing==3.0.7
35 | pyserial==3.5
36 | python-json-logger==0.1.10
37 | python-slugify==4.0.1
38 | pytz==2021.3
39 | PyYAML==6.0
40 | requests==2.27.1
41 | scp==0.14.4
42 | six==1.16.0
43 | smmap==5.0.0
44 | soupsieve==2.3.1
45 | text-unidecode==1.3
46 | textfsm==0.4.1
47 | urllib3==1.26.8
48 | whitenoise==4.1.4
49 | wrapt==1.14.0
50 | xeger==0.3.4
51 | yangsuite==2.8.7
52 | yangsuite-devices==2.9.2
53 | yangsuite-filemanager==1.8.1
54 | yangsuite-netconf==1.15.3
55 | yangsuite-yangtree==1.19.1
56 |
--------------------------------------------------------------------------------
/yanglint/bad-data.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | eth
4 | 300.1.1.1
5 |
6 |
7 |
--------------------------------------------------------------------------------
/yanglint/data.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | eth1
4 | 1.1.1.1
5 |
6 |
7 | eth2
8 | 2.2.2.2
9 |
10 |
11 |
--------------------------------------------------------------------------------