Switch to use new ovs nsh version
[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                             "exts": "gpe",
144                             "remote-ip": "flow",
145                             "dst-port": "6633",
146                             "key": "flow",
147                             "nsp": "flow",
148                             "nsi": "flow",
149                             "nshc1": "flow",
150                             "nshc2": "flow",
151                             "nshc3": "flow",
152                             "nshc4": "flow"
153                         }
154                     }
155                 ]
156             },
157             {
158                 "name": "SFF2",
159                 "service-node": "OVSDB2",
160                 "service-function-forwarder-ovs:ovs-bridge": {
161                     "bridge-name": "sw4"
162                 },
163                 "service-function-dictionary": [
164                     {
165                         "name": "dpi-74",
166                         "sff-sf-data-plane-locator": {
167                             "sf-dpl-name": "3",
168                             "sff-dpl-name": "sfc-tun4"
169                         }
170                     }
171                 ],
172                 "sff-data-plane-locator": [
173                     {
174                         "name": "sfc-tun4",
175                         "data-plane-locator": {
176                             "transport": "service-locator:vxlan-gpe",
177                             "port": 6633,
178                             "ip": "192.168.50.73"
179                         },
180                         "service-function-forwarder-ovs:ovs-options": {
181                             "exts": "gpe",
182                             "remote-ip": "flow",
183                             "dst-port": "6633",
184                             "key": "flow",
185                             "nsp": "flow",
186                             "nsi": "flow",
187                             "nshc1": "flow",
188                             "nshc2": "flow",
189                             "nshc3": "flow",
190                             "nshc4": "flow"
191                         }
192                     }
193                 ]
194             }
195         ]
196     }
197 }
198
199 def get_service_function_chains_uri():
200     return "/restconf/config/service-function-chain:service-function-chains/"
201
202 def get_service_function_chains_data():
203     return {
204     "service-function-chains": {
205         "service-function-chain": [
206             {
207                 "name": "SFCGBP",
208                 "symmetric": "true",
209                 "sfc-service-function": [
210                     {
211                         "name": "firewall-abstract1",
212                         "type": "service-function-type:firewall"
213                     },
214                     {
215                         "name": "dpi-abstract1",
216                         "type": "service-function-type:dpi"
217                     }
218                 ]
219             }
220         ]
221     }
222 }
223
224 def get_service_function_paths_uri():
225     return "/restconf/config/service-function-path:service-function-paths/"
226
227 def get_service_function_paths_data():
228     return {
229     "service-function-paths": {
230         "service-function-path": [
231             {
232                 "name": "SFCGBP-Path",
233                 "service-chain-name": "SFCGBP",
234                 "starting-index": 255,
235                 "symmetric": "true"
236
237             }
238         ]
239     }
240 }
241
242 def get_tenant_data():
243     return {
244         "tenant": [
245           {
246             "id": "tenant-red",
247             "name": "DockerTenant",
248             "forwarding-context": {
249               "l2-flood-domain": [
250                 {
251                   "id": "flood-domain-1",
252                   "parent": "bridge-domain1"
253                 },
254                 {
255                   "id": "flood-domain-2",
256                   "parent": "bridge-domain1"
257                 }
258               ],
259               "l3-context": [
260                 {
261                   "id": "l3-context-vrf-red"
262                 }
263               ],
264               "l2-bridge-domain": [
265                 {
266                   "id": "bridge-domain1",
267                   "parent": "l3-context-vrf-red"
268                 }
269               ],
270               "subnet": [
271                 {
272                   "id": "subnet-10.0.36.0/24",
273                   "virtual-router-ip": "10.0.36.1",
274                   "parent": "flood-domain-2",
275                   "ip-prefix": "10.0.36.1/24"
276                 },
277                 {
278                   "id": "subnet-10.0.35.0/24",
279                   "virtual-router-ip": "10.0.35.1",
280                   "parent": "flood-domain-1",
281                   "ip-prefix": "10.0.35.1/24"
282                 }
283               ]
284             },
285             "policy": {
286               "endpoint-group": [
287                 {
288                   "id": "webservers",
289                   "name": "webservers",
290                   "provider-named-selector": [
291                     {
292                       "name": "webservers-clients-icmp-http-contract",
293                       "contract": [
294                         "icmp-http-contract"
295                       ]
296                     }
297                   ]
298                 },
299                 {
300                   "id": "clients",
301                   "name": "clients",
302                   "consumer-named-selector": [
303                     {
304                       "name": "webservers-clients-icmp-http-contract",
305                       "contract": [
306                         "icmp-http-contract"
307                       ]
308                     }
309                   ]
310                 }
311               ],
312               "subject-feature-instances": {
313                 "classifier-instance": [
314                   {
315                     "name": "icmp",
316                     "classifier-definition-id": "Classifier-IP-Protocol",
317                     "parameter-value": [
318                       {
319                         "name": "proto",
320                         "int-value": 1
321                       }
322                     ]
323                   },
324                   {
325                     "name": "http-dest",
326                     "classifier-definition-id": "Classifier-L4",
327                     "parameter-value": [
328                       {
329                         "int-value": "6",
330                         "name": "proto"
331                       },
332                       {
333                         "int-value": "80",
334                         "name": "destport"
335                       }
336                     ]
337                   },
338                   {
339                     "name": "http-src",
340                     "classifier-definition-id": "Classifier-L4",
341                     "parameter-value": [
342                       {
343                         "int-value": "6",
344                         "name": "proto"
345                       },
346                       {
347                         "int-value": "80",
348                         "name": "sourceport"
349                       }
350                     ]
351                   }
352                 ],
353                 "action-instance": [
354                   {
355                     "name": "chain1",
356                     "action-definition-id": "Action-Chain",
357                     "parameter-value": [
358                       {
359                         "name": "sfc-chain-name",
360                         "string-value": "SFCGBP"
361                       }
362                     ]
363                   },
364                   {
365                     "name": "allow1",
366                     "action-definition-id": "Action-Allow"
367                   }
368                 ]
369               },
370               "contract": [
371                 {
372                   "id": "icmp-http-contract",
373                   "subject": [
374                     {
375                       "name": "icmp-subject",
376                       "rule": [
377                         {
378                           "name": "allow-icmp-rule",
379                           "order": 0,
380                           "classifier-ref": [
381                             {
382                               "name": "icmp-in",
383                               "instance-name": "icmp",
384                               "direction": "in"
385                             },
386                             {
387                               "name": "icmp-out",
388                               "instance-name": "icmp",
389                               "direction": "out"
390                             }
391                           ],
392                           "action-ref": [
393                             {
394                               "name": "allow1",
395                               "order": 0
396                             }
397                           ]
398                         }
399                       ]
400                     },
401                     {
402                       "name": "http-subject",
403                       "rule": [
404                         {
405                           "name": "http-chain-rule-in",
406                           "classifier-ref": [
407                             {
408                               "name": "http-dest",
409                               "instance-name": "http-dest",
410                               "direction": "in"
411                             }
412                           ],
413                           "action-ref": [
414                             {
415                               "name": "chain1",
416                               "order": 0
417                             }
418                           ]
419                         },
420                         {
421                           "name": "http-chain-rule-out",
422                           "classifier-ref": [
423                             {
424                               "name": "http-src",
425                               "instance-name": "http-src",
426                               "direction": "out"
427                             }
428                           ],
429                           "action-ref": [
430                             {
431                               "name": "chain1",
432                               "order": 0
433                             }
434                           ]
435                         }
436                       ]
437                     }
438                   ],
439                   "clause": [
440                     {
441                       "name": "icmp-http-clause",
442                       "subject-refs": [
443                         "icmp-subject",
444                         "http-subject"
445                       ]
446                     }
447                   ]
448                 }
449               ]
450             }
451           }
452         ]
453     }
454
455 # Main definition - constants
456
457 # =======================
458 #     MENUS FUNCTIONS
459 # =======================
460
461 # Main menu
462
463 # =======================
464 #      MAIN PROGRAM
465 # =======================
466
467 # Main Program
468
469 def get_tenant_uri():
470     return "/restconf/config/policy:tenants/policy:tenant/tenant-red"
471
472 def get_tunnel_data_1():
473     return {
474     "node": [
475       {
476         "id": "openflow:1",
477         "ofoverlay:tunnel": [
478           {
479             "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
480             "node-connector-id": "openflow:1:1",
481             "ip": "192.168.50.70",
482             "port": 6633
483           },
484           {
485             "tunnel-type": "overlay:tunnel-type-vxlan",
486             "node-connector-id": "openflow:1:2",
487             "ip": "192.168.50.70",
488             "port": 4789
489           }
490         ]
491       }
492     ]
493   }
494
495 def get_tunnel_uri_1():
496     return "/restconf/config/opendaylight-inventory:nodes/node/openflow:1"
497
498 def get_tunnel_data_6():
499     return {
500     "node": [
501       {
502         "id": "openflow:6",
503         "ofoverlay:tunnel": [
504           {
505             "tunnel-type": "overlay:tunnel-type-vxlan-gpe",
506             "node-connector-id": "openflow:6:1",
507             "ip": "192.168.50.75",
508             "port": 6633
509           },
510           {
511             "tunnel-type": "overlay:tunnel-type-vxlan",
512             "node-connector-id": "openflow:6:2",
513             "ip": "192.168.50.75",
514             "port": 4789
515           }
516         ]
517       }
518     ]
519 }
520
521 def get_tunnel_uri_6():
522     return "/restconf/config/opendaylight-inventory:nodes/node/openflow:6"
523
524 def get_endpoint_data():
525     return [
526 {
527 "input": {
528
529     "endpoint-group": "webservers",
530
531     "network-containment" : "subnet-10.0.36.0/24",
532
533     "l2-context": "bridge-domain1",
534     "mac-address": "00:00:00:00:36:02",
535
536     "l3-address": [
537         {
538             "ip-address": "10.0.36.2",
539             "l3-context": "l3-context-vrf-red"
540         }
541     ],
542     "port-name": "vethl-h36-2",
543     "tenant": "tenant-red"
544 }
545 },
546 {
547 "input": {
548     "endpoint-group": "clients",
549 "network-containment" : "subnet-10.0.35.0/24",
550 "l2-context": "bridge-domain1",
551 "mac-address": "00:00:00:00:35:02",
552 "l3-address": [
553     {
554         "ip-address": "10.0.35.2",
555         "l3-context": "l3-context-vrf-red"
556     }
557 ],
558 "port-name": "vethl-h35-2",
559 "tenant": "tenant-red"
560 }
561 },
562 {
563 "input": {
564
565     "endpoint-group": "clients",
566
567     "network-containment" : "subnet-10.0.35.0/24",
568
569     "l2-context": "bridge-domain1",
570     "mac-address": "00:00:00:00:35:03",
571
572     "l3-address": [
573         {
574             "ip-address": "10.0.35.3",
575             "l3-context": "l3-context-vrf-red"
576         }
577     ],
578     "port-name": "vethl-h35-3",
579     "tenant": "tenant-red"
580 }
581 },
582 {
583 "input": {
584
585     "endpoint-group": "webservers",
586
587     "network-containment" : "subnet-10.0.36.0/24",
588
589     "l2-context": "bridge-domain1",
590     "mac-address": "00:00:00:00:36:03",
591
592     "l3-address": [
593         {
594             "ip-address": "10.0.36.3",
595             "l3-context": "l3-context-vrf-red"
596         }
597     ],
598     "port-name": "vethl-h36-3",
599     "tenant": "tenant-red"
600 }
601 },
602 {
603 "input": {
604
605     "endpoint-group": "webservers",
606
607     "network-containment" : "subnet-10.0.36.0/24",
608
609     "l2-context": "bridge-domain1",
610     "mac-address": "00:00:00:00:36:04",
611
612     "l3-address": [
613         {
614             "ip-address": "10.0.36.4",
615             "l3-context": "l3-context-vrf-red"
616         }
617     ],
618     "port-name": "vethl-h36-4",
619     "tenant": "tenant-red"
620 }
621 },
622 {
623 "input": {
624
625     "endpoint-group": "clients",
626
627     "network-containment" : "subnet-10.0.35.0/24",
628
629     "l2-context": "bridge-domain1",
630     "mac-address": "00:00:00:00:35:04",
631
632     "l3-address": [
633         {
634             "ip-address": "10.0.35.4",
635             "l3-context": "l3-context-vrf-red"
636         }
637     ],
638     "port-name": "vethl-h35-4",
639     "tenant": "tenant-red"
640 }
641 },
642 {
643 "input": {
644
645     "endpoint-group": "clients",
646
647     "network-containment" : "subnet-10.0.35.0/24",
648
649     "l2-context": "bridge-domain1",
650     "mac-address": "00:00:00:00:35:05",
651
652     "l3-address": [
653         {
654             "ip-address": "10.0.35.5",
655             "l3-context": "l3-context-vrf-red"
656         }
657     ],
658     "port-name": "vethl-h35-5",
659     "tenant": "tenant-red"
660 }
661 },
662 {
663 "input": {
664
665     "endpoint-group": "webservers",
666
667     "network-containment" : "subnet-10.0.36.0/24",
668
669     "l2-context": "bridge-domain1",
670     "mac-address": "00:00:00:00:36:05",
671
672     "l3-address": [
673         {
674             "ip-address": "10.0.36.5",
675             "l3-context": "l3-context-vrf-red"
676         }
677     ],
678     "port-name": "vethl-h36-5",
679     "tenant": "tenant-red"
680 }
681 }]
682
683 def get_endpoint_uri():
684     return "/restconf/operations/endpoint:register-endpoint"
685
686 def get_tunnel_oper_uri():
687     return "/restconf/operational/opendaylight-inventory:nodes/"
688
689 def get_topology_oper_uri():
690     return "/restconf/operational/network-topology:network-topology/topology/ovsdb:1/"
691
692 if __name__ == "__main__":
693     # Launch main menu
694
695
696     # Some sensible defaults
697     controller=os.environ.get('ODL')
698     if controller == None:
699         sys.exit("No controller set.")
700
701     print "Contacting controller at %s" % controller
702     print "waiting for manager on SFFs..."
703     wait_for_sff_in_datastore(get_topology_oper_uri())
704     print "sending service functions"
705     put(controller, DEFAULT_PORT, get_service_functions_uri(), get_service_functions_data(), True)
706     print "sending service function forwarders"
707     put(controller, DEFAULT_PORT, get_service_function_forwarders_uri(), get_service_function_forwarders_data(), True)
708     print "waiting for switches on SFFs..."
709     wait_for_sff_in_datastore(get_tunnel_oper_uri())
710     print "sending service function chains"
711     put(controller, DEFAULT_PORT, get_service_function_chains_uri(), get_service_function_chains_data(), True)
712     print "sending service function paths"
713     put(controller, DEFAULT_PORT, get_service_function_paths_uri(), get_service_function_paths_data(), True)
714     print "sending tunnel"
715     put(controller, DEFAULT_PORT, get_tunnel_uri_1(), get_tunnel_data_1(), True)
716     print "sending tenant"
717     put(controller, DEFAULT_PORT, get_tunnel_uri_6(), get_tunnel_data_6(), True)
718     print "sending tenant"
719     put(controller, DEFAULT_PORT, get_tenant_uri(), get_tenant_data(),True)
720     print "registering endpoints"
721     for endpoint in get_endpoint_data():
722         post(controller, DEFAULT_PORT, get_endpoint_uri(),endpoint,True)