This is a quick guide for having fast access to the commands ################################################################################ # Preparation (already done): ################################################################################ $ cd ~/tfs-ctrl/hackfest $ pip install pyang $ pip install git+https://github.com/robshakir/pyangbind.git $ pip install netconf $ sudo apt-get install -y graphviz openjdk-11-jre # Download plantuml.7997.jar from http://sourceforge.net/projects/plantuml/files/plantuml.7997.jar/download cp ~/Downloads/plantuml.7997.jar ~/tfs-ctrl/hackfest/yang/plantuml.jar sudo apt-get install -y wireshark # When asked "allow non-root users to capture?" answer "yes" sudo usermod -a -G wireshark $USER ################################################################################ # YANG ################################################################################ $ cd ~/tfs-ctrl/hackfest/yang $ cat topology.yang $ pyang -f tree topology.yang $ pyang -f tree topology.yang -o topology.tree $ pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang $ pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang -o topology-sample.xml $ pyang -f uml topology.yang -o topology.uml $ java -jar plantuml.jar topology.uml PYANGBIND --------- $ export PYBINDPLUGIN=`/usr/bin/env python3 -c \ 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` $ echo $PYBINDPLUGIN $ pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py $ python3 topology.py EXERCISE: CONNECTION -------------------- $ cd ~/tfs-ctrl/hackfest/yang/connection $ export PYBINDPLUGIN=`/usr/bin/env python3 -c \ 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` $ pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py $ python3 connection.py ################################################################################ # NETCONF ################################################################################ Run server: $ cd ~/tfs-ctrl/hackfest/netconf $ python3 server_topology.py In another window, run client: $ cd ~/tfs-ctrl/hackfest/netconf $ python3 client_topology.py EXERCISE: NETCONF EDIT-CONFIG ----------------------------- Run server: $ cd ~/tfs-ctrl/hackfest/netconf/connection $ python3 server_topology_connection.py In another window, run client: $ cd ~/tfs-ctrl/hackfest/netconf/connection $ python3 client_connection.py ################################################################################ # TAPI ################################################################################ RUN TAPI SERVER: (if needed) $ pip install -r ~/tfs-ctrl/hackfest/tapi/server/requirements.txt $ cd ~/tfs-ctrl/hackfest/tapi/server $ python3 tapi_server.py RUN TAPI CLIENT (In a new window): $ cd ~/tfs-ctrl/hackfest/tapi/client $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/service-interface-point/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/service-interface-point/sip-pe1-uni1/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/owned-node-edge-point/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/node/node-pe-1/owned-node-edge-point/NEP_PE_01_UNI1/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/topology/topo-nwk/link/PE1_NNI3_PI3_NNI1/ CONNECTIONS: $ curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/ -d @cs1.json $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/ $ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connection/cs1/ $ curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/context/connectivity-service/cs1/ EXERCISE: TAPI_APP $ cd ~/tfs-ctrl/hackfest/tapi/tapi_app $ python3 tapi_app.py == GRPC $ cd ~/tfs-ctrl/hackfest/grpc COMPILE connection.proto: $ python -m grpc_tools.protoc -I=. --python_out=connection/ connection.proto RUN CREATE AND LIST CONNECTION $ cd ~/tfs-ctrl/hackfest/grpc/connection $ python3 create.py connection.txt $ python3 list.py connection.txt COMPILE connectionService.proto $ python -m grpc_tools.protoc -I=. --python_out=connectionService/ --grpc_python_out=connectionService/ connectionService.proto RUN SERVER $ cd ~/tfs-ctrl/hackfest/grpc/connectionService $ python3 connectionService_server.py RUN CLIENT (in another window) $ cd ~/tfs-ctrl/hackfest/grpc/connectionService $ python3 connectionService_client.py ### EXERCISE COMPILE connectionServiceWithNotif.proto $ cd ~/tfs-ctrl/hackfest/grpc/ $ python -m grpc_tools.protoc -I=. --python_out=connectionServiceWithNotif/ --grpc_python_out=connectionServiceWithNotif/ connectionServiceWithNotif.proto RUN SERVER $ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif $ python3 connectionServiceWithNotif_server.py RUN CLIENT (in another window) $ cd ~/tfs-ctrl/hackfest/grpc/connectionServiceWithNotif $ python3 connectionServiceWithNotif_client.py == GNMI $ cd /usr/share/gocode/src/ $ export GOPATH=/usr/share/gocode/ $ go run github.com/openconfig/ygot/generator/generator.go -generate_fakeroot -output_file github.com/google/gnxi/gnmi/modeldata/gostruct/generated.go -package_name gostruct github.com/rvilalta/OFC_SC472/yang/topology.yang $ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_target $ go run gnmi_target.go -bind_address :10161 -config ~/tfs-ctrl/hackfest/gnmi/topology.json --notls -alsologtostderr RUN CLIENT (in another window) $ export GOPATH=/usr/share/gocode/ $ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_get $ go run gnmi_get.go -notls -xpath "/topology/" -target_addr localhost:10161 -alsologtostderr $ go run gnmi_get.go -notls -xpath "/topology/node[node-id=A]" -target_addr localhost:10161 -alsologtostderr USE PYTHON CLIENT $ cd /usr/share/gocode/src/github.com/google/gnxi/gnmi_cli_py $ python py_gnmicli.py -n -m get -t localhost -p 10161 -x /topology -u foo -pass bar == KAFKA $ cd ~/tfs-ctrl/hackfest/kafka (INSTALL) $ pip3 install kafka-python $ wget https://ftp.cixug.es/apache/kafka/2.8.0/kafka_2.13-2.8.0.tgz $ tar -xzf kafka_2.13-2.8.0.tgz (RUN) $ cd kafka_2.13-2.8.0 $ bin/zookeeper-server-start.sh config/zookeeper.properties (In new window) $ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0 $ bin/kafka-server-start.sh config/server.properties CREATE TOPIC (In new window) $ cd ~/tfs-ctrl/hackfest/kafka/kafka_2.13-2.8.0 $ bin/kafka-topics.sh --create --topic my-topic --bootstrap-server localhost:9092 (In new window) $ cd ~/tfs-ctrl/hackfest/kafka $ python3 sub.py (In new window) $ cd ~/tfs-ctrl/hackfest/kafka $ python3 pub.py == APPENDIX: CONFD $ cd ~/tfs-ctrl/hackfest/netconf $ unzip confd-basic-6.4.linux.x86_64.zip $ cd confd-basic-6.4.linux.x86_64/ $ ./confd-basic-6.4.linux.x86_64.installer.bin /root/confd/ Data model compilation $ cd /root/confd/bin/ $ ./confdc -c ~/tfs-ctrl/hackfest/yang/topology.yang Start ConfD $ ./confd --foreground -v --addloadpath . In another terminal, use ConfD-client to populate model $ cd /root/confd/bin/ $ ./confd_cli > conf > topology node node1 > exit > commit > exit > exit Use ConfD-client to show db $ ./confd_cli > conf > show full-configuration > exit > exit == RUN ONOS $ cd /root/onos-2.1.0/apache-karaf-4.2.3/bin/ $ ./karaf clean > app activate org.onosproject.openflow > app activate org.onosproject.gui In another terminal, run mininet: $ mn --topo linear,3 --mac --controller=remote,ip=127.0.0.1,port=6653 --switch ovs,protocols=OpenFlow13 In another terminal, we use ONOS REST API: $ curl -X GET -u onos:rocks --header 'Accept: application/json' http://localhost:8181/onos/v1/links | python -m json.tool $ cd ~/tfs-ctrl/hackfest/onos_api/ $ python3 onos_topology.py ################################################################################ # OTHER MATERIAL ################################################################################ == RESTCONF === YANG2SWAGGER $ cd ~/tfs-ctrl/hackfest/restconf (if needed) $ wget https://github.com/bartoszm/yang2swagger/releases/download/1.1.11/swagger-generator-cli-1.1.11-executable.jar Generate swagger files: $ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output topology.yaml topology $ java -jar swagger-generator-cli-1.1.11-executable.jar -yang-dir ../yang/ -output connection.yaml connection === SERVER $ cd ~/tfs-ctrl/hackfest/restconf (if needed) $ wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.11/swagger-codegen-cli-3.0.11.jar -O swagger-codegen-cli.jar Create the server: $ mkdir ~/tfs-ctrl/hackfest/restconf/server $ java -jar swagger-codegen-cli.jar generate -i connection.yaml -l python-flask -o server Run the server: $ cd ~/tfs-ctrl/hackfest/restconf/server $ pip3 install -r requirements.txt (Open ~/tfs-ctrl/hackfest/restconf/server/swagger_server/swagger/swagger.yaml and modify all: "name: connection_id" for "name: connection-id") RUN AUTOGENERATED SERVER $ python3 -m swagger_server (you have the solution in ~/tfs-ctrl/hackfest/restconf/connectionserver ) RUN CURL AS CLIENT (In another window) $ cd ~/tfs-ctrl/hackfest/restconf/ $ curl -X POST -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection/ -d@conn1.json $ curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/ $ curl -X DELETE -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/connection=0/ === Exercise: RESTCONF TOPOLOGY === $ mkdir ~/tfs-ctrl/hackfest/restconf/topologyserver $ java -jar swagger-codegen-cli.jar generate -i topology.yaml -l python-flask -o topologyserver $ cd ~/tfs-ctrl/hackfest/restconf/topologyserver (Open ~/tfs-ctrl/hackfest/restconf/topologyserver/swagger_server/swagger/swagger.yaml and modify all: "name: link_id" for "name: link-id", same for node and port) $ python3 -m swagger_server RUN CURL AS CLIENT (In another window) $curl -X GET -H "Content-Type: application/yang-data+json" http://127.0.0.1:8080/data/topology/