blob: 7b900384f690ffa32c1e4ce742b1545543ccf678 [file] [log] [blame]
Zsolt Harasztia133a452016-12-22 01:26:57 -08001#!/usr/bin/env python
2#
3# Copyright 2016 the original author or authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17import sys
18from cmd2 import Cmd, make_option, options
19import readline
20import grpc
21from simplejson import dumps
22
23from voltha.protos import third_party
24from voltha.protos import voltha_pb2
25from google.protobuf.empty_pb2 import Empty
26from google.protobuf.json_format import MessageToDict
27_ = third_party
28from cli.utils import print_flows
29
30
31def pb2dict(pb_msg):
32 d = MessageToDict(pb_msg, including_default_value_fields=1,
33 preserving_proto_field_name=1)
34 return d
35
36
37class VolthaCli(Cmd):
38
39 prompt = 'voltha'
40 history_file_name = '.voltha_cli_history'
41 max_history_lines = 500
42
43 Cmd.settable.update(dict(
44 voltha_grpc='Voltha GRPC endpoint in form of <host>:<port>'
45 ))
46
47 voltha_grpc = 'localhost:50055'
48
49 def __init__(self, *args, **kw):
50 Cmd.__init__(self, *args, **kw)
51 self.prompt = '(' + self.colorize(
52 self.colorize(self.prompt, 'red'), 'bold') + ') '
53 self.channel = None
54
55 def load_history(self):
56 """Load saved command history from local history file"""
57 try:
58 with file(self.history_file_name, 'r') as f:
59 for line in f.readlines():
60 stripped_line = line.strip()
61 self.history.append(stripped_line)
62 readline.add_history(stripped_line)
63 except IOError:
64 pass # ignore if file cannot be read
65
66 def save_history(self):
67 try:
68 with file(self.history_file_name, 'w') as f:
69 f.write('\n'.join(self.history[-self.max_history_lines:]))
70 except IOError, e:
71 print >> sys.stderr, 'Could not save history in {}: {}'.format(
72 self.history_file_name, e.msg)
73 else:
74 print >> sys.stderr, 'History saved as {}'.format(
75 self.history_file_name)
76
77 def get_channel(self):
78 if self.channel is None:
79 self.channel = grpc.insecure_channel(self.voltha_grpc)
80 return self.channel
81
82 def do_reset_history(self, arg):
83 """Reset CLI history"""
84 while self.history:
85 self.history.pop()
86
87 def do_launch(self, arg):
88 """If Voltha is not running yet, launch it"""
89 pass
90
91 def do_restart(self, arg):
92 """Launch Voltha, but if it is already running, terminate it first"""
93 pass
94
95 def do_devices(self, arg):
96 """List devices registered in Voltha"""
97 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
98 res = stub.ListDevices(Empty())
99 for device in res.items:
100 print self.colorize('# ====== device {}'.format(device.id), 'blue')
101 print dumps(pb2dict(device), indent=4, sort_keys=True)
102
103 def do_logical_devices(self, arg):
104 """List logical devices in Voltha"""
105 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
106 res = stub.ListLogicalDevices(Empty())
107 for logical_device in res.items:
108 print self.colorize('# ====== logical device {}'.format(
109 logical_device.id), 'blue')
110 print dumps(pb2dict(logical_device), indent=4, sort_keys=True)
111
112 def do_device(self, arg):
113 """Enter device level command mode"""
114 sub = DeviceCli(self.get_channel, arg)
115 sub.cmdloop()
116
117 def do_logical_device(self, arg):
118 """Enter logical device level command mode"""
119 sub = LogicalDeviceCli(self.get_channel, arg)
120 sub.cmdloop()
121
122 def do_debug(self, arg):
123 """Launch PDB debug prompt in CLI (for CLI development)"""
124 from pdb import set_trace
125 set_trace()
126
127 def do_health(self, arg):
128 """Show connectivity status to Voltha status"""
129 stub = voltha_pb2.HealthServiceStub(self.get_channel())
130 res = stub.GetHealthStatus(Empty())
131 print dumps(pb2dict(res), indent=4)
132
133
134class DeviceCli(Cmd):
135
136 def __init__(self, get_channel, device_id):
137 Cmd.__init__(self)
138 self.get_channel = get_channel
139 self.device_id = device_id
140 self.prompt = '(' + self.colorize(
141 self.colorize('device {}'.format(device_id), 'red'), 'bold') + ') '
142
143 def get_device(self, depth=0):
144 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
145 res = stub.GetDevice(voltha_pb2.ID(id=self.device_id),
146 metadata=(('get-depth', str(depth)), ))
147 return res
148
149 def do_show(self, arg):
150 """Show detailed device information"""
151 print dumps(pb2dict(self.get_device(depth=-1)),
152 indent=4, sort_keys=True)
153
154 def do_flows(self, arg):
155 """Show flow table for device"""
156 device = pb2dict(self.get_device(-1))
157 print_flows(
158 'Device',
159 self.device_id,
160 type=device['type'],
161 flows=device['flows']['items'],
162 groups=device['flow_groups']['items']
163 )
164
165
166class LogicalDeviceCli(Cmd):
167
168 def __init__(self, get_channel, logical_device_id):
169 Cmd.__init__(self)
170 self.get_channel = get_channel
171 self.logical_device_id = logical_device_id
172 self.prompt = '(' + self.colorize(
173 self.colorize('device {}'.format(logical_device_id), 'red'),
174 'bold') + ') '
175
176 def get_logical_device(self, depth=0):
177 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
178 res = stub.GetLogicalDevice(voltha_pb2.ID(id=self.logical_device_id),
179 metadata=(('get-depth', str(depth)), ))
180 return res
181
182 def do_show(self, arg):
183 """Show detailed logical device information"""
184 print dumps(pb2dict(self.get_logical_device(depth=-1)),
185 indent=4, sort_keys=True)
186
187 def do_flows(self, arg):
188 """Show flow table for logical device"""
189 logical_device = pb2dict(self.get_logical_device(-1))
190 print_flows(
191 'Logical Device',
192 self.logical_device_id,
193 type='n/a',
194 flows=logical_device['flows']['items'],
195 groups=logical_device['flow_groups']['items']
196 )
197
198
199if __name__ == '__main__':
200 c = VolthaCli()
201 c.load_history()
202 c.cmdloop()
203 c.save_history()