diff --git a/hackfest/commands.txt b/hackfest/commands.txt index dbc72991b251ed9b54c42b627e9d1399884f7075..c34c6acc112e3d5dee47752967b60bab32556c94 100644 --- a/hackfest/commands.txt +++ b/hackfest/commands.txt @@ -1,21 +1,31 @@ -This is a quick guide for having fast access to the commands - - +This is a quick guide for having fast access to the commands. ################################################################################ -# Preparation (already done): +# Prepare environment ################################################################################ -$ 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 +# (done) Create PyEnv virtual environment +cd ~/tfs-ctrl +pyenv virtualenv 3.9.13 tfs +pyenv local 3.9.13/envs/tfs +./install_requirements.sh + +# (done) Install Python dependencies +pip install pyang +pip install git+https://github.com/robshakir/pyangbind.git +pip install netconf + +# (done) Install PlantUML +# (done) Install dependencies to run PlantUML +sudo apt-get install -y graphviz openjdk-11-jre + +# (done) 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 +# (done) Install WireShark # When asked "allow non-root users to capture?" answer "yes" +sudo apt-get install -y wireshark +# Add current user to wireshark group to allow capturing as non-root (requires log-out & log-in, or reboot) sudo usermod -a -G wireshark $USER @@ -24,34 +34,48 @@ 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 +## GUIDED + +# Convert Topology YANG to Text-based tree +pyang -f tree topology.yang +pyang -f tree topology.yang -o topology.tree +# Report a sample message following Topology YANG data model +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 +# Convert Topology YANG to UML +pyang -f uml topology.yang -o topology.uml +java -jar plantuml.jar topology.uml -PYANGBIND ---------- -$ export PYBINDPLUGIN=`/usr/bin/env python3 -c \ +# Convert Topology YANG to Python bindings +export PYBINDPLUGIN=`/usr/bin/env python -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 +echo $PYBINDPLUGIN +pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py +# Test creation of JSON-/XML-encoded Topology messages +python topology.py +## EXERCISE -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 +# Convert Connection YANG to Text-based tree +pyang -f tree connection.yang + +# Report a sample message following Connection YANG data model +pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations connection.yang + +# Convert Connection YANG to UML +pyang -f uml connection.yang -o connection.uml +java -jar plantuml.jar connection.uml + +# Convert Connection YANG to Python bindings +export PYBINDPLUGIN=`/usr/bin/env python -c \ + 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` +pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py + +# Test creation of JSON-/XML-encoded Connection messages +python connection.py @@ -59,25 +83,25 @@ $ python3 connection.py # NETCONF ################################################################################ +## GUIDED + Run server: -$ cd ~/tfs-ctrl/hackfest/netconf -$ python3 server_topology.py +cd ~/tfs-ctrl/hackfest/netconf +python3 server_topology.py In another window, run client: -$ cd ~/tfs-ctrl/hackfest/netconf -$ python3 client_topology.py - +cd ~/tfs-ctrl/hackfest/netconf +python3 client_topology.py +## EXERCISE -EXERCISE: NETCONF EDIT-CONFIG ------------------------------ Run server: -$ cd ~/tfs-ctrl/hackfest/netconf/connection -$ python3 server_topology_connection.py +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 +cd ~/tfs-ctrl/hackfest/netconf/connection +python3 client_connection.py @@ -85,213 +109,158 @@ $ 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): +## GUIDED + +# (done) Install dependencies +cd ~/tfs-ctrl/hackfest/tapi/server +pip install -r requirements.txt + +# (done) Build & Implement methods for the TAPI v2.1.3 server: +cd ~/tfs-ctrl/hackfest/tapi +wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar +wget -O tapi-connectivity.yaml https://github.com/OpenNetworkingFoundation/TAPI/raw/v2.1.3/OAS/tapi-connectivity%402020-06-16.yaml +java -jar swagger-codegen-cli-3.0.35.jar generate --input-spec tapi-connectivity.yaml \ + --lang python-flask --output server --disable-examples --config codegen-config.json +pip install connexion==2.14.1 +cd ~/tfs-ctrl/hackfest/tapi/server +# Rename methods in "tapi_server/controllers/tapi_path_computation_controller.py" as follows: +# operations_tapi_path_computationcompute_p2_p_path_post => operations_tapi_path_computationcompute_p_2_p_path_post +# operations_tapi_path_computationdelete_p2_p_path_post => operations_tapi_path_computationdelete_p_2_p_path_post +# operations_tapi_path_computationoptimize_p2_ppath_post => operations_tapi_path_computationoptimize_p_2_ppath_post +# Implement database based on Reference Implementation [Ref-3] in tapi/server/Acknowledgements.txt + +# Run the TAPI server: +cd ~/tfs-ctrl/hackfest/tapi/server +python3 -m tapi_server 8080 database/mini-ols-context.json + +# Run TAPI client using cURL (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 + +# Interrogate Context and SIPs: +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/service-interface-point=node-4-port-16-output/ + +# Interrogate Topology, Nodes and Links: +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/link=link-4:2-2:4/ + +# Create ConnectivityServices and Connections: +curl -X POST -H "Content-Type: application/json" \ + http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service/ \ + -d @/home/tfs/tfs-ctrl/hackfest/tapi/client/cs1.json + +# Interrogate ConnectivityServices and Connections: +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/ +curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connection=cs1/ + +# Delete ConnectivityServices and Connections: +curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/ + + +## EXERCISE +# Exercise: retrieve and draw the topology +# solution in folder tapi_app + +cd ~/tfs-ctrl/hackfest/tapi/tapi_app +python3 tapi_app.py + + + +################################################################################ +# Deploy TeraFlowSDN +################################################################################ + +# Check status of Kubernetes +microk8s.status --wait-ready + +# Check all resources in Kubernetes +microk8s.kubectl get all --all-namespaces + +# Deploy TeraFlowSDN +cd ~/tfs-ctrl +source my_deploy.sh +./deploy.sh + +# Show status of your deployment +(if new terminal) cd ~/tfs-ctrl && source my_deploy.sh +./show_deploy.sh + +# Show logs of a specific component +(if new terminal) cd ~/tfs-ctrl && source my_deploy.sh +scripts/show_logs_device.sh + ################################################################################ -# OTHER MATERIAL +# Programmable L3 routers ################################################################################ -== RESTCONF +# (done) Build a Netconf server supporting basic OpenConfig data model + +# Start the Netconf/OpenConfig server +cd ~/tfs-ctrl/hackfest/netconf-oc +python3 server_openconfig.py 8300 + + + +################################################################################ +# Service requests +################################################################################ + +## L3VPN service from JSON descriptors + +# (in a new terminal) Start OLS TAPI server: +cd ~/tfs-ctrl/hackfest/tapi/server +python3 -m tapi_server 8080 database/mini-ols-context.json + +# (in a new terminal) Start the Netconf/OpenConfig server for R1 +cd ~/tfs-ctrl/hackfest/netconf-oc +python3 server_openconfig.py 8301 + +# (in a new terminal) Start the Netconf/OpenConfig server for R2 +cd ~/tfs-ctrl/hackfest/netconf-oc +python3 server_openconfig.py 8302 -=== YANG2SWAGGER +# (in a new terminal) Start the Netconf/OpenConfig server for R3 +cd ~/tfs-ctrl/hackfest/netconf-oc +python3 server_openconfig.py 8303 -$ 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 +# (in a new terminal) Start the Netconf/OpenConfig server for R4 +cd ~/tfs-ctrl/hackfest/netconf-oc +python3 server_openconfig.py 8304 -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 +############ +# Mock OSM +############ -=== 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 +$ cd ~/tfs-ctrl/hackfest/ +$ python -m mock_osm +Welcome to the MockOSM shell. +Type help or ? to list commands. -Create the server: -$ mkdir ~/tfs-ctrl/hackfest/restconf/server -$ java -jar swagger-codegen-cli.jar generate -i connection.yaml -l python-flask -o server +(mock-osm) create +Service b8c99e2c-39d8-424d-9833-554634269555 created +# Service should be created in TFS. Check "Slice" and "Service" pages on WebUI. +# Check configuration rules in "Devices" -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 +(mock-osm) status +response.status_code=200 +Status of Service b8c99e2c-39d8-424d-9833-554634269555 is {'sdn_status': 'ACTIVE'} -(you have the solution in ~/tfs-ctrl/hackfest/restconf/connectionserver ) +(mock-osm) delete +Service b8c99e2c-39d8-424d-9833-554634269555 deleted +# Service should be removed from TFS. Check "Slice" and "Service" pages on WebUI. +# Check configuration rules in "Devices" -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/ +(mock-osm) exit +Bye! -=== 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/ diff --git a/hackfest/gnmi/commands.txt b/hackfest/gnmi/commands.txt new file mode 100644 index 0000000000000000000000000000000000000000..6fae7f9a8fc8b9b69d364b1d279aca80759c90ef --- /dev/null +++ b/hackfest/gnmi/commands.txt @@ -0,0 +1,17 @@ +== 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 + diff --git a/hackfest/grpc/commands.txt b/hackfest/grpc/commands.txt new file mode 100644 index 0000000000000000000000000000000000000000..e0148b180c03841098781563976467d980abc464 --- /dev/null +++ b/hackfest/grpc/commands.txt @@ -0,0 +1,36 @@ +== 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 + + diff --git a/hackfest/kafka/commands.txt b/hackfest/kafka/commands.txt new file mode 100644 index 0000000000000000000000000000000000000000..f29d6020b5fa044b1d60020b30075c763161f31f --- /dev/null +++ b/hackfest/kafka/commands.txt @@ -0,0 +1,27 @@ +== 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 + diff --git a/hackfest/netconf-oc/_commands.md b/hackfest/netconf-oc/_commands.md deleted file mode 100644 index c8f1cff029b2ad992471aa350fc48aafbe88f9d6..0000000000000000000000000000000000000000 --- a/hackfest/netconf-oc/_commands.md +++ /dev/null @@ -1,82 +0,0 @@ -# NETCONF TFS exercise - -## 1. Interrogate Topology - -```bash -# Configure basic NetConf/OpenConfig server - -mkdir -p ~/yang-netconf/netconf-tfs/{git_openconfig,openconfig} -git clone https://github.com/openconfig/public.git ~/yang-netconf/netconf-tfs/git_openconfig - -cd ~/yang-netconf/netconf-tfs - -export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` -pyang --plugindir $PYBINDPLUGIN -p git_openconfig/release/models/ -f pybind --split-class-dir openconfig \ - git_openconfig/release/models/interfaces/openconfig-interfaces.yang \ - git_openconfig/release/models/interfaces/openconfig-if-ethernet.yang \ - git_openconfig/release/models/platform/openconfig-platform.yang \ - git_openconfig/release/models/platform/openconfig-platform-port.yang - -python3 serverOpenConfig.py - -# Terminal 2 (client) -cd ~/yang-netconf/netconf -python3 clientTopology.py -``` - -### 2.2. Report a sample message following Topology YANG data model -```bash -mkdir -p sample-xml-skeleton -pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations topology.yang -o sample-xml-skeleton/topology.xml -``` - -### 2.3. Convert Topology YANG to UML -```bash -mkdir -p uml -pyang -f uml topology.yang -o uml/topology.uml -java -jar plantuml.jar uml/topology.uml -``` - -### 2.4. Convert Topology YANG to Python bindings -```bash -export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` -pyang -f pybind topology.yang --plugindir $PYBINDPLUGIN -o binding_topology.py -``` - -### 2.5. Test creation of JSON-/XML-encoded Topology messages -```bash -python topology.py -``` - - -## 3. Connection YANG data model (exercise solution) - -### 3.1. Convert Connection YANG to Text-based tree -```bash -mkdir -p tree -pyang -f tree connection.yang -o tree/connection.txt -``` - -### 3.2. Report a sample message following Connection YANG data model -```bash -mkdir -p sample-xml-skeleton -pyang -f sample-xml-skeleton --sample-xml-skeleton-annotations connection.yang -o sample-xml-skeleton/connection.xml -``` - -### 3.3. Convert Connection YANG to UML -```bash -mkdir -p uml -pyang -f uml connection.yang -o uml/connection.uml -java -jar plantuml.jar uml/connection.uml -``` - -### 3.4. Convert Connection YANG to Python bindings -```bash -export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` -pyang -f pybind connection.yang --plugindir $PYBINDPLUGIN -o binding_connection.py -``` - -### 3.5. Test creation of JSON-/XML-encoded Connection messages -```bash -python topology.py -``` diff --git a/hackfest/netconf-oc/build-instructions.txt b/hackfest/netconf-oc/build-instructions.txt new file mode 100644 index 0000000000000000000000000000000000000000..c485bc006d25244d170f6c515ea985d7cec6d75b --- /dev/null +++ b/hackfest/netconf-oc/build-instructions.txt @@ -0,0 +1,14 @@ +# Build a Netconf server supporting basic OpenConfig data model + +mkdir -p ~/tfs-ctrl/netconf-oc/{git_openconfig,openconfig} + +git clone https://github.com/openconfig/public.git ~/tfs-ctrl/netconf-oc/git_openconfig + +cd ~/tfs-ctrl/netconf-oc + +export PYBINDPLUGIN=`/usr/bin/env python -c 'import pyangbind; import os; print ("{}/plugin".format(os.path.dirname(pyangbind.__file__)))'` +pyang --plugindir $PYBINDPLUGIN -p git_openconfig/release/models/ -f pybind --split-class-dir openconfig \ + git_openconfig/release/models/interfaces/openconfig-interfaces.yang \ + git_openconfig/release/models/interfaces/openconfig-if-ethernet.yang \ + git_openconfig/release/models/platform/openconfig-platform.yang \ + git_openconfig/release/models/platform/openconfig-platform-port.yang diff --git a/hackfest/netconf/connection/topology.xml b/hackfest/netconf/connection/topology.xml index 64f95dd7b1b8531937468f3500bde0b63e3b606a..93af480850b540669f133a76b12519f5554b8850 100644 --- a/hackfest/netconf/connection/topology.xml +++ b/hackfest/netconf/connection/topology.xml @@ -21,5 +21,3 @@ </link> </topology> </topology> - - diff --git a/hackfest/netconf/topology.xml b/hackfest/netconf/topology.xml index 64f95dd7b1b8531937468f3500bde0b63e3b606a..93af480850b540669f133a76b12519f5554b8850 100644 --- a/hackfest/netconf/topology.xml +++ b/hackfest/netconf/topology.xml @@ -21,5 +21,3 @@ </link> </topology> </topology> - - diff --git a/hackfest/onos_api/commands.txt b/hackfest/onos_api/commands.txt new file mode 100644 index 0000000000000000000000000000000000000000..cac0169e63fac4b16bee718ab0720e2589ffb103 --- /dev/null +++ b/hackfest/onos_api/commands.txt @@ -0,0 +1,45 @@ +== 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 + + diff --git a/hackfest/restconf/commands.txt b/hackfest/restconf/commands.txt new file mode 100644 index 0000000000000000000000000000000000000000..2eac80cf60d58675981983c722bb7d2fdcbd84bf --- /dev/null +++ b/hackfest/restconf/commands.txt @@ -0,0 +1,48 @@ +== 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/ diff --git a/hackfest/tapi/commands.txt b/hackfest/tapi/commands.txt deleted file mode 100644 index 4861aeecd372837510c359cf2563cdc20e3c01f5..0000000000000000000000000000000000000000 --- a/hackfest/tapi/commands.txt +++ /dev/null @@ -1,52 +0,0 @@ -# Commands to build TAPI v2.1.3 Server: - -# Acknowledgements and References: -# [Ref-1]: https://github.com/OpenNetworkingFoundation/TAPI -# [Ref-2]: https://github.com/OpenNetworkingFoundation/TAPI/tree/v2.1.3/YANG -# [Ref-3]: https://github.com/OpenNetworkingFoundation/TAPI/tree/develop/RI - -cd ~/tfs-ctrl/hackfest/tapi -wget https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.35/swagger-codegen-cli-3.0.35.jar -wget -O tapi-connectivity.yaml https://github.com/OpenNetworkingFoundation/TAPI/raw/v2.1.3/OAS/tapi-connectivity%402020-06-16.yaml -java -jar swagger-codegen-cli-3.0.35.jar generate --input-spec tapi-connectivity.yaml \ - --lang python-flask --output server --disable-examples --config codegen-config.json -pip install connexion==2.14.1 -cd ~/tfs-ctrl/hackfest/tapi/server -# Rename methods in "tapi_server/controllers/tapi_path_computation_controller.py" as follows: -# operations_tapi_path_computationcompute_p2_p_path_post => operations_tapi_path_computationcompute_p_2_p_path_post -# operations_tapi_path_computationdelete_p2_p_path_post => operations_tapi_path_computationdelete_p_2_p_path_post -# operations_tapi_path_computationoptimize_p2_ppath_post => operations_tapi_path_computationoptimize_p_2_ppath_post -# Implement database based on Reference Implementation [Ref-3] -python3 -m tapi_server - -RUN TAPI CLIENT (In a new window): -# Context: -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/service-interface-point=node-4-port-16-output/ - -# Topology: -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/link=link-4:2-2:4/ - -# Connection: -curl -X POST -H "Content-Type: application/json" \ - http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service/ \ - -d @/home/tfs/tfs-ctrl/hackfest/tapi/client/cs1.json - -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/ -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connection=cs1/ - -curl -X DELETE -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-connectivity:connectivity-context/connectivity-service=cs1/ - - -# Exercise: retrieve and draw the topology -solution in folder tapi_app - - -Not testable since there is no path computation -curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8080/restconf/data/tapi-common:context/tapi-topology:topology-context/topology=ols-topo/node=node-odu-pi-4/owned-node-edge-point=node-4-port-13/tapi-connectivity:cep-list/connection-end-point={cep-uuid}/ diff --git a/hackfest/tapi/server/Acknowledgements.txt b/hackfest/tapi/server/Acknowledgements.txt new file mode 100644 index 0000000000000000000000000000000000000000..288a31e12df8aef0f2c8098c64a2f48b9fc11faf --- /dev/null +++ b/hackfest/tapi/server/Acknowledgements.txt @@ -0,0 +1,3 @@ +# [Ref-1]: https://github.com/OpenNetworkingFoundation/TAPI +# [Ref-2]: https://github.com/OpenNetworkingFoundation/TAPI/tree/v2.1.3/YANG +# [Ref-3]: https://github.com/OpenNetworkingFoundation/TAPI/tree/develop/RI diff --git a/hackfest/tapi/server/tapi_server/database/mini-ols-context.json b/hackfest/tapi/server/tapi_server/database/mini-ols-context.json index 6bfe9e402eb688874aae14caaf2bd1f256469657..59a4fb7cfb54df9a101ac5eda848f36553791704 100644 --- a/hackfest/tapi/server/tapi_server/database/mini-ols-context.json +++ b/hackfest/tapi/server/tapi_server/database/mini-ols-context.json @@ -308,7 +308,7 @@ ], "topology-context": { "nw-topology-service": { - "uuid": "ols-topo", + "uuid": "ols-ctx", "topology": [{"topology-uuid": "ols-topo"}] }, "topology": [ diff --git a/hackfest/tapi/tapi_app/tapi_app.py b/hackfest/tapi/tapi_app/tapi_app.py index 08d6facf4ab55be932e78003fdafe8336ced3bcf..195306c7b1e0f586f03b1c625846550a2cc06c57 100644 --- a/hackfest/tapi/tapi_app/tapi_app.py +++ b/hackfest/tapi/tapi_app/tapi_app.py @@ -1,55 +1,51 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -import requests +import json, requests, networkx as nx from requests.auth import HTTPBasicAuth -import json -import networkx as nx IP = '127.0.0.1' PORT = 8080 -USER = '' -PASS = '' TOPO_UUID = 'ols-topo' +TOPO_URL = 'http://{:s}:{:d}/restconf/data/tapi-common:context/'\ + 'tapi-topology:topology-context/topology={:s}/' -TOPO_LIST_URL = 'http://{:s}:{:d}/restconf/data/tapi-common:context/tapi-topology:topology-context/topology={:s}/' - -def retrieveTopology(ip, port, user, password, topo_uuid): +def retrieve_topology(ip, port, topo_uuid, user='', passwd=''): print ("Reading network-topology") - topologies = [] - topo_list_url = TOPO_LIST_URL.format(ip, port, topo_uuid) - response = requests.get(topo_list_url, auth=HTTPBasicAuth(user, password)) - topologies.append(response.json()) - print ("Retrieved Topology: " + json.dumps(response.json(), indent=4)) - return topologies - -def draw_topologies (topologies): + topo_url = TOPO_URL.format(ip, port, topo_uuid) + response = requests.get(topo_url, auth=HTTPBasicAuth(user, passwd)) + topology = response.json() + print ("Retrieved Topology: " + json.dumps(topology, indent=4)) + return topology + +def to_png_matplotlib(nwk_graph, topo_uuid): + import matplotlib.pyplot as plt + nx.draw(nwk_graph, pos=nx.spring_layout(nwk_graph, scale=500)) + plt.show(block=False) + plt.savefig('{:s}.png'.format(topo_uuid), format='PNG') + plt.close() + +def to_png_pydot(nwk_graph, topo_uuid): + from networkx.drawing.nx_pydot import write_dot, to_pydot + write_dot(nwk_graph, '{:s}.dot'.format(topo_uuid)) + dot_graph = to_pydot(nwk_graph) + with open('{:s}.png'.format(topo_uuid), 'wb') as f: + f.write(dot_graph.create(format='png')) + +def draw_topology(topology): nwk_graph = nx.DiGraph() - for topo in topologies: - topo_uuid = topo['uuid'] - for node in topo['node']: - if node['owned-node-edge-point']: - nwk_graph.add_node(node['uuid']) - - for link in topo['link']: - node1 = link['node-edge-point'][0]['node-uuid'] - node2 = link['node-edge-point'][1]['node-uuid'] - nwk_graph.add_edge(node1, node2) - - # Using Matplotlib - #import matplotlib.pyplot as plt - #nx.draw(nwk_graph, pos=nx.spring_layout(nwk_graph, scale=500)) - #plt.show(block=False) - #plt.savefig('{:s}.png'.format(TOPO_UUID), format='PNG') - - # Using Pydot and Graphviz - from networkx.drawing.nx_pydot import write_dot, to_pydot - write_dot(nwk_graph, '{:s}.dot'.format(topo_uuid)) - dot_graph = to_pydot(nwk_graph) - with open('{:s}.png'.format(topo_uuid), 'wb') as f: - f.write(dot_graph.create(format='png')) + for node in topology['node']: + if node['owned-node-edge-point']: + nwk_graph.add_node(node['uuid']) + + for link in topology['link']: + node1 = link['node-edge-point'][0]['node-uuid'] + node2 = link['node-edge-point'][1]['node-uuid'] + nwk_graph.add_edge(node1, node2) + + #to_png_matplotlib(nwk_graph, topology['uuid']) + to_png_pydot(nwk_graph, topology['uuid']) if __name__ == "__main__": - topologies = retrieveTopology(IP, PORT, USER, PASS, TOPO_UUID) - draw_topologies(topologies) + draw_topology(retrieve_topology(IP, PORT, TOPO_UUID)) diff --git a/hackfest/tfs-descriptors/context-topology.json b/hackfest/tfs-descriptors/context-topology.json new file mode 100644 index 0000000000000000000000000000000000000000..36b3c44fd61fdec9d208a82a11d5a16c3671d004 --- /dev/null +++ b/hackfest/tfs-descriptors/context-topology.json @@ -0,0 +1,19 @@ +{ + "contexts": [ + { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_ids": [], + "service_ids": [] + } + ], + "topologies": [ + { + "topology_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "topology_uuid": {"uuid": "admin"} + }, + "device_ids": [], + "link_ids": [] + } + ] +} diff --git a/hackfest/tfs-descriptors/device-all.json b/hackfest/tfs-descriptors/device-all.json new file mode 100644 index 0000000000000000000000000000000000000000..ff9e529348a26409549eeffc2ec976443c5e273b --- /dev/null +++ b/hackfest/tfs-descriptors/device-all.json @@ -0,0 +1,84 @@ +{ + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1"}}, + "device_type": "packet-router", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8301"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", + "force_running": false, "hostkey_verify": false, "look_for_keys": false, + "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120} + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [1], + "device_endpoints": [] + }, + { + "device_id": {"device_uuid": {"uuid": "R2"}}, + "device_type": "packet-router", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8302"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", + "force_running": false, "hostkey_verify": false, "look_for_keys": false, + "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120} + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [1], + "device_endpoints": [] + }, + { + "device_id": {"device_uuid": {"uuid": "R3"}}, + "device_type": "packet-router", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8303"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", + "force_running": false, "hostkey_verify": false, "look_for_keys": false, + "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120} + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [1], + "device_endpoints": [] + }, + { + "device_id": {"device_uuid": {"uuid": "R4"}}, + "device_type": "packet-router", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8304"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", + "force_running": false, "hostkey_verify": false, "look_for_keys": false, + "allow_agent": false, "delete_rule": true, "device_params": {"name": "huaweiyang"}, + "manager_params": {"timeout" : 120} + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [1], + "device_endpoints": [] + }, + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, + "device_type": "open-line-system", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]}, + "device_operational_status": 1, + "device_drivers": [2], + "device_endpoints": [] + } + ] +} diff --git a/hackfest/tfs-descriptors/device-netconf-openconfig.json b/hackfest/tfs-descriptors/device-netconf-openconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..7e01f037e744493a8cd1190b2510ed3d4d1c86aa --- /dev/null +++ b/hackfest/tfs-descriptors/device-netconf-openconfig.json @@ -0,0 +1,21 @@ +{ + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "R1"}}, + "device_type": "packet-router", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8300"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": { + "username": "admin", "password": "admin", + "force_running": false, "hostkey_verify": false, "look_for_keys": false, + "allow_agent": false, "delete_rule": true, "device_params": {"name": "default"}, + "manager_params": {"timeout" : 15} + }}} + ]}, + "device_operational_status": 1, + "device_drivers": [1], + "device_endpoints": [] + } + ] +} diff --git a/hackfest/tfs-descriptors/device-tapi-ols.json b/hackfest/tfs-descriptors/device-tapi-ols.json new file mode 100644 index 0000000000000000000000000000000000000000..3dcdc562edb50e0b63e69f5745600110dd42151c --- /dev/null +++ b/hackfest/tfs-descriptors/device-tapi-ols.json @@ -0,0 +1,16 @@ +{ + "devices": [ + { + "device_id": {"device_uuid": {"uuid": "OLS"}}, + "device_type": "open-line-system", + "device_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "_connect/address", "resource_value": "10.0.2.10"}}, + {"action": 1, "custom": {"resource_key": "_connect/port", "resource_value": "8080"}}, + {"action": 1, "custom": {"resource_key": "_connect/settings", "resource_value": {"timeout": 120}}} + ]}, + "device_operational_status": 1, + "device_drivers": [2], + "device_endpoints": [] + } + ] +} diff --git a/hackfest/tfs-descriptors/links.json b/hackfest/tfs-descriptors/links.json new file mode 100644 index 0000000000000000000000000000000000000000..8a991fd622ac89bcb6fafed5abe61de0c6e17641 --- /dev/null +++ b/hackfest/tfs-descriptors/links.json @@ -0,0 +1,63 @@ +{ + "links": [ + { + "link_id": {"link_uuid": {"uuid": "R1/1/1==OLS/node-1-port-15-input"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-1-port-15-input"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/node-1-port-15-output==R1/1/1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-1-port-15-output"}}, + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "R2/1/1==OLS/node-2-port-15-input"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-2-port-15-input"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/node-2-port-15-output==R2/1/1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-2-port-15-output"}}, + {"device_id": {"device_uuid": {"uuid": "R2"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "R3/1/1==OLS/node-3-port-15-input"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-3-port-15-input"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/node-3-port-15-output==R3/1/1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-3-port-15-output"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + }, + + { + "link_id": {"link_uuid": {"uuid": "R4/1/1==OLS/node-4-port-15-input"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "1/1"}}, + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-4-port-15-input"}} + ] + }, + { + "link_id": {"link_uuid": {"uuid": "OLS/node-4-port-15-output==R4/1/1"}}, + "link_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "OLS"}}, "endpoint_uuid": {"uuid": "node-4-port-15-output"}}, + {"device_id": {"device_uuid": {"uuid": "R4"}}, "endpoint_uuid": {"uuid": "1/1"}} + ] + } + ] +} diff --git a/hackfest/netconf-oc/tfs-device-descriptor.json b/hackfest/tfs-descriptors/old/device.json similarity index 100% rename from hackfest/netconf-oc/tfs-device-descriptor.json rename to hackfest/tfs-descriptors/old/device.json diff --git a/hackfest/netconf-oc/tfs-service-descriptor.json b/hackfest/tfs-descriptors/old/service.json similarity index 100% rename from hackfest/netconf-oc/tfs-service-descriptor.json rename to hackfest/tfs-descriptors/old/service.json diff --git a/hackfest/tfs-descriptors/service-l3vpn.json b/hackfest/tfs-descriptors/service-l3vpn.json new file mode 100644 index 0000000000000000000000000000000000000000..457ba1a509aebc5eaea8caa37a09ac62ef286f32 --- /dev/null +++ b/hackfest/tfs-descriptors/service-l3vpn.json @@ -0,0 +1,44 @@ +{ + "services": [ + { + "service_id": { + "context_id": {"context_uuid": {"uuid": "admin"}}, + "service_uuid": {"uuid": "netx-l3-svc"} + }, + "service_type": 1, + "service_status": {"service_status": 1}, + "service_endpoint_ids": [ + {"device_id": {"device_uuid": {"uuid": "R1"}}, "endpoint_uuid": {"uuid": "1/2"}}, + {"device_id": {"device_uuid": {"uuid": "R3"}}, "endpoint_uuid": {"uuid": "1/2"}} + ], + "service_constraints": [ + {"custom": {"constraint_type": "bandwidth[gbps]", "constraint_value": "10.0"}}, + {"custom": {"constraint_type": "latency[ms]", "constraint_value": "15.2"}} + ], + "service_config": {"config_rules": [ + {"action": 1, "custom": {"resource_key": "/settings", "resource_value": { + "address_families": ["IPV4"], + "bgp_as": 65000, + "bgp_route_target": "65000:333", + "mtu": 1512 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R1]/endpoint[1/2]/settings", "resource_value": { + "address_ip": "3.3.2.1", + "address_prefix": 24, + "route_distinguisher": "65000:123", + "router_id": "10.10.10.1", + "sub_interface_index": 400, + "vlan_id": 400 + }}}, + {"action": 1, "custom": {"resource_key": "/device[R3]/endpoint[1/2]/settings", "resource_value": { + "address_ip": "3.3.1.1", + "address_prefix": 24, + "route_distinguisher": "65000:321", + "router_id": "20.20.20.1", + "sub_interface_index": 400, + "vlan_id": 500 + }}} + ]} + } + ] +} diff --git a/hackfest/yang/connection/connection.py b/hackfest/yang/connection/connection.py index a6f573a82799e5b7db7c5a8e87f9f933649bc069..c404d2f5c06508a5b23d733b618dc16dc0b20a9f 100644 --- a/hackfest/yang/connection/connection.py +++ b/hackfest/yang/connection/connection.py @@ -3,12 +3,13 @@ from pyangbind.lib.serialise import pybindIETFXMLEncoder import pyangbind.lib.pybindJSON as pybindJSON con = connection() -con1=con.connection.add("con1") +con1 = con.connection.add("con1") con1.source_node = "node1" con1.target_node = "node2" con1.source_port = "node1portA" con1.target_port = "node2portA" con1.bandwidth = 1000 con1.layer_protocol_name = "OPTICAL" + print(pybindIETFXMLEncoder.serialise(con)) print(pybindJSON.dumps(con)) diff --git a/hackfest/yang/topology.py b/hackfest/yang/topology.py index dc32ca4ec9d42f747145c7f90959266b27b12aa3..441300fb5ca91243e55bbd1995b6610109b52d7e 100644 --- a/hackfest/yang/topology.py +++ b/hackfest/yang/topology.py @@ -3,14 +3,18 @@ from pyangbind.lib.serialise import pybindIETFXMLEncoder import pyangbind.lib.pybindJSON as pybindJSON topo = topology() -node1=topo.topology.node.add("node1") + +node1 = topo.topology.node.add("node1") node1.port.add("node1portA") -node2=topo.topology.node.add("node2") + +node2 = topo.topology.node.add("node2") node2.port.add("node2portA") -link=topo.topology.link.add("link1") + +link = topo.topology.link.add("link1") link.source_node = "node1" link.target_node = "node2" link.source_port = "node1portA" link.target_port = "node2portA" + print(pybindIETFXMLEncoder.serialise(topo)) -print(pybindJSON.dumps(topo)) \ No newline at end of file +print(pybindJSON.dumps(topo))