4 from requests.auth import HTTPBasicAuth
5 from subprocess import call
18 OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
19 CONF_TENANT='/restconf/config/policy:tenants'
21 def get(host, port, uri):
22 url='http://'+host+":"+port+uri
23 r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
26 def put(host, port, uri, data, debug=False):
27 '''Perform a PUT rest operation, using the URL and data provided'''
29 url='http://'+host+":"+port+uri
31 headers = {'Content-type': 'application/yang.data+json',
32 'Accept': 'application/yang.data+json'}
35 print json.dumps(data, indent=4, sort_keys=True)
36 r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
41 def post(host, port, uri, data, debug=False):
42 '''Perform a POST rest operation, using the URL and data provided'''
44 url='http://'+host+":"+port+uri
45 headers = {'Content-type': 'application/yang.data+json',
46 'Accept': 'application/yang.data+json'}
49 print json.dumps(data, indent=4, sort_keys=True)
50 r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
55 def wait_for_sff_in_datastore(url):
57 resp=get(controller, DEFAULT_PORT, url)
58 if ('192.168.50.71' in resp.text) and ('192.168.50.73' in resp.text):
61 if ('192.168.50.71' not in resp.text):
62 print "ERROR: SFF1 has not been initialized!"
64 if ('192.168.50.73' not in resp.text):
65 print "ERROR: SFF2 has not been initialized!"
71 def get_service_functions_uri():
72 return "/restconf/config/service-function:service-functions"
74 def get_service_functions_data():
76 "service-functions": {
79 "name": "firewall-72",
80 "ip-mgmt-address": "192.168.50.72",
81 "type": "service-function-type:firewall",
83 "sf-data-plane-locator": [
87 "ip": "192.168.50.72",
88 "transport": "service-locator:vxlan-gpe",
89 "service-function-forwarder": "SFF1"
95 "ip-mgmt-address": "192.168.50.74",
96 "type": "service-function-type:dpi",
98 "sf-data-plane-locator": [
102 "ip": "192.168.50.74",
103 "transport": "service-locator:vxlan-gpe",
104 "service-function-forwarder": "SFF2"
112 def get_service_function_forwarders_uri():
113 return "/restconf/config/service-function-forwarder:service-function-forwarders"
115 def get_service_function_forwarders_data():
117 "service-function-forwarders": {
118 "service-function-forwarder": [
121 "service-node": "OVSDB2",
122 "service-function-forwarder-ovs:ovs-bridge": {
125 "service-function-dictionary": [
127 "name": "firewall-72",
128 "sff-sf-data-plane-locator": {
130 "sff-dpl-name": "sfc-tun2"
134 "sff-data-plane-locator": [
137 "data-plane-locator": {
138 "transport": "service-locator:vxlan-gpe",
140 "ip": "192.168.50.71"
142 "service-function-forwarder-ovs:ovs-options": {
158 "service-node": "OVSDB2",
159 "service-function-forwarder-ovs:ovs-bridge": {
162 "service-function-dictionary": [
165 "sff-sf-data-plane-locator": {
167 "sff-dpl-name": "sfc-tun4"
171 "sff-data-plane-locator": [
174 "data-plane-locator": {
175 "transport": "service-locator:vxlan-gpe",
177 "ip": "192.168.50.73"
179 "service-function-forwarder-ovs:ovs-options": {
197 def get_service_function_chains_uri():
198 return "/restconf/config/service-function-chain:service-function-chains/"
200 def get_service_function_chains_data():
202 "service-function-chains": {
203 "service-function-chain": [
207 "sfc-service-function": [
209 "name": "firewall-abstract1",
210 "type": "service-function-type:firewall"
213 "name": "dpi-abstract1",
214 "type": "service-function-type:dpi"
222 def get_service_function_paths_uri():
223 return "/restconf/config/service-function-path:service-function-paths/"
225 def get_service_function_paths_data():
227 "service-function-paths": {
228 "service-function-path": [
230 "name": "SFCGBP-Path",
231 "service-chain-name": "SFCGBP",
232 "starting-index": 255,
240 def get_tenant_data():
244 "id": "tenant-dobre",
247 "id": "flood-domain-1",
248 "parent": "bridge-domain1"
251 "id": "flood-domain-2",
252 "parent": "bridge-domain1"
255 "name": "DockerTenant",
258 "id": "l3-context-vrf-red"
261 "l2-bridge-domain": [
263 "id": "bridge-domain1",
264 "parent": "l3-context-vrf-red"
269 "id": "subnet-10.0.36.0/24",
270 "virtual-router-ip": "10.0.36.1",
271 "parent": "flood-domain-2",
272 "ip-prefix": "10.0.36.1/24"
275 "id": "subnet-10.0.35.0/24",
276 "virtual-router-ip": "10.0.35.1",
277 "parent": "flood-domain-1",
278 "ip-prefix": "10.0.35.1/24"
284 "name" : "webservers",
285 "provider-named-selector": [
287 "name": "webservers-clients-icmp-http-contract",
297 "consumer-named-selector": [
299 "name": "webservers-clients-icmp-http-contract",
307 "subject-feature-instances": {
308 "classifier-instance": [
311 "classifier-definition-id": "Classifier-IP-Protocol",
321 "classifier-definition-id": "Classifier-L4",
335 "classifier-definition-id": "Classifier-L4",
351 "action-definition-id": "Action-Chain",
354 "name": "sfc-chain-name",
355 "string-value": "SFCGBP"
361 "action-definition-id": "Action-Allow"
367 "id": "icmp-http-contract",
370 "name": "icmp-subject",
373 "name": "allow-icmp-rule",
378 "instance-name" : "icmp"
392 "name": "http-subject",
395 "name": "http-chain-rule-in",
398 "name" : "http-dest",
399 "instance-name": "http-dest",
411 "name": "http-chain-rule-out",
415 "instance-name": "http-src",
431 "name": "icmp-http-clause",
444 # Main definition - constants
446 # =======================
448 # =======================
452 # =======================
454 # =======================
458 def get_tenant_uri():
459 return "/restconf/config/policy:tenants/policy:tenant/tenant-dobre"
461 def get_tunnel_data_1():
466 "ofoverlay:tunnel": [
468 "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
469 "node-connector-id": "openflow:1:1",
470 "ip": "192.168.50.70",
474 "tunnel-type": "overlay:tunnel-type-vxlan",
475 "node-connector-id": "openflow:1:2",
476 "ip": "192.168.50.70",
484 def get_tunnel_uri_1():
485 return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
487 def get_tunnel_data_6():
492 "ofoverlay:tunnel": [
494 "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
495 "node-connector-id": "openflow:6:1",
496 "ip": "192.168.50.75",
500 "tunnel-type": "overlay:tunnel-type-vxlan",
501 "node-connector-id": "openflow:6:2",
502 "ip": "192.168.50.75",
510 def get_tunnel_uri_6():
511 return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
513 def get_endpoint_data():
518 "endpoint-group": "webservers",
520 "network-containment" : "subnet-10.0.36.0/24",
522 "l2-context": "bridge-domain1",
523 "mac-address": "00:00:00:00:36:02",
527 "ip-address": "10.0.36.2",
528 "l3-context": "l3-context-vrf-red"
531 "port-name": "vethl-h36_2",
532 "tenant": "tenant-dobre"
537 "endpoint-group": "clients",
538 "network-containment" : "subnet-10.0.35.0/24",
539 "l2-context": "bridge-domain1",
540 "mac-address": "00:00:00:00:35:02",
543 "ip-address": "10.0.35.2",
544 "l3-context": "l3-context-vrf-red"
547 "port-name": "vethl-h35_2",
548 "tenant": "tenant-dobre"
554 "endpoint-group": "clients",
556 "network-containment" : "subnet-10.0.35.0/24",
558 "l2-context": "bridge-domain1",
559 "mac-address": "00:00:00:00:35:03",
563 "ip-address": "10.0.35.3",
564 "l3-context": "l3-context-vrf-red"
567 "port-name": "vethl-h35_3",
568 "tenant": "tenant-dobre"
574 "endpoint-group": "webservers",
576 "network-containment" : "subnet-10.0.36.0/24",
578 "l2-context": "bridge-domain1",
579 "mac-address": "00:00:00:00:36:03",
583 "ip-address": "10.0.36.3",
584 "l3-context": "l3-context-vrf-red"
587 "port-name": "vethl-h36_3",
588 "tenant": "tenant-dobre"
594 "endpoint-group": "webservers",
596 "network-containment" : "subnet-10.0.36.0/24",
598 "l2-context": "bridge-domain1",
599 "mac-address": "00:00:00:00:36:04",
603 "ip-address": "10.0.36.4",
604 "l3-context": "l3-context-vrf-red"
607 "port-name": "vethl-h36_4",
608 "tenant": "tenant-dobre"
614 "endpoint-group": "clients",
616 "network-containment" : "subnet-10.0.35.0/24",
618 "l2-context": "bridge-domain1",
619 "mac-address": "00:00:00:00:35:04",
623 "ip-address": "10.0.35.4",
624 "l3-context": "l3-context-vrf-red"
627 "port-name": "vethl-h35_4",
628 "tenant": "tenant-dobre"
634 "endpoint-group": "clients",
636 "network-containment" : "subnet-10.0.35.0/24",
638 "l2-context": "bridge-domain1",
639 "mac-address": "00:00:00:00:35:05",
643 "ip-address": "10.0.35.5",
644 "l3-context": "l3-context-vrf-red"
647 "port-name": "vethl-h35_5",
648 "tenant": "tenant-dobre"
654 "endpoint-group": "webservers",
656 "network-containment" : "subnet-10.0.36.0/24",
658 "l2-context": "bridge-domain1",
659 "mac-address": "00:00:00:00:36:05",
663 "ip-address": "10.0.36.5",
664 "l3-context": "l3-context-vrf-red"
667 "port-name": "vethl-h36_5",
668 "tenant": "tenant-dobre"
672 def get_endpoint_uri():
673 return "/restconf/operations/endpoint:register-endpoint"
675 def get_tunnel_oper_uri():
676 return "/restconf/operational/opendaylight-inventory:nodes/"
678 def get_topology_oper_uri():
679 return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
681 if __name__ == "__main__":
685 # Some sensible defaults
686 controller=os.environ.get('ODL')
687 if controller == None:
688 sys.exit("No controller set.")
690 print "Contacting controller at %s" % controller
691 print "waiting for manager on SFFs..."
692 wait_for_sff_in_datastore(get_topology_oper_uri())
693 print "sending service functions"
694 put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
695 print "sending service function forwarders"
696 put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
697 print "waiting for switches on SFFs..."
698 wait_for_sff_in_datastore(get_tunnel_oper_uri())
699 print "sending service function chains"
700 put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
701 print "sending service function paths"
702 put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
703 print "sending tunnel"
704 put(controller, DEFAULT_PORT, get_tunnel_uri_1(), get_tunnel_data_1(), True)
705 print "sending tenant"
706 put(controller, DEFAULT_PORT, get_tunnel_uri_6(), get_tunnel_data_6(), True)
707 print "sending tenant"
708 put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
709 print "registering endpoints"
710 for endpoint in get_endpoint_data():
711 post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)