5eb35bc7f993fe223a04981e818170dfabdbfcf0
[groupbasedpolicy.git] / demos / gbpsfc-env / demo-symmetric-chain / rest.py
1 #!/usr/bin/python
2 import argparse
3 import requests,json
4 from requests.auth import HTTPBasicAuth
5 from subprocess import call
6 import time
7 import sys
8 import os
9
10
11 DEFAULT_PORT='8181'
12
13
14 USERNAME='admin'
15 PASSWORD='admin'
16
17
18 OPER_NODES='/restconf/operational/opendaylight-inventory:nodes/'
19 CONF_TENANT='/restconf/config/policy:tenants'
20
21 def get(host, port, uri):
22     url='http://'+host+":"+port+uri
23     r = requests.get(url, auth=HTTPBasicAuth(USERNAME, PASSWORD))
24     return r
25
26 def put(host, port, uri, data, debug=False):
27     '''Perform a PUT rest operation, using the URL and data provided'''
28
29     url='http://'+host+":"+port+uri
30
31     headers = {'Content-type': 'application/yang.data+json',
32                'Accept': 'application/yang.data+json'}
33     if debug == True:
34         print "PUT %s" % url
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))
37     if debug == True:
38         print r.text
39     r.raise_for_status()
40
41 def post(host, port, uri, data, debug=False):
42     '''Perform a POST rest operation, using the URL and data provided'''
43
44     url='http://'+host+":"+port+uri
45     headers = {'Content-type': 'application/yang.data+json',
46                'Accept': 'application/yang.data+json'}
47     if debug == True:
48         print "POST %s" % url
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))
51     if debug == True:
52         print r.text
53     r.raise_for_status()
54
55 def wait_for_sff_in_datastore(url):
56     for i in xrange(30):
57         resp=get(controller, DEFAULT_PORT, url)
58         if ('192.168.50.71' in resp.text) and ('192.168.50.73' in resp.text):
59             break
60         time.sleep(3)
61     if ('192.168.50.71' not in resp.text):
62         print "ERROR: SFF1 has not been initialized!"
63         sys.exit(1)
64     if ('192.168.50.73' not in resp.text):
65         print "ERROR: SFF2 has not been initialized!"
66         sys.exit(1)
67
68
69
70
71 def get_service_functions_uri():
72     return "/restconf/config/service-function:service-functions"
73
74 def get_service_functions_data():
75     return {
76     "service-functions": {
77         "service-function": [
78             {
79                 "name": "firewall-72",
80                 "ip-mgmt-address": "192.168.50.72",
81                 "type": "service-function-type:firewall",
82                 "nsh-aware": "true",
83                 "sf-data-plane-locator": [
84                     {
85                         "name": "2",
86                         "port": 6633,
87                         "ip": "192.168.50.72",
88                         "transport": "service-locator:vxlan-gpe",
89                         "service-function-forwarder": "SFF1"
90                     }
91                 ]
92             },
93             {
94                 "name": "dpi-74",
95                 "ip-mgmt-address": "192.168.50.74",
96                 "type": "service-function-type:dpi",
97                 "nsh-aware": "true",
98                 "sf-data-plane-locator": [
99                     {
100                         "name": "3",
101                         "port": 6633,
102                         "ip": "192.168.50.74",
103                         "transport": "service-locator:vxlan-gpe",
104                         "service-function-forwarder": "SFF2"
105                     }
106                 ]
107             }
108         ]
109     }
110 }
111
112 def get_service_function_forwarders_uri():
113     return "/restconf/config/service-function-forwarder:service-function-forwarders"
114
115 def get_service_function_forwarders_data():
116     return {
117     "service-function-forwarders": {
118         "service-function-forwarder": [
119             {
120                 "name": "SFF1",
121                 "service-node": "OVSDB2",
122                 "service-function-forwarder-ovs:ovs-bridge": {
123                     "bridge-name": "sw2"
124                 },
125                 "service-function-dictionary": [
126                     {
127                         "name": "firewall-72",
128                         "sff-sf-data-plane-locator": {
129                             "sf-dpl-name": "2",
130                             "sff-dpl-name": "sfc-tun2"
131                         }
132                     }
133                 ],
134                 "sff-data-plane-locator": [
135                     {
136                         "name": "sfc-tun2",
137                         "data-plane-locator": {
138                             "transport": "service-locator:vxlan-gpe",
139                             "port": 6633,
140                             "ip": "192.168.50.71"
141                         },
142                         "service-function-forwarder-ovs:ovs-options": {
143                             "remote-ip": "flow",
144                             "dst-port": "6633",
145                             "key": "flow",
146                             "nsp": "flow",
147                             "nsi": "flow",
148                             "nshc1": "flow",
149                             "nshc2": "flow",
150                             "nshc3": "flow",
151                             "nshc4": "flow"
152                         }
153                     }
154                 ]
155             },
156             {
157                 "name": "SFF2",
158                 "service-node": "OVSDB2",
159                 "service-function-forwarder-ovs:ovs-bridge": {
160                     "bridge-name": "sw4"
161                 },
162                 "service-function-dictionary": [
163                     {
164                         "name": "dpi-74",
165                         "sff-sf-data-plane-locator": {
166                             "sf-dpl-name": "3",
167                             "sff-dpl-name": "sfc-tun4"
168                         }
169                     }
170                 ],
171                 "sff-data-plane-locator": [
172                     {
173                         "name": "sfc-tun4",
174                         "data-plane-locator": {
175                             "transport": "service-locator:vxlan-gpe",
176                             "port": 6633,
177                             "ip": "192.168.50.73"
178                         },
179                         "service-function-forwarder-ovs:ovs-options": {
180                             "remote-ip": "flow",
181                             "dst-port": "6633",
182                             "key": "flow",
183                             "nsp": "flow",
184                             "nsi": "flow",
185                             "nshc1": "flow",
186                             "nshc2": "flow",
187                             "nshc3": "flow",
188                             "nshc4": "flow"
189                         }
190                     }
191                 ]
192             }
193         ]
194     }
195 }
196
197 def get_service_function_chains_uri():
198     return "/restconf/config/service-function-chain:service-function-chains/"
199
200 def get_service_function_chains_data():
201     return {
202     "service-function-chains": {
203         "service-function-chain": [
204             {
205                 "name": "SFCGBP",
206                 "symmetric": "true",
207                 "sfc-service-function": [
208                     {
209                         "name": "firewall-abstract1",
210                         "type": "service-function-type:firewall"
211                     },
212                     {
213                         "name": "dpi-abstract1",
214                         "type": "service-function-type:dpi"
215                     }
216                 ]
217             }
218         ]
219     }
220 }
221
222 def get_service_function_paths_uri():
223     return "/restconf/config/service-function-path:service-function-paths/"
224
225 def get_service_function_paths_data():
226     return {
227     "service-function-paths": {
228         "service-function-path": [
229             {
230                 "name": "SFCGBP-Path",
231                 "service-chain-name": "SFCGBP",
232                 "starting-index": 255,
233                 "symmetric": "true"
234
235             }
236         ]
237     }
238 }
239
240 def get_tenant_data():
241     return {
242     "tenant": [
243       {
244         "id": "tenant-dobre",
245         "l2-flood-domain": [
246           {
247             "id": "flood-domain-1",
248             "parent": "bridge-domain1"
249           },
250           {
251             "id": "flood-domain-2",
252             "parent": "bridge-domain1"
253           }
254         ],
255         "name": "DockerTenant",
256         "l3-context": [
257           {
258             "id": "l3-context-vrf-red"
259           }
260         ],
261         "l2-bridge-domain": [
262           {
263             "id": "bridge-domain1",
264             "parent": "l3-context-vrf-red"
265           }
266         ],
267         "subnet": [
268           {
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"
273           },
274           {
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"
279           }
280         ],
281         "endpoint-group": [
282           {
283             "id": "webservers",
284             "name" : "webservers",
285             "provider-named-selector": [
286               {
287                 "name": "webservers-clients-icmp-http-contract",
288                 "contract": [
289                   "icmp-http-contract"
290                 ]
291               }
292             ]
293           },
294           {
295             "id": "clients",
296             "name" : "clients",
297             "consumer-named-selector": [
298               {
299                 "name": "webservers-clients-icmp-http-contract",
300                 "contract": [
301                   "icmp-http-contract"
302                 ]
303               }
304             ]
305           }
306         ],
307         "subject-feature-instances": {
308           "classifier-instance": [
309             {
310               "name": "icmp",
311               "classifier-definition-id": "Classifier-IP-Protocol",
312               "parameter-value": [
313                 {
314                   "name": "proto",
315                   "int-value": 1
316                 }
317               ]
318             },
319             {
320               "name": "http-dest",
321               "classifier-definition-id": "Classifier-L4",
322               "parameter-value": [
323                 {
324                   "int-value": "6",
325                   "name": "proto"
326                 },
327                 {
328                   "int-value": "80",
329                   "name": "destport"
330                 }
331               ]
332             },
333             {
334               "name": "http-src",
335               "classifier-definition-id": "Classifier-L4",
336               "parameter-value": [
337                 {
338                   "int-value": "6",
339                   "name": "proto"
340                 },
341                 {
342                   "int-value": "80",
343                   "name": "sourceport"
344                 }
345               ]
346             }
347           ],
348           "action-instance": [
349             {
350               "name": "chain1",
351               "action-definition-id": "Action-Chain",
352               "parameter-value": [
353                 {
354                   "name": "sfc-chain-name",
355                   "string-value": "SFCGBP"
356                 }
357               ]
358             },
359             {
360               "name": "allow1",
361               "action-definition-id": "Action-Allow"
362             }
363           ]
364         },
365         "contract": [
366           {
367             "id": "icmp-http-contract",
368             "subject": [
369               {
370                 "name": "icmp-subject",
371                 "rule": [
372                   {
373                     "name": "allow-icmp-rule",
374                     "order" : 0,
375                     "classifier-ref": [
376                       {
377                         "name": "icmp",
378                         "instance-name" : "icmp"
379                       }
380                     ],
381                     "action-ref": [
382                       {
383                         "name": "allow1",
384                         "order": 0
385                       }
386                     ]
387                   }
388
389                 ]
390               },
391               {
392                 "name": "http-subject",
393                 "rule": [
394                   {
395                     "name": "http-chain-rule-in",
396                     "classifier-ref": [
397                       {
398                         "name" : "http-dest",
399                         "instance-name": "http-dest",
400                         "direction": "in"
401                       }
402                     ],
403                     "action-ref": [
404                       {
405                         "name": "chain1",
406                         "order": 0
407                       }
408                     ]
409                   },
410                   {
411                     "name": "http-chain-rule-out",
412                     "classifier-ref": [
413                       {
414                         "name" : "http-src",
415                         "instance-name": "http-src",
416                         "direction": "out"
417                       }
418                     ],
419                     "action-ref": [
420                       {
421                         "name": "chain1",
422                         "order": 0
423                       }
424                     ]
425                   }
426                 ]
427               }
428             ],
429             "clause": [
430               {
431                 "name": "icmp-http-clause",
432                 "subject-refs": [
433                   "icmp-subject",
434                   "http-subject"
435                 ]
436               }
437             ]
438           }
439         ]
440       }
441     ]
442 }
443
444 # Main definition - constants
445
446 # =======================
447 #     MENUS FUNCTIONS
448 # =======================
449
450 # Main menu
451
452 # =======================
453 #      MAIN PROGRAM
454 # =======================
455
456 # Main Program
457
458 def get_tenant_uri():
459     return "/restconf/config/policy:tenants/policy:tenant/tenant-dobre"
460
461 def get_tunnel_data_1():
462     return {
463     "node": [
464       {
465         "id": "openflow:1",
466         "ofoverlay:tunnel": [
467           {
468             "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
469             "node-connector-id": "openflow:1:1",
470             "ip": "192.168.50.70",
471             "port": 6633
472           },
473           {
474             "tunnel-type": "overlay:tunnel-type-vxlan",
475             "node-connector-id": "openflow:1:2",
476             "ip": "192.168.50.70",
477             "port": 4789
478           }
479         ]
480       }
481     ]
482   }
483
484 def get_tunnel_uri_1():
485     return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
486
487 def get_tunnel_data_6():
488     return {
489     "node": [
490       {
491         "id": "openflow:6",
492         "ofoverlay:tunnel": [
493           {
494             "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
495             "node-connector-id": "openflow:6:1",
496             "ip": "192.168.50.75",
497             "port": 6633
498           },
499           {
500             "tunnel-type": "overlay:tunnel-type-vxlan",
501             "node-connector-id": "openflow:6:2",
502             "ip": "192.168.50.75",
503             "port": 4789
504           }
505         ]
506       }
507     ]
508 }
509
510 def get_tunnel_uri_6():
511     return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
512
513 def get_endpoint_data():
514     return [
515 {
516 "input": {
517
518     "endpoint-group": "webservers",
519
520     "network-containment" : "subnet-10.0.36.0/24",
521
522     "l2-context": "bridge-domain1",
523     "mac-address": "00:00:00:00:36:02",
524
525     "l3-address": [
526         {
527             "ip-address": "10.0.36.2",
528             "l3-context": "l3-context-vrf-red"
529         }
530     ],
531     "port-name": "vethl-h36_2",
532     "tenant": "tenant-dobre"
533 }
534 },
535 {
536 "input": {
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",
541 "l3-address": [
542     {
543         "ip-address": "10.0.35.2",
544         "l3-context": "l3-context-vrf-red"
545     }
546 ],
547 "port-name": "vethl-h35_2",
548 "tenant": "tenant-dobre"
549 }
550 },
551 {
552 "input": {
553
554     "endpoint-group": "clients",
555
556     "network-containment" : "subnet-10.0.35.0/24",
557
558     "l2-context": "bridge-domain1",
559     "mac-address": "00:00:00:00:35:03",
560
561     "l3-address": [
562         {
563             "ip-address": "10.0.35.3",
564             "l3-context": "l3-context-vrf-red"
565         }
566     ],
567     "port-name": "vethl-h35_3",
568     "tenant": "tenant-dobre"
569 }
570 },
571 {
572 "input": {
573
574     "endpoint-group": "webservers",
575
576     "network-containment" : "subnet-10.0.36.0/24",
577
578     "l2-context": "bridge-domain1",
579     "mac-address": "00:00:00:00:36:03",
580
581     "l3-address": [
582         {
583             "ip-address": "10.0.36.3",
584             "l3-context": "l3-context-vrf-red"
585         }
586     ],
587     "port-name": "vethl-h36_3",
588     "tenant": "tenant-dobre"
589 }
590 },
591 {
592 "input": {
593
594     "endpoint-group": "webservers",
595
596     "network-containment" : "subnet-10.0.36.0/24",
597
598     "l2-context": "bridge-domain1",
599     "mac-address": "00:00:00:00:36:04",
600
601     "l3-address": [
602         {
603             "ip-address": "10.0.36.4",
604             "l3-context": "l3-context-vrf-red"
605         }
606     ],
607     "port-name": "vethl-h36_4",
608     "tenant": "tenant-dobre"
609 }
610 },
611 {
612 "input": {
613
614     "endpoint-group": "clients",
615
616     "network-containment" : "subnet-10.0.35.0/24",
617
618     "l2-context": "bridge-domain1",
619     "mac-address": "00:00:00:00:35:04",
620
621     "l3-address": [
622         {
623             "ip-address": "10.0.35.4",
624             "l3-context": "l3-context-vrf-red"
625         }
626     ],
627     "port-name": "vethl-h35_4",
628     "tenant": "tenant-dobre"
629 }
630 },
631 {
632 "input": {
633
634     "endpoint-group": "clients",
635
636     "network-containment" : "subnet-10.0.35.0/24",
637
638     "l2-context": "bridge-domain1",
639     "mac-address": "00:00:00:00:35:05",
640
641     "l3-address": [
642         {
643             "ip-address": "10.0.35.5",
644             "l3-context": "l3-context-vrf-red"
645         }
646     ],
647     "port-name": "vethl-h35_5",
648     "tenant": "tenant-dobre"
649 }
650 },
651 {
652 "input": {
653
654     "endpoint-group": "webservers",
655
656     "network-containment" : "subnet-10.0.36.0/24",
657
658     "l2-context": "bridge-domain1",
659     "mac-address": "00:00:00:00:36:05",
660
661     "l3-address": [
662         {
663             "ip-address": "10.0.36.5",
664             "l3-context": "l3-context-vrf-red"
665         }
666     ],
667     "port-name": "vethl-h36_5",
668     "tenant": "tenant-dobre"
669 }
670 }]
671
672 def get_endpoint_uri():
673     return "/restconf/operations/endpoint:register-endpoint"
674
675 def get_tunnel_oper_uri():
676     return "/restconf/operational/opendaylight-inventory:nodes/"
677
678 def get_topology_oper_uri():
679     return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
680
681 if __name__ == "__main__":
682     # Launch main menu
683
684
685     # Some sensible defaults
686     controller=os.environ.get('ODL')
687     if controller == None:
688         sys.exit("No controller set.")
689
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)