How can I load data into CDB operational to test my YANG config false part?

As you could read in this excellent post - you can use CDB for storing operational data - e.g. stats, monitor data, etc. But how can I test my CDB oper data implementation before I have a program that push data into the CDB operational data store? Let’s take a common scenario as an example using the $CONFD_DIR/examples.confd/cdb_oper/ifstatus to illustrate.

Say I have finished my YANG module and want to test out my “config false” part. In the ifstatus if.yang example that would be this part:

container status {
  config false;
  tailf:cdb-oper;

  container receive {
...

I of course could just set config false to true, but that would not cause the same behaviour as if the data was stored in the running/candidate/startup datastore(s) instead of the operational datastore, and ConfD would treat the data a bit different.

And what if I have finished my project, but don’t yet have the HW to test with?
Or as in this case, I want to run the example in my MacOS instead of Linux?
Let’s try to do that. First we edit the ifstats example Makefile to remove the Linux check and the ifstatus.c program:

$ pwd
/Users/conny/tailf/confd-basic-6.0/examples.confd/cdb_oper/ifstatus
$ diff -u Makefile.bak Makefile
--- Makefile.bak	2015-08-22 22:06:31.000000000 +0200
+++ Makefile	2015-08-22 22:40:46.000000000 +0200
@@ -39,7 +39,8 @@
 OBJS	= $(SRC:.c=.o)
 LIBS	+= -lcrypto
 
-all:	linux if.fxs $(PROG) $(CDB_DIR) $(CDB_DIR)/if_init.xml ssh-keydir
+#all:	linux if.fxs $(PROG) $(CDB_DIR) $(CDB_DIR)/if_init.xml ssh-keydir
+all:    if.fxs $(CDB_DIR) $(CDB_DIR)/if_init.xml ssh-keydir
 	@echo "Build complete"
 
 $(PROG): $(OBJS)
@@ -64,7 +65,7 @@
 	$(CONFD) -c confd.conf $(CONFD_FLAGS)
 	### In another terminal window, start the CLI (make cli)
 	### Starting the ifstatus agent
-	./$(PROG) $(START_FLAGS)
+	#./$(PROG) $(START_FLAGS)
 
 ######################################################################
 stop:
$ make clean all start
...
### Start the confd daemon with our example specific confd-config'
/Users/conny/tailf/releases/confd-basic-6.0.darwin.x86_64/../../confd-basic-6.0/bin/confd -c confd.conf --addloadpath /Users/conny/tailf/releases/confd-basic-6.0.darwin.x86_64/../../confd-basic-6.0/etc/confd 
...
$ make cli
...
# show interfaces
NAME  BYTES  PACKETS  ERRORS  DROPPED  BYTES  PACKETS  ERRORS  DROPPED  COLLISIONS 
------------------------------------------------------------------------------------
lo    -      -        -       -        -      -        -       -        -           

No interface stats without the ifstatus.c program as expected…
Now let’s use the nifty confd_load tool to load some example data into CDB oper through the CDB API. But first we need some dummy data. One simple way of getting data into for example an XML file is to first set config false to true, and here also comment out the mandatory checks. What we want to do is to quickly create an xml file with some made up data:

$ cp if.yang if.yang.bak
...
$ diff if.yang.bak if.yang
32,33c32,33
<         config false;
<         tailf:cdb-oper;
---
>         config true;
> //        tailf:cdb-oper;
38c38
<             mandatory true;
---
> //            mandatory true;
42c42
<             mandatory true;
---
> //            mandatory true;
46c46
<             mandatory true;
---
> //            mandatory true;
50c50
<             mandatory true;
---
> //            mandatory true;
56c56
<             mandatory true;
---
> //            mandatory true;
60c60
<             mandatory true;
---
> //            mandatory true;
64c64
<             mandatory true;
---
> //            mandatory true;
68c68
<             mandatory true;
---
> //            mandatory true;
72c72
<             mandatory true;
---
> //            mandatory true;
$ make clean all start
...
$ make cli
...
# config
(config)# interfaces interface lo status receive bytes 424242 dropped 42 errors 2 packets 4242
(config-interface-lo)# status transmit bytes 123456 dropped 12 errors 1 packets 1234 collisions 2
(config-interface-lo)# commit
(config-interface-lo)# exit
(config)# show full-configuration interfaces interface lo status
interfaces interface lo
 status receive bytes 424242
 status receive packets 4242
 status receive errors 2
 status receive dropped 42
 status transmit bytes 123456
 status transmit packets 1234
 status transmit errors 1
 status transmit dropped 12
 status transmit collisions 2
!
(config)# exit
# file show ifoper_init.xml
<config xmlns="http://tail-f.com/ns/config/1.0">
  <interfaces xmlns="http://tail-f.com/ns/example/if">
  <interface>
    <name>lo</name>
      <status>
        <receive>
          <bytes>424242</bytes>
          <packets>4242</packets>
          <errors>2</errors>
          <dropped>42</dropped>
        </receive>
        <transmit>
          <bytes>123456</bytes>
          <packets>1234</packets>
          <errors>1</errors>
          <dropped>12</dropped>
          <collisions>2</collisions>
        </transmit>
      </status>
  </interface>
  </interfaces>
</config>
# exit
$ mv if.yang.bak if.yang
$ make clean all start
...
/Users/conny/tailf/releases/confd-basic-6.0.darwin.x86_64/../../confd-basic-6.0/bin/confd -c confd.conf --addloadpath /Users/conny/tailf/releases/confd-basic-6.0.darwin.x86_64/../../confd-basic-6.0/etc/confd 
...

So now ConfD is up and running with the original if.yang where the if status is in the CDB operational datastore again. To load the xml init file we created we just use the confd_load tool that comes with ConfD in binary and source:

$ confd_load -C ifoper_init.xml
$ make cli
...
# show interfaces
NAME  BYTES   PACKETS  ERRORS  DROPPED  BYTES   PACKETS  ERRORS  DROPPED  COLLISIONS 
--------------------------------------------------------------------------------------
lo    424242  4242     2       42       123456  1234     1       12       2          

There you go, long story short - use confd_load with the -C flag :slight_smile:

Or you just use the “confd_cmd” tool that also comes with ConfD in binary and source:

$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/receive/bytes 424242"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/receive/packets 4242"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/receive/errors 2"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/receive/dropped 42"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/transmit/bytes 123456"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/transmit/packets 1234"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/transmit/errors 1"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/transmit/dropped 12"
$ confd_cmd -o -f rw -c "cdb_set /interfaces/interface{lo}/status/transmit/collisions 2"
$ make cli
...
# show interfaces
NAME  BYTES   PACKETS  ERRORS  DROPPED  BYTES   PACKETS  ERRORS  DROPPED  COLLISIONS  
--------------------------------------------------------------------------------------
lo    424242  4242     2       42       123456  1234     1       12       2