1 #!/usr/local/bin/python
4 Copyright (c) 2013 Plexxi, Inc. All rights reserved.
6 This program and the accompanying materials are made available under the
7 terms of the Eclipse Public License v1.0 which accompanies this distribution,
8 and is available at http://www.eclipse.org/legal/epl-v10.html
16 from stats import Stats
17 from subnet import SubnetControl
18 from affinity_control import AffinityControl
20 # This class has nothing to do with the analytics API, but it makes
21 # adding flows *so* much easier.
24 def __init__(self, node, data):
25 self.node_id = node['id']
26 self.priority = data['priority']
27 self.ether_type = '0x800'
28 for match_field in data['match']['matchField']:
29 if match_field['type'] == 'DL_DST':
30 self.dl_dst = match_field['value']
31 elif match_field['type'] == 'IN_PORT':
32 self.in_port = match_field['value'].split('@')[0].split('|')[-1]
33 self.output_port = data['actions'][0]['port']['id']
35 def set_priority(self, priority):
36 self.priority = priority
38 def set_protocol(self, protocol):
39 self.protocol = protocol
41 def get_json(self, name):
42 json_data = {'installInHw' : 'true',
44 'node' : {'id' : self.node_id, 'type' : 'OF'},
45 'priority' : self.priority,
46 'etherType' : self.ether_type,
47 'dlDst' : self.dl_dst,
48 'ingressPort' : self.in_port,
49 'protocol' : self.protocol,
50 'actions' : ['OUTPUT=%s' % self.output_port]}
54 def rest_method(url, rest_type, payload=None):
55 if (rest_type == "GET"):
56 resp = requests.get(url, auth=('admin', 'admin'))
57 print "status:", resp.status_code
59 elif (rest_type == "PUT"):
60 headers = {'content-type': 'application/json'}
61 resp = requests.put(url, auth=('admin', 'admin'), data=json.dumps(payload), headers=headers)
62 print "status:", resp.status_code, resp.text
63 elif (rest_type == "DELETE"):
64 resp = requests.delete(url, auth=('admin', 'admin'))
65 print "status:", resp.status_code
70 def stats_hosts(src, dst):
71 url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s" % (src, dst)
72 data = rest_method(url, "GET")
73 print("%s bytes between %s and %s" % (data["byteCount"], src, dst))
74 print("%s bit/s between %s and %s" % (data["bitRate"], src, dst))
76 def stats_hosts_protocol(src, dst, protocol):
77 url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/%d" % (src, dst, protocol)
78 data = rest_method(url, "GET")
79 print("%s bytes between %s and %s for protocol %d" % (data["byteCount"], src, dst, protocol))
80 print("%s bit/s between %s and %s on protocol %d" % (data["bitRate"], src, dst, protocol))
82 def all_stats_hosts(src, dst):
83 url = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/%s/%s/all" % (src, dst)
84 data = rest_method(url, "GET")['stats']
86 print("%s bytes from protocol %s" % (entry['stat']['byteCount'], entry['protocol']))
87 print("%s bit/s from protocol %s" % (entry['stat']['bitRate'], entry['protocol']))
89 ### Affinity link statistics
92 url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s" % al
93 data = rest_method(url, "GET")
94 print("%s bytes on link %s" % (data['byteCount'], al))
95 print("%s bit/s on link %s" % (data['bitRate'], al))
97 def stats_link_protocol(al, protocol):
98 url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s/%s" % (al, protocol)
99 data = rest_method(url, "GET")
100 print("%s bytes on link %s for protocol %s" % (data['byteCount'], al, protocol))
101 print("%s bit/s on link %s for protocol %s" % (data['bitRate'], al, protocol))
103 def all_stats_link(al):
104 url = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/%s/all" % al
105 data = rest_method(url, "GET")['stats']
107 print("%s bytes from protocol %s" % (entry['stat']['byteCount'], entry['protocol']))
108 print("%s bit/s from protocol %s" % (entry['stat']['bitRate'], entry['protocol']))
110 ### Subnet statistics
112 def stats_subnet(src_sub, dst_sub):
113 url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s" % (src_sub, dst_sub)
114 data = rest_method(url, "GET")
115 if (src_sub == "null/null"):
116 print("%s bytes into %s" % (data['byteCount'], dst_sub))
117 print("%s bit/s into %s" % (data['bitRate'], dst_sub))
118 elif (dst_sub == "null/null"):
119 print("%s bytes out of %s" % (data['byteCount'], src_sub))
120 print("%s bit/s out of %s" % (data['bitRate'], src_sub))
122 print("%s bytes between %s and %s" % (data['byteCount'], src_sub, dst_sub))
123 print("%s bit/s between %s and %s" % (data['bitRate'], src_sub, dst_sub))
125 def stats_subnet_protocol(src_sub, dst_sub, protocol):
126 url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s/%s" % (src_sub, dst_sub, protocol)
127 data = rest_method(url, "GET")
128 if (src_sub == "null/null"):
129 print("%s bytes into %s from protocol %s" % (data['byteCount'], dst_sub, protocol))
130 print("%s bit/s into %s from protocol %s" % (data['bitRate'], dst_sub, protocol))
131 elif (dst_sub == "null/null"):
132 print("%s bytes out of %s from protocol %s" % (data['byteCount'], src_sub, protocol))
133 print("%s bit/s out of %s from protocol %s" % (data['bitRate'], src_sub, protocol))
135 print("%s bytes between %s and %s from protocol %s" % (data['byteCount'], src_sub, dst_sub, protocol))
136 print("%s bit/s between %s and %s from protocol %s" % (data['bitRate'], src_sub, dst_sub, protocol))
138 def all_stats_subnet(src_sub, dst_sub):
139 url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/%s/%s/all" % (src_sub, dst_sub)
140 data = rest_method(url, "GET")['stats']
142 print("%s bytes from protocol %s" % (entry['stat']['byteCount'], entry['protocol']))
143 print("%s bit/s from protocol %s" % (entry['stat']['bitRate'], entry['protocol']))
145 def incoming_hosts(subnet):
146 url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/incoming/%s" % subnet
147 data = rest_method(url, "GET")
148 data = rest_method(url, "GET")['stats']
149 if (type(data) == type({})):
152 print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
154 def incoming_hosts_protocol(subnet, protocol):
155 url = "http://localhost:8080/affinity/nb/v2/analytics/default/subnetstats/incoming/%s/%s" % (subnet, protocol)
156 data = rest_method(url, "GET")['data']['entry']
157 if (type(data) == type({})):
160 print("%s bytes from host %s" % (entry['byteCount'], entry['hostIP']))
162 # This is not part of the analytics NB API, but it is a necessary step
163 # if you want to monitor protocols
164 def add_protocol_flows():
165 protocols = [1, 6, 17] # ICMP, TCP, UDP
170 name = "flow" + str(i)
175 #### Flow control methods
178 url = "http://localhost:8080/controller/nb/v2/statistics/default/flow"
179 data = rest_method(url, "GET")
181 for item in data['flowStatistics']:
183 for item in item['flowStatistic']:
184 f = Flow(n, item['flow'])
188 def add_flow(flow, flow_name):
189 print "adding flow %s" % flow_name
190 url = "http://localhost:8080/controller/nb/v2/flowprogrammer/default/node/OF/%s/staticFlow/%s" % (flow.node_id, flow_name)
191 rest_method(url, "PUT", flow.get_json(flow_name))
193 #### End flow control methods
195 def run_interactive_mode():
197 print "Usage: [host | link | subnet] [src dst | link-name | src_sub dst_sub] {protocol}"
202 request = raw_input("> ")
203 request = request.split()
204 request_type = request[0]
206 if (request_type == "quit" or request_type == "exit"):
209 if (request_type == "host"):
210 if (len(request) == 3):
211 src, dst = request[1:3]
212 stats_hosts(src, dst)
213 all_stats_hosts(src, dst)
214 elif (len(request) == 4):
215 src, dst, protocol = request[1:4]
216 stats_hosts_protocol(src, dst, int(protocol))
218 elif (request_type == "link"):
219 if (len(request) == 2):
223 elif (len(request) == 3):
224 link, protocol = request[1:3]
225 stats_link_protocol(link, protocol)
227 elif (request_type == "subnet"):
228 if (len(request) == 3):
229 src_sub, dst_sub = request[1:3]
230 if src_sub == "null": src_sub = "null/null"
231 if dst_sub == "null": dst_sub = "null/null"
232 stats_subnet(src_sub, dst_sub)
233 all_stats_subnet(src_sub, dst_sub)
234 elif (len(request) == 4):
235 src_sub, dst_sub, protocol = request[1:4]
236 if src_sub == "null": src_sub = "null/null"
237 if dst_sub == "null": dst_sub = "null/null"
238 stats_subnet_protocol(src_sub, dst_sub, protocol)
242 # Default subnet is required for the host tracker to work.
243 subnet_control = SubnetControl()
244 subnet_control.add_subnet("defaultSubnet", "10.0.0.254/8")
246 # Set up an affinity link
247 affinity_control = AffinityControl()
248 affinity_control.add_affinity_group("testAG1", ips=["10.0.0.1", "10.0.0.2"])
249 affinity_control.add_affinity_group("testAG2", ips=["10.0.0.3", "10.0.0.4"])
250 affinity_control.add_affinity_link("testAL", "testAG1", "testAG2")
252 raw_input("press enter ")
255 run_interactive_mode()
257 if __name__ == "__main__":