blob: 3a30a0dc8a21aaea9a0c798c05a6c01bbfc6e668 [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#
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080017import argparse
18import os
Zsolt Harasztia133a452016-12-22 01:26:57 -080019import readline
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040020import sys
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080021from optparse import make_option
Zsolt Haraszti80175202016-12-24 00:17:51 -080022from time import sleep, time
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080023
ntoorchi9cb00a72019-07-17 10:43:54 -070024import etcd3
Zsolt Harasztia133a452016-12-22 01:26:57 -080025import grpc
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080026import requests
27from cmd2 import Cmd, options
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040028from consul import Consul
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080029from google.protobuf.empty_pb2 import Empty
Zsolt Harasztia133a452016-12-22 01:26:57 -080030from simplejson import dumps
31
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080032from cli.device import DeviceCli
Nikolay Titov89004ec2017-06-19 18:22:42 -040033from cli.xpon import XponCli
Chip Boling69abce82018-06-18 09:56:23 -050034from cli.omci import OmciCli
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040035from cli.alarm_filters import AlarmFiltersCli
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080036from cli.logical_device import LogicalDeviceCli
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040037from cli.table import print_pb_list_as_table
Zsolt Harasztia133a452016-12-22 01:26:57 -080038from voltha.protos import third_party
Scott Bakerd865fa22018-11-07 11:45:28 -080039from voltha.protos import voltha_pb2, voltha_pb2_grpc, health_pb2_grpc
Zsolt Haraszti85f12852016-12-24 08:30:58 -080040from voltha.protos.openflow_13_pb2 import FlowTableUpdate, FlowGroupTableUpdate
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080041
Zsolt Harasztia133a452016-12-22 01:26:57 -080042_ = third_party
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040043from cli.utils import pb2dict
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080044
45defs = dict(
46 # config=os.environ.get('CONFIG', './cli.yml'),
ntoorchi9cb00a72019-07-17 10:43:54 -070047 etcd=os.environ.get('ETCD', 'etcd-cluster.default.svc.cluster.local:2379'),
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080048 consul=os.environ.get('CONSUL', 'localhost:8500'),
49 voltha_grpc_endpoint=os.environ.get('VOLTHA_GRPC_ENDPOINT',
50 'localhost:50055'),
51 voltha_sim_rest_endpoint=os.environ.get('VOLTHA_SIM_REST_ENDPOINT',
52 'localhost:18880'),
khenaidoo108f05c2017-07-06 11:15:29 -040053 global_request=os.environ.get('GLOBAL_REQUEST', False)
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080054)
55
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080056banner = """\
Zsolt Haraszti313c4be2016-12-27 11:06:53 -080057 _ _ _ ___ _ ___
58__ _____| | |_| |_ __ _ / __| | |_ _|
59\ V / _ \ | _| ' \/ _` | | (__| |__ | |
60 \_/\___/_|\__|_||_\__,_| \___|____|___|
ntoorchi9cb00a72019-07-17 10:43:54 -070061(to exit type quit or exit or hit Ctrl-D)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080062"""
Zsolt Harasztia133a452016-12-22 01:26:57 -080063
Zsolt Harasztia133a452016-12-22 01:26:57 -080064
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040065class VolthaCli(Cmd):
Zsolt Harasztia133a452016-12-22 01:26:57 -080066 prompt = 'voltha'
67 history_file_name = '.voltha_cli_history'
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080068
69 # Settable CLI parameters
70 voltha_grpc = 'localhost:50055'
71 voltha_sim_rest = 'localhost:18880'
khenaidoo108f05c2017-07-06 11:15:29 -040072 global_request = False
Zsolt Harasztia133a452016-12-22 01:26:57 -080073 max_history_lines = 500
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080074 default_device_id = None
75 default_logical_device_id = None
Zsolt Harasztia133a452016-12-22 01:26:57 -080076
77 Cmd.settable.update(dict(
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080078 voltha_grpc='Voltha GRPC endpoint in form of <host>:<port>',
79 voltha_sim_rest='Voltha simulation back door for testing in form '
80 'of <host>:<port>',
81 max_history_lines='Maximum number of history lines stored across '
82 'sessions',
83 default_device_id='Device id used when no device id is specified',
84 default_logical_device_id='Logical device id used when no device id '
85 'is specified',
Zsolt Harasztia133a452016-12-22 01:26:57 -080086 ))
87
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080088 # cleanup of superfluous commands from cmd2
Zsolt Haraszti80175202016-12-24 00:17:51 -080089 del Cmd.do_cmdenvironment
Steve Crooks05f24522017-02-27 13:32:27 -050090 del Cmd.do_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080091 del Cmd.do__relative_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080092
ntoorchi9cb00a72019-07-17 10:43:54 -070093 def __init__(self, voltha_grpc, voltha_sim_rest, etcd, global_request=False):
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080094 VolthaCli.voltha_grpc = voltha_grpc
95 VolthaCli.voltha_sim_rest = voltha_sim_rest
khenaidoo108f05c2017-07-06 11:15:29 -040096 VolthaCli.global_request = global_request
ntoorchi9cb00a72019-07-17 10:43:54 -070097 VolthaCli.etcd = etcd
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080098 Cmd.__init__(self)
Zsolt Harasztia133a452016-12-22 01:26:57 -080099 self.prompt = '(' + self.colorize(
Zsolt Haraszti80175202016-12-24 00:17:51 -0800100 self.colorize(self.prompt, 'blue'), 'bold') + ') '
Zsolt Harasztia133a452016-12-22 01:26:57 -0800101 self.channel = None
khenaidoo108f05c2017-07-06 11:15:29 -0400102 self.stub = None
Zsolt Haraszti80175202016-12-24 00:17:51 -0800103 self.device_ids_cache = None
104 self.device_ids_cache_ts = time()
105 self.logical_device_ids_cache = None
106 self.logical_device_ids_cache_ts = time()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800107
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800108 # we override cmd2's method to avoid its optparse conflicting with our
109 # command line parsing
110 def cmdloop(self):
111 self._cmdloop()
112
Zsolt Harasztia133a452016-12-22 01:26:57 -0800113 def load_history(self):
114 """Load saved command history from local history file"""
115 try:
116 with file(self.history_file_name, 'r') as f:
117 for line in f.readlines():
118 stripped_line = line.strip()
119 self.history.append(stripped_line)
120 readline.add_history(stripped_line)
121 except IOError:
122 pass # ignore if file cannot be read
123
124 def save_history(self):
125 try:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800126 with open(self.history_file_name, 'w') as f:
Zsolt Harasztia133a452016-12-22 01:26:57 -0800127 f.write('\n'.join(self.history[-self.max_history_lines:]))
Zsolt Haraszti80175202016-12-24 00:17:51 -0800128 except IOError as e:
129 self.perror('Could not save history in {}: {}'.format(
130 self.history_file_name, e))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800131 else:
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800132 self.poutput('History saved as {}'.format(
Zsolt Haraszti80175202016-12-24 00:17:51 -0800133 self.history_file_name))
134
135 def perror(self, errmsg, statement=None):
136 # Touch it up to make sure error is prefixed and colored
137 Cmd.perror(self, self.colorize('***ERROR: ', 'red') + errmsg,
138 statement)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800139
140 def get_channel(self):
141 if self.channel is None:
142 self.channel = grpc.insecure_channel(self.voltha_grpc)
143 return self.channel
144
khenaidoo108f05c2017-07-06 11:15:29 -0400145 def get_stub(self):
146 if self.stub is None:
147 self.stub = \
Scott Bakerd865fa22018-11-07 11:45:28 -0800148 voltha_pb2_grpc.VolthaGlobalServiceStub(self.get_channel()) \
khenaidoo108f05c2017-07-06 11:15:29 -0400149 if self.global_request else \
Scott Bakerd865fa22018-11-07 11:45:28 -0800150 voltha_pb2_grpc.VolthaLocalServiceStub(self.get_channel())
khenaidoo108f05c2017-07-06 11:15:29 -0400151 return self.stub
152
Zsolt Haraszti80175202016-12-24 00:17:51 -0800153 # ~~~~~~~~~~~~~~~~~ ACTUAL COMMAND IMPLEMENTATIONS ~~~~~~~~~~~~~~~~~~~~~~~~
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800154
Zsolt Haraszti80175202016-12-24 00:17:51 -0800155 def do_reset_history(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800156 """Reset CLI history"""
157 while self.history:
158 self.history.pop()
159
ntoorchi9cb00a72019-07-17 10:43:54 -0700160 def do_exit(self,line):
161 """exit from CLI"""
162 quit()
163
Zsolt Haraszti80175202016-12-24 00:17:51 -0800164 def do_launch(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800165 """If Voltha is not running yet, launch it"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800166 raise NotImplementedError('not implemented yet')
Zsolt Harasztia133a452016-12-22 01:26:57 -0800167
Zsolt Haraszti80175202016-12-24 00:17:51 -0800168 def do_restart(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800169 """Launch Voltha, but if it is already running, terminate it first"""
170 pass
171
Zsolt Haraszti80175202016-12-24 00:17:51 -0800172 def do_adapters(self, line):
173 """List loaded adapter"""
khenaidoo108f05c2017-07-06 11:15:29 -0400174 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800175 res = stub.ListAdapters(Empty())
Sergio Slobodrian6e9fb692017-03-17 14:46:33 -0400176 omit_fields = {'config.log_level', 'logical_device_ids'}
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800177 print_pb_list_as_table('Adapters:', res.items, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800178
179 def get_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400180 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800181 res = stub.ListDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800182 return res.items
Zsolt Harasztia133a452016-12-22 01:26:57 -0800183
Zsolt Haraszti80175202016-12-24 00:17:51 -0800184 def get_logical_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400185 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800186 res = stub.ListLogicalDevices(Empty())
187 return res.items
188
189 def do_devices(self, line):
190 """List devices registered in Voltha"""
191 devices = self.get_devices()
192 omit_fields = {
193 'adapter',
194 'vendor',
195 'model',
196 'hardware_version',
ggowdru236bd952017-06-20 20:32:55 -0700197 'images',
Zsolt Haraszti80175202016-12-24 00:17:51 -0800198 'firmware_version',
Nicolas Palpacuerb83853e2018-06-28 16:11:30 -0400199 'vendor_id'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800200 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800201 print_pb_list_as_table('Devices:', devices, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800202
203 def do_logical_devices(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800204 """List logical devices in Voltha"""
khenaidoo108f05c2017-07-06 11:15:29 -0400205 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800206 res = stub.ListLogicalDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800207 omit_fields = {
208 'desc.mfr_desc',
209 'desc.hw_desc',
210 'desc.sw_desc',
211 'desc.dp_desc',
212 'desc.serial_number',
Sergio Slobodriana95f99b2017-03-21 10:22:47 -0400213 'switch_features.capabilities'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800214 }
Jonathan Hart7d4a23d2018-06-28 07:36:28 -0700215 presfns = {
216 'datapath_id': lambda x: "{0:0{1}x}".format(int(x), 16)
217 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800218 print_pb_list_as_table('Logical devices:', res.items, omit_fields,
Jonathan Hart7d4a23d2018-06-28 07:36:28 -0700219 self.poutput, presfns=presfns)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800220
Zsolt Haraszti80175202016-12-24 00:17:51 -0800221 def do_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800222 """Enter device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800223 device_id = line.strip() or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800224 if not device_id:
225 raise Exception('<device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500226 if device_id not in self.device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500227 self.poutput( self.colorize('Error: ', 'red') +
228 'There is no such device')
229 raise Exception('<device-id> is not a valid one')
ntoorchi9cb00a72019-07-17 10:43:54 -0700230 sub = DeviceCli(device_id, self.get_stub, self.etcd)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800231 sub.cmdloop()
232
Zsolt Haraszti80175202016-12-24 00:17:51 -0800233 def do_logical_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800234 """Enter logical device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800235 logical_device_id = line.strip() or self.default_logical_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800236 if not logical_device_id:
237 raise Exception('<logical-device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500238 if logical_device_id not in self.logical_device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500239 self.poutput( self.colorize('Error: ', 'red') +
240 'There is no such device')
241 raise Exception('<logical-device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400242 sub = LogicalDeviceCli(logical_device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800243 sub.cmdloop()
244
Zsolt Haraszti80175202016-12-24 00:17:51 -0800245 def device_ids(self, force_refresh=False):
246 if force_refresh or self.device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400247 (time() - self.device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800248 self.device_ids_cache = [d.id for d in self.get_devices()]
249 self.device_ids_cache_ts = time()
250 return self.device_ids_cache
251
252 def logical_device_ids(self, force_refresh=False):
253 if force_refresh or self.logical_device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400254 (time() - self.logical_device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800255 self.logical_device_ids_cache = [d.id for d
256 in self.get_logical_devices()]
257 self.logical_device_ids_cache_ts = time()
258 return self.logical_device_ids_cache
259
260 def complete_device(self, text, line, begidx, endidx):
261 if not text:
262 completions = self.device_ids()[:]
263 else:
264 completions = [d for d in self.device_ids() if d.startswith(text)]
265 return completions
266
267 def complete_logical_device(self, text, line, begidx, endidx):
268 if not text:
269 completions = self.logical_device_ids()[:]
270 else:
271 completions = [d for d in self.logical_device_ids()
272 if d.startswith(text)]
273 return completions
274
Nikolay Titov89004ec2017-06-19 18:22:42 -0400275 def do_xpon(self, line):
276 """xpon <optional> [device_ID] - Enter xpon level command mode"""
277 device_id = line.strip()
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400278 if device_id:
279 stub = self.get_stub()
280 try:
281 res = stub.GetDevice(voltha_pb2.ID(id=device_id))
282 except Exception:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400283 self.poutput(
284 self.colorize('Error: ', 'red') + 'No device id ' +
285 self.colorize(device_id, 'blue') + ' is found')
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400286 return
287 sub = XponCli(self.get_channel, device_id)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400288 sub.cmdloop()
289
Chip Boling69abce82018-06-18 09:56:23 -0500290 def do_omci(self, line):
291 """omci <device_ID> - Enter OMCI level command mode"""
292
293 device_id = line.strip() or self.default_device_id
294 if not device_id:
295 raise Exception('<device-id> parameter needed')
296 sub = OmciCli(device_id, self.get_stub)
297 sub.cmdloop()
298
Zsolt Haraszti80175202016-12-24 00:17:51 -0800299 def do_pdb(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800300 """Launch PDB debug prompt in CLI (for CLI development)"""
301 from pdb import set_trace
302 set_trace()
303
Jonathan Hartda93ac62018-05-01 11:25:29 -0700304 def do_version(self, line):
305 """Show the VOLTHA core version"""
306 stub = self.get_stub()
307 voltha = stub.GetVoltha(Empty())
308 self.poutput('{}'.format(voltha.version))
309
Zsolt Haraszti80175202016-12-24 00:17:51 -0800310 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800311 """Show connectivity status to Voltha status"""
Scott Bakerd865fa22018-11-07 11:45:28 -0800312 stub = health_pb2_grpc.HealthServiceStub(self.get_channel())
Zsolt Harasztia133a452016-12-22 01:26:57 -0800313 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800314 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800315
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800316 @options([
317 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400318 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800319 make_option('-m', '--mac-address', action='store', dest='mac_address',
320 default='00:0c:e2:31:40:00'),
321 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800322 make_option('-H', '--host_and_port', action='store',
323 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800324 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800325 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800326 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400327 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800328 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800329 if opts.host_and_port:
330 kw['host_and_port'] = opts.host_and_port
331 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800332 kw['ipv4_address'] = opts.ip_address
333 elif opts.mac_address:
Venkata Teludc1a15b2018-07-06 14:31:05 -0500334 kw['mac_address'] = opts.mac_address.lower()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800335 else:
336 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500337 # Pass any extra arguments past '--' to the device as custom arguments
338 kw['extra_args'] = line
339
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800340 device = voltha_pb2.Device(**kw)
341 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800342 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800343 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800344
Khen Nursimulud068d812017-03-06 11:44:18 -0500345 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800346 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500347 Enable a device. If the <id> is not provided, it will be on the last
348 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800349 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800350 device_id = line or self.default_device_id
Venkata Telu0ccc4302018-07-27 15:11:13 -0500351 if device_id not in self.device_ids():
352 self.poutput('Error: There is no such preprovisioned device')
353 return
354
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400355 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400356 stub = self.get_stub()
Venkata Telu0ccc4302018-07-27 15:11:13 -0500357 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
358 if device.admin_state == voltha_pb2.AdminState.ENABLED:
Nicolas Palpacuer5807dfc2018-08-27 15:47:03 -0400359 if device.oper_status != voltha_pb2.OperStatus.ACTIVATING:
360 self.poutput('Error: Device is already enabled')
361 return
362 else:
363 stub.EnableDevice(voltha_pb2.ID(id=device_id))
364 self.poutput('enabling {}'.format(device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800365
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400366 while True:
367 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
368 # If this is an OLT then acquire logical device id
369 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
370 if device.type.endswith('_olt'):
371 assert device.parent_id
372 self.default_logical_device_id = device.parent_id
373 self.poutput('success (logical device id = {})'.format(
374 self.default_logical_device_id))
375 else:
376 self.poutput('success (device id = {})'.format(device.id))
377 break
378 self.poutput('waiting for device to be enabled...')
379 sleep(.5)
Chip Boling69abce82018-06-18 09:56:23 -0500380 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400381 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800382
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800383 complete_activate_olt = complete_device
384
Khen Nursimulud068d812017-03-06 11:44:18 -0500385 def do_reboot(self, line):
386 """
387 Rebooting a device. ID of the device needs to be provided
388 """
389 device_id = line or self.default_device_id
390 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400391 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400392 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400393 stub.RebootDevice(voltha_pb2.ID(id=device_id))
394 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700395 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400396 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500397
sathishg5ae86222017-06-28 15:16:29 +0530398 def do_self_test(self, line):
399 """
400 Self Test a device. ID of the device needs to be provided
401 """
402 device_id = line or self.default_device_id
403 self.poutput('Self Testing {}'.format(device_id))
404 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400405 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530406 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
407 self.poutput('Self Tested {}'.format(device_id))
408 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700409 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530410 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
411
Khen Nursimulud068d812017-03-06 11:44:18 -0500412 def do_delete(self, line):
413 """
414 Deleting a device. ID of the device needs to be provided
415 """
416 device_id = line or self.default_device_id
417 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400418 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400419 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400420 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
421 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700422 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400423 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500424
425 def do_disable(self, line):
426 """
427 Disable a device. ID of the device needs to be provided
428 """
429 device_id = line
Venkata Teluf468de82018-08-07 13:03:58 -0500430 if device_id not in self.device_ids():
431 self.poutput('Error: There is no such device')
432 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400433 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400434 stub = self.get_stub()
Venkata Teluf468de82018-08-07 13:03:58 -0500435 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
436 if device.admin_state == voltha_pb2.AdminState.DISABLED:
437 self.poutput('Error: Device is already disabled')
438 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400439 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Venkata Teluf468de82018-08-07 13:03:58 -0500440 self.poutput('disabling {}'.format(device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500441
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400442 # Do device query and verify that the device admin status is
443 # DISABLED and Operational Status is unknown
444 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700445 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400446 self.poutput('disabled successfully {}'.format(device_id))
447 else:
448 self.poutput('disabling failed {}. Admin State:{} '
449 'Operation State: {}'.format(device_id,
450 device.admin_state,
451 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700452 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400453 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500454
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800455 def do_test(self, line):
456 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400457 sub = TestCli(self.history, self.voltha_grpc,
458 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800459 sub.cmdloop()
460
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400461 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400462 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400463 sub.cmdloop()
464
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800465
466class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400467 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800468 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
469 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400470 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800471 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400472 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800473
474 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400475 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800476 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400477 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800478 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800479
480 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800481 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800482 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800483 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800484 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800485
486 # verify that device is of type simulated_olt
487 device = self.get_device(device_id)
488 assert device.type == 'simulated_olt', (
489 'Cannot use it on this device type (only on simulated_olt type)')
490
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800491 requests.get('http://{}/devices/{}/detect_onus'.format(
492 self.voltha_sim_rest, device_id
493 ))
494
Zsolt Haraszti80175202016-12-24 00:17:51 -0800495 complete_arrive_onus = VolthaCli.complete_device
496
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800497 def get_logical_ports(self, logical_device_id):
498 """
499 Return the NNI port number and the first usable UNI port of logical
500 device, and the vlan associated with the latter.
501 """
khenaidoo108f05c2017-07-06 11:15:29 -0400502 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800503 ports = stub.ListLogicalDevicePorts(
504 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800505 nni = None
506 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800507 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800508 if port.root_port:
509 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800510 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800511 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800512 uni = port.ofp_port.port_no
513 uni_device = self.get_device(port.device_id)
514 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800515 unis.append((uni, vlan))
516
517 assert nni is not None, "No NNI port found"
518 assert unis, "Not a single UNI?"
519
520 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800521
Zsolt Haraszti80175202016-12-24 00:17:51 -0800522 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800523 """
524 Install an EAPOL flow on the given logical device. If device is not
525 given, it will be applied to logical device of the last pre-provisioned
526 OLT device.
527 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800528 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800529
530 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800531 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800532
533 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400534 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800535 for uni_port_no, _ in unis:
536 update = FlowTableUpdate(
537 id=logical_device_id,
538 flow_mod=mk_simple_flow_mod(
539 priority=2000,
540 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
541 actions=[
542 # push_vlan(0x8100),
543 # set_field(vlan_vid(4096 + 4000)),
544 output(ofp.OFPP_CONTROLLER)
545 ]
546 )
547 )
548 res = stub.UpdateLogicalDeviceFlowTable(update)
549 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800550
Zsolt Haraszti80175202016-12-24 00:17:51 -0800551 complete_install_eapol_flow = VolthaCli.complete_logical_device
552
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800553 def do_install_all_controller_bound_flows(self, line):
554 """
555 Install all flow rules for controller bound flows, including EAPOL,
556 IGMP and DHCP. If device is not given, it will be applied to logical
557 device of the last pre-provisioned OLT device.
558 """
559 logical_device_id = line or self.default_logical_device_id
560
561 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800562 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800563
564 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400565 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800566
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800567 for uni_port_no, _ in unis:
568 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
569 id=logical_device_id,
570 flow_mod=mk_simple_flow_mod(
571 priority=2000,
572 match_fields=[
573 in_port(uni_port_no),
574 eth_type(0x888e)
575 ],
576 actions=[output(ofp.OFPP_CONTROLLER)]
577 )
578 ))
579 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
580 id=logical_device_id,
581 flow_mod=mk_simple_flow_mod(
582 priority=1000,
583 match_fields=[
584 in_port(uni_port_no),
585 eth_type(0x800),
586 ip_proto(2)
587 ],
588 actions=[output(ofp.OFPP_CONTROLLER)]
589 )
590 ))
591 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
592 id=logical_device_id,
593 flow_mod=mk_simple_flow_mod(
594 priority=1000,
595 match_fields=[
596 in_port(uni_port_no),
597 eth_type(0x800),
598 ip_proto(17),
599 udp_dst(67)
600 ],
601 actions=[output(ofp.OFPP_CONTROLLER)]
602 )
603 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800604 self.poutput('success')
605
606 complete_install_all_controller_bound_flows = \
607 VolthaCli.complete_logical_device
608
609 def do_install_all_sample_flows(self, line):
610 """
611 Install all flows that are representative of the virtualized access
612 scenario in a PON network.
613 """
614 logical_device_id = line or self.default_logical_device_id
615
616 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800617 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800618
619 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400620 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800621
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800622 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800623 # Controller-bound flows
624 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
625 id=logical_device_id,
626 flow_mod=mk_simple_flow_mod(
627 priority=2000,
628 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
629 actions=[
630 # push_vlan(0x8100),
631 # set_field(vlan_vid(4096 + 4000)),
632 output(ofp.OFPP_CONTROLLER)
633 ]
634 )
635 ))
636 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
637 id=logical_device_id,
638 flow_mod=mk_simple_flow_mod(
639 priority=1000,
640 match_fields=[eth_type(0x800), ip_proto(2)],
641 actions=[output(ofp.OFPP_CONTROLLER)]
642 )
643 ))
644 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
645 id=logical_device_id,
646 flow_mod=mk_simple_flow_mod(
647 priority=1000,
648 match_fields=[eth_type(0x800), ip_proto(17), udp_dst(67)],
649 actions=[output(ofp.OFPP_CONTROLLER)]
650 )
651 ))
652
653 # Unicast flows:
654 # Downstream flow 1
655 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
656 id=logical_device_id,
657 flow_mod=mk_simple_flow_mod(
658 priority=500,
659 match_fields=[
660 in_port(nni_port_no),
661 vlan_vid(4096 + 1000),
662 metadata(c_vid) # here to mimic an ONOS artifact
663 ],
664 actions=[pop_vlan()],
665 next_table_id=1
666 )
667 ))
668 # Downstream flow 2
669 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
670 id=logical_device_id,
671 flow_mod=mk_simple_flow_mod(
672 priority=500,
673 table_id=1,
674 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
675 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
676 )
677 ))
678 # Upstream flow 1 for 0-tagged case
679 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
680 id=logical_device_id,
681 flow_mod=mk_simple_flow_mod(
682 priority=500,
683 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
684 actions=[set_field(vlan_vid(4096 + c_vid))],
685 next_table_id=1
686 )
687 ))
688 # Upstream flow 1 for untagged case
689 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
690 id=logical_device_id,
691 flow_mod=mk_simple_flow_mod(
692 priority=500,
693 match_fields=[in_port(uni_port_no), vlan_vid(0)],
694 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
695 next_table_id=1
696 )
697 ))
698 # Upstream flow 2 for s-tag
699 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
700 id=logical_device_id,
701 flow_mod=mk_simple_flow_mod(
702 priority=500,
703 table_id=1,
704 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
705 actions=[
706 push_vlan(0x8100),
707 set_field(vlan_vid(4096 + 1000)),
708 output(nni_port_no)
709 ]
710 )
711 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800712
713 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800714 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800715 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
716 id=logical_device_id,
717 group_mod=mk_multicast_group_mod(
718 group_id=1,
719 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800720 ofp.ofp_bucket(actions=[
721 pop_vlan(),
722 output(unis[0][0])
723 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800724 ]
725 )
726 ))
727 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
728 id=logical_device_id,
729 flow_mod=mk_simple_flow_mod(
730 priority=1000,
731 match_fields=[
732 in_port(nni_port_no),
733 eth_type(0x800),
734 vlan_vid(4096 + 140),
735 ipv4_dst(0xe4010101)
736 ],
737 actions=[group(1)]
738 )
739 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800740
741 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800742 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
743 id=logical_device_id,
744 group_mod=mk_multicast_group_mod(
745 group_id=2,
746 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800747 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400748 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800749 ]
750 )
751 ))
752 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
753 id=logical_device_id,
754 flow_mod=mk_simple_flow_mod(
755 priority=1000,
756 match_fields=[
757 in_port(nni_port_no),
758 eth_type(0x800),
759 vlan_vid(4096 + 140),
760 ipv4_dst(0xe4020202)
761 ],
762 actions=[group(2)]
763 )
764 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800765
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800766 # 3rd with empty bucket
767 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
768 id=logical_device_id,
769 group_mod=mk_multicast_group_mod(
770 group_id=3,
771 buckets=[]
772 )
773 ))
774 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
775 id=logical_device_id,
776 flow_mod=mk_simple_flow_mod(
777 priority=1000,
778 match_fields=[
779 in_port(nni_port_no),
780 eth_type(0x800),
781 vlan_vid(4096 + 140),
782 ipv4_dst(0xe4030303)
783 ],
784 actions=[group(3)]
785 )
786 ))
787
788 self.poutput('success')
789
790 complete_install_all_sample_flows = VolthaCli.complete_logical_device
791
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600792 def do_install_dhcp_flows(self, line):
793 """
794 Install all dhcp flows that are representative of the virtualized access
795 scenario in a PON network.
796 """
797 logical_device_id = line or self.default_logical_device_id
798
799 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800800 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600801
802 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400803 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600804
805 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800806 for uni_port_no, _ in unis:
807 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
808 id=logical_device_id,
809 flow_mod=mk_simple_flow_mod(
810 priority=1000,
811 match_fields=[
812 in_port(uni_port_no),
813 eth_type(0x800),
814 ip_proto(17),
815 udp_dst(67)
816 ],
817 actions=[output(ofp.OFPP_CONTROLLER)]
818 )
819 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600820
821 self.poutput('success')
822
823 complete_install_dhcp_flows = VolthaCli.complete_logical_device
824
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800825 def do_delete_all_flows(self, line):
826 """
827 Remove all flows and flow groups from given logical device
828 """
829 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400830 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800831 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
832 id=logical_device_id,
833 flow_mod=ofp.ofp_flow_mod(
834 command=ofp.OFPFC_DELETE,
835 table_id=ofp.OFPTT_ALL,
836 cookie_mask=0,
837 out_port=ofp.OFPP_ANY,
838 out_group=ofp.OFPG_ANY
839 )
840 ))
841 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
842 id=logical_device_id,
843 group_mod=ofp.ofp_group_mod(
844 command=ofp.OFPGC_DELETE,
845 group_id=ofp.OFPG_ALL
846 )
847 ))
848 self.poutput('success')
849
850 complete_delete_all_flows = VolthaCli.complete_logical_device
851
Zsolt Haraszti80175202016-12-24 00:17:51 -0800852 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800853 """
854 Send an EAPOL upstream from a simulated OLT
855 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800856 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800857 requests.get('http://{}/devices/{}/test_eapol_in'.format(
858 self.voltha_sim_rest, device_id
859 ))
860
Zsolt Haraszti80175202016-12-24 00:17:51 -0800861 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
862
863 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800864 """
865 Send out an an EAPOL start message into the given Unix interface
866 """
867 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800868
869
870if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800871
872 parser = argparse.ArgumentParser()
873
874 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
875 parser.add_argument(
876 '-C', '--consul', action='store', default=defs['consul'], help=_help)
877
ntoorchi9cb00a72019-07-17 10:43:54 -0700878 _help = '<hostname>:<port> to etcd container (default: %s)' % defs['etcd']
879 parser.add_argument(
880 '-E', '--etcd', action='store', default=defs['etcd'], help=_help)
881
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800882 _help = 'Lookup Voltha endpoints based on service entries in Consul'
883 parser.add_argument(
884 '-L', '--lookup', action='store_true', help=_help)
885
khenaidoo108f05c2017-07-06 11:15:29 -0400886 _help = 'All requests to the Voltha gRPC service are global'
887 parser.add_argument(
888 '-G', '--global_request', action='store_true', help=_help)
889
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800890 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
891 defs['voltha_grpc_endpoint'])
892 parser.add_argument('-g', '--grpc-endpoint', action='store',
893 default=defs['voltha_grpc_endpoint'], help=_help)
894
895 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
896 'testing (default={})'.format(
897 defs['voltha_sim_rest_endpoint'])
898 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
899 default=defs['voltha_sim_rest_endpoint'], help=_help)
900
901 args = parser.parse_args()
902
903 if args.lookup:
904 host = args.consul.split(':')[0].strip()
905 port = int(args.consul.split(':')[1].strip())
906 consul = Consul(host=host, port=port)
907
908 _, services = consul.catalog.service('voltha-grpc')
909 if not services:
910 print('No voltha-grpc service registered in consul; exiting')
911 sys.exit(1)
912 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
913 services[0]['ServicePort'])
914
915 _, services = consul.catalog.service('voltha-sim-rest')
916 if not services:
917 print('No voltha-sim-rest service registered in consul; exiting')
918 sys.exit(1)
919 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
920 services[0]['ServicePort'])
921
ntoorchi9cb00a72019-07-17 10:43:54 -0700922 host = args.etcd.split(':')[0].strip()
923 port = int(args.etcd.split(':')[1].strip())
924 etcd = etcd3.client(host=host, port=port)
925 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint, etcd,
khenaidoo108f05c2017-07-06 11:15:29 -0400926 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800927 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800928 c.load_history()
929 c.cmdloop()
930 c.save_history()