4 from requests.auth import HTTPBasicAuth
\r
5 from subprocess import call
\r
18 CONF_TENANT='/restconf/config/policy:tenants'
\r
20 def get(host, port, uri):
\r
21 url='http://'+host+":"+port+uri
\r
22 r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
\r
25 def put(host, port, uri, data, debug=False):
\r
26 '''Perform a PUT rest operation, using the URL and data provided'''
\r
28 url='http://'+host+":"+port+uri
\r
30 headers = {'Content-type': 'application/yang.data+json',
\r
31 'Accept': 'application/yang.data+json'}
\r
33 print "PUT %s" % url
\r
34 print json.dumps(data, indent=4, sort_keys=True)
\r
35 r = requests.put(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
\r
38 r.raise_for_status()
\r
40 def post(host, port, uri, data, debug=False):
\r
41 '''Perform a POST rest operation, using the URL and data provided'''
\r
43 url='http://'+host+":"+port+uri
\r
44 headers = {'Content-type': 'application/yang.data+json',
\r
45 'Accept': 'application/yang.data+json'}
\r
47 print "POST %s" % url
\r
48 print json.dumps(data, indent=4, sort_keys=True)
\r
49 r = requests.post(url, data=json.dumps(data), headers=headers, auth=HTTPBasicAuth(USERNAME, PASSWORD))
\r
52 r.raise_for_status()
\r
54 def wait_for_sff_in_datastore(url):
\r
55 for i in xrange(30):
\r
56 resp=get(controller, DEFAULT_PORT, url)
\r
57 if ('192.168.50.70' in resp.text) and ('192.168.50.71' in resp.text):
\r
60 if ('192.168.50.70' not in resp.text):
\r
61 print "ERROR: SFF1 has not been initialized!"
\r
63 if ('192.168.50.71' not in resp.text):
\r
64 print "ERROR: SFF2 has not been initialized!"
\r
69 def get_service_functions_uri():
\r
70 return "/restconf/config/service-function:service-functions"
\r
72 def get_service_functions_data():
\r
74 "service-functions": {
\r
75 "service-function": [
\r
77 "name": "firewall-72",
\r
78 "ip-mgmt-address": "192.168.50.72",
\r
79 "type": "service-function-type:firewall",
\r
80 "nsh-aware": "true",
\r
81 "sf-data-plane-locator": [
\r
85 "ip": "192.168.50.72",
\r
86 "transport": "service-locator:vxlan-gpe",
\r
87 "service-function-forwarder": "SFF1"
\r
93 "ip-mgmt-address": "192.168.50.74",
\r
94 "type": "service-function-type:dpi",
\r
95 "nsh-aware": "true",
\r
96 "sf-data-plane-locator": [
\r
100 "ip": "192.168.50.74",
\r
101 "transport": "service-locator:vxlan-gpe",
\r
102 "service-function-forwarder": "SFF2"
\r
110 def get_service_function_forwarders_uri():
\r
111 return "/restconf/config/service-function-forwarder:service-function-forwarders"
\r
113 def get_service_function_forwarders_data():
\r
115 "service-function-forwarders": {
\r
116 "service-function-forwarder": [
\r
119 "service-node": "OVSDB2",
\r
120 "service-function-forwarder-ovs:ovs-bridge": {
\r
121 "bridge-name": "sw1"
\r
123 "service-function-dictionary": [
\r
125 "name": "firewall-72",
\r
126 "sff-sf-data-plane-locator": {
\r
127 "sf-dpl-name": "2",
\r
128 "sff-dpl-name": "sfc-tun2"
\r
132 "sff-data-plane-locator": [
\r
134 "name": "sfc-tun2",
\r
135 "data-plane-locator": {
\r
136 "transport": "service-locator:vxlan-gpe",
\r
138 "ip": "192.168.50.70"
\r
140 "service-function-forwarder-ovs:ovs-options": {
\r
141 "remote-ip": "flow",
\r
142 "dst-port": "6633",
\r
156 "service-node": "OVSDB2",
\r
157 "service-function-forwarder-ovs:ovs-bridge": {
\r
158 "bridge-name": "sw2"
\r
160 "service-function-dictionary": [
\r
163 "sff-sf-data-plane-locator": {
\r
164 "sf-dpl-name": "3",
\r
165 "sff-dpl-name": "sfc-tun4"
\r
169 "sff-data-plane-locator": [
\r
171 "name": "sfc-tun4",
\r
172 "data-plane-locator": {
\r
173 "transport": "service-locator:vxlan-gpe",
\r
175 "ip": "192.168.50.71"
\r
177 "service-function-forwarder-ovs:ovs-options": {
\r
178 "remote-ip": "flow",
\r
179 "dst-port": "6633",
\r
195 def get_service_function_chains_uri():
\r
196 return "/restconf/config/service-function-chain:service-function-chains/"
\r
198 def get_service_function_chains_data():
\r
200 "service-function-chains": {
\r
201 "service-function-chain": [
\r
204 "symmetric": "false",
\r
205 "sfc-service-function": [
\r
207 "name": "firewall-abstract1",
\r
208 "type": "service-function-type:firewall"
\r
211 "name": "dpi-abstract1",
\r
212 "type": "service-function-type:dpi"
\r
220 def get_service_function_paths_uri():
\r
221 return "/restconf/config/service-function-path:service-function-paths/"
\r
223 def get_service_function_paths_data():
\r
225 "service-function-paths": {
\r
226 "service-function-path": [
\r
228 "name": "SFCGBP-Path",
\r
229 "service-chain-name": "SFCGBP",
\r
230 "starting-index": 255,
\r
231 "symmetric": "false"
\r
238 def get_tenant_data():
\r
242 "id": "tenant-red",
\r
243 "name": "DockerTenant",
\r
244 "forwarding-context": {
\r
245 "l2-flood-domain": [
\r
247 "id": "flood-domain-1",
\r
248 "parent": "bridge-domain1"
\r
251 "id": "flood-domain-2",
\r
252 "parent": "bridge-domain1"
\r
257 "id": "l3-context-vrf-red"
\r
260 "l2-bridge-domain": [
\r
262 "id": "bridge-domain1",
\r
263 "parent": "l3-context-vrf-red"
\r
268 "id": "subnet-10.0.36.0/24",
\r
269 "virtual-router-ip": "10.0.36.1",
\r
270 "parent": "flood-domain-2",
\r
271 "ip-prefix": "10.0.36.1/24"
\r
274 "id": "subnet-10.0.35.0/24",
\r
275 "virtual-router-ip": "10.0.35.1",
\r
276 "parent": "flood-domain-1",
\r
277 "ip-prefix": "10.0.35.1/24"
\r
282 "endpoint-group": [
\r
284 "id": "webservers",
\r
285 "name": "webservers",
\r
286 "provider-named-selector": [
\r
288 "name": "webservers-clients-icmp-http-contract",
\r
290 "icmp-http-contract"
\r
298 "consumer-named-selector": [
\r
300 "name": "webservers-clients-icmp-http-contract",
\r
302 "icmp-http-contract"
\r
308 "subject-feature-instances": {
\r
309 "classifier-instance": [
\r
312 "classifier-definition-id": "Classifier-IP-Protocol",
\r
313 "parameter-value": [
\r
321 "name": "http-dest",
\r
322 "classifier-definition-id": "Classifier-L4",
\r
323 "parameter-value": [
\r
335 "name": "http-src",
\r
336 "classifier-definition-id": "Classifier-L4",
\r
337 "parameter-value": [
\r
344 "name": "sourceport"
\r
349 "action-instance": [
\r
352 "action-definition-id": "Action-Chain",
\r
353 "parameter-value": [
\r
355 "name": "sfc-chain-name",
\r
356 "string-value": "SFCGBP"
\r
362 "action-definition-id": "Action-Allow"
\r
368 "id": "icmp-http-contract",
\r
371 "name": "icmp-subject",
\r
374 "name": "allow-icmp-rule",
\r
376 "classifier-ref": [
\r
379 "instance-name": "icmp"
\r
392 "name": "http-subject",
\r
395 "name": "http-chain-rule",
\r
396 "classifier-ref": [
\r
398 "name": "http-dest",
\r
399 "instance-name": "http-dest",
\r
411 "name": "http-out-rule",
\r
412 "classifier-ref": [
\r
414 "name": "http-src",
\r
415 "instance-name": "http-src",
\r
431 "name": "icmp-http-clause",
\r
445 # Main definition - constants
\r
447 # =======================
\r
449 # =======================
\r
453 # =======================
\r
455 # =======================
\r
459 def get_tenant_uri():
\r
460 return "/restconf/config/policy:tenants/policy:tenant/tenant-red"
\r
462 def get_tunnel_data_1():
\r
466 "id": "openflow:1",
\r
467 "ofoverlay:tunnel": [
\r
469 "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
\r
470 "node-connector-id": "openflow:1:1",
\r
471 "ip": "192.168.50.70",
\r
475 "tunnel-type": "overlay:tunnel-type-vxlan",
\r
476 "node-connector-id": "openflow:1:2",
\r
477 "ip": "192.168.50.70",
\r
485 def get_tunnel_uri_1():
\r
486 return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
\r
488 def get_tunnel_data_6():
\r
492 "id": "openflow:6",
\r
493 "ofoverlay:tunnel": [
\r
495 "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
\r
496 "node-connector-id": "openflow:6:1",
\r
497 "ip": "192.168.50.75",
\r
501 "tunnel-type": "overlay:tunnel-type-vxlan",
\r
502 "node-connector-id": "openflow:6:2",
\r
503 "ip": "192.168.50.75",
\r
511 def get_tunnel_uri_6():
\r
512 return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
\r
514 def get_endpoint_data():
\r
519 "endpoint-group": "webservers",
\r
521 "network-containment" : "subnet-10.0.36.0/24",
\r
523 "l2-context": "bridge-domain1",
\r
524 "mac-address": "00:00:00:00:36:02",
\r
528 "ip-address": "10.0.36.2",
\r
529 "l3-context": "l3-context-vrf-red"
\r
532 "port-name": "vethl-h36_2",
\r
533 "tenant": "tenant-red"
\r
538 "endpoint-group": "clients",
\r
539 "network-containment" : "subnet-10.0.35.0/24",
\r
540 "l2-context": "bridge-domain1",
\r
541 "mac-address": "00:00:00:00:35:02",
\r
544 "ip-address": "10.0.35.2",
\r
545 "l3-context": "l3-context-vrf-red"
\r
548 "port-name": "vethl-h35_2",
\r
549 "tenant": "tenant-red"
\r
555 "endpoint-group": "clients",
\r
557 "network-containment" : "subnet-10.0.35.0/24",
\r
559 "l2-context": "bridge-domain1",
\r
560 "mac-address": "00:00:00:00:35:03",
\r
564 "ip-address": "10.0.35.3",
\r
565 "l3-context": "l3-context-vrf-red"
\r
568 "port-name": "vethl-h35_3",
\r
569 "tenant": "tenant-red"
\r
575 "endpoint-group": "webservers",
\r
577 "network-containment" : "subnet-10.0.36.0/24",
\r
579 "l2-context": "bridge-domain1",
\r
580 "mac-address": "00:00:00:00:36:03",
\r
584 "ip-address": "10.0.36.3",
\r
585 "l3-context": "l3-context-vrf-red"
\r
588 "port-name": "vethl-h36_3",
\r
589 "tenant": "tenant-red"
\r
595 "endpoint-group": "webservers",
\r
597 "network-containment" : "subnet-10.0.36.0/24",
\r
599 "l2-context": "bridge-domain1",
\r
600 "mac-address": "00:00:00:00:36:04",
\r
604 "ip-address": "10.0.36.4",
\r
605 "l3-context": "l3-context-vrf-red"
\r
608 "port-name": "vethl-h36_4",
\r
609 "tenant": "tenant-red"
\r
615 "endpoint-group": "clients",
\r
617 "network-containment" : "subnet-10.0.35.0/24",
\r
619 "l2-context": "bridge-domain1",
\r
620 "mac-address": "00:00:00:00:35:04",
\r
624 "ip-address": "10.0.35.4",
\r
625 "l3-context": "l3-context-vrf-red"
\r
628 "port-name": "vethl-h35_4",
\r
629 "tenant": "tenant-red"
\r
635 "endpoint-group": "clients",
\r
637 "network-containment" : "subnet-10.0.35.0/24",
\r
639 "l2-context": "bridge-domain1",
\r
640 "mac-address": "00:00:00:00:35:05",
\r
644 "ip-address": "10.0.35.5",
\r
645 "l3-context": "l3-context-vrf-red"
\r
648 "port-name": "vethl-h35_5",
\r
649 "tenant": "tenant-red"
\r
655 "endpoint-group": "webservers",
\r
657 "network-containment" : "subnet-10.0.36.0/24",
\r
659 "l2-context": "bridge-domain1",
\r
660 "mac-address": "00:00:00:00:36:05",
\r
664 "ip-address": "10.0.36.5",
\r
665 "l3-context": "l3-context-vrf-red"
\r
668 "port-name": "vethl-h36_5",
\r
669 "tenant": "tenant-red"
\r
674 def get_endpoint_uri():
\r
675 return "/restconf/operations/endpoint:register-endpoint"
\r
677 def get_tunnel_oper_uri():
\r
678 return "/restconf/operational/opendaylight-inventory:nodes/"
\r
680 def get_topology_oper_uri():
\r
681 return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
\r
683 if __name__ == "__main__":
\r
687 # Some sensible defaults
\r
688 controller=os.environ.get('ODL')
\r
689 if controller == None:
\r
690 sys.exit("No controller set.")
\r
692 print "Contacting controller at %s" % controller
\r
693 print "waiting for manager on SFFs..."
\r
694 wait_for_sff_in_datastore(get_topology_oper_uri())
\r
695 print "sending service functions"
\r
696 put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
\r
697 print "sending service function forwarders"
\r
698 put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
\r
699 print "waiting for switches on SFFs..."
\r
700 wait_for_sff_in_datastore(get_tunnel_oper_uri())
\r
701 print "sending service function chains"
\r
702 put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
\r
703 print "sending service function paths"
\r
704 put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
\r
705 print "sending tunnel"
\r
706 put(controller, DEFAULT_PORT, get_tunnel_uri_1(), get_tunnel_data_1(), True)
\r
707 print "sending tenant"
\r
708 put(controller, DEFAULT_PORT, get_tunnel_uri_6(), get_tunnel_data_6(), True)
\r
709 print "sending tenant"
\r
710 put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
\r
711 print "registering endpoints"
\r
712 for endpoint in get_endpoint_data():
\r
713 post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)
\r