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