blob: 441b29241363fd90efb54e01b322f05eea916bd3 [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
Zsolt Harasztia133a452016-12-22 01:26:57 -080024import grpc
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080025import requests
26from cmd2 import Cmd, options
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040027from consul import Consul
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080028from google.protobuf.empty_pb2 import Empty
Zsolt Harasztia133a452016-12-22 01:26:57 -080029from simplejson import dumps
30
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080031from cli.device import DeviceCli
Nikolay Titov89004ec2017-06-19 18:22:42 -040032from cli.xpon import XponCli
Chip Boling69abce82018-06-18 09:56:23 -050033from cli.omci import OmciCli
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040034from cli.alarm_filters import AlarmFiltersCli
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080035from cli.logical_device import LogicalDeviceCli
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040036from cli.table import print_pb_list_as_table
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080037from voltha.core.flow_decomposer import *
Zsolt Harasztia133a452016-12-22 01:26:57 -080038from voltha.protos import third_party
39from voltha.protos import voltha_pb2
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'),
47 consul=os.environ.get('CONSUL', 'localhost:8500'),
48 voltha_grpc_endpoint=os.environ.get('VOLTHA_GRPC_ENDPOINT',
49 'localhost:50055'),
50 voltha_sim_rest_endpoint=os.environ.get('VOLTHA_SIM_REST_ENDPOINT',
51 'localhost:18880'),
khenaidoo108f05c2017-07-06 11:15:29 -040052 global_request=os.environ.get('GLOBAL_REQUEST', False)
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080053)
54
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080055banner = """\
Zsolt Haraszti313c4be2016-12-27 11:06:53 -080056 _ _ _ ___ _ ___
57__ _____| | |_| |_ __ _ / __| | |_ _|
58\ V / _ \ | _| ' \/ _` | | (__| |__ | |
59 \_/\___/_|\__|_||_\__,_| \___|____|___|
Zsolt Haraszti80175202016-12-24 00:17:51 -080060(to exit type quit or hit Ctrl-D)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080061"""
Zsolt Harasztia133a452016-12-22 01:26:57 -080062
Zsolt Harasztia133a452016-12-22 01:26:57 -080063
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040064class VolthaCli(Cmd):
Zsolt Harasztia133a452016-12-22 01:26:57 -080065 prompt = 'voltha'
66 history_file_name = '.voltha_cli_history'
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080067
68 # Settable CLI parameters
69 voltha_grpc = 'localhost:50055'
70 voltha_sim_rest = 'localhost:18880'
khenaidoo108f05c2017-07-06 11:15:29 -040071 global_request = False
Zsolt Harasztia133a452016-12-22 01:26:57 -080072 max_history_lines = 500
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080073 default_device_id = None
74 default_logical_device_id = None
Zsolt Harasztia133a452016-12-22 01:26:57 -080075
76 Cmd.settable.update(dict(
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080077 voltha_grpc='Voltha GRPC endpoint in form of <host>:<port>',
78 voltha_sim_rest='Voltha simulation back door for testing in form '
79 'of <host>:<port>',
80 max_history_lines='Maximum number of history lines stored across '
81 'sessions',
82 default_device_id='Device id used when no device id is specified',
83 default_logical_device_id='Logical device id used when no device id '
84 'is specified',
Zsolt Harasztia133a452016-12-22 01:26:57 -080085 ))
86
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080087 # cleanup of superfluous commands from cmd2
Zsolt Haraszti80175202016-12-24 00:17:51 -080088 del Cmd.do_cmdenvironment
Steve Crooks05f24522017-02-27 13:32:27 -050089 del Cmd.do_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080090 del Cmd.do__relative_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080091
khenaidoo108f05c2017-07-06 11:15:29 -040092 def __init__(self, voltha_grpc, voltha_sim_rest, global_request=False):
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080093 VolthaCli.voltha_grpc = voltha_grpc
94 VolthaCli.voltha_sim_rest = voltha_sim_rest
khenaidoo108f05c2017-07-06 11:15:29 -040095 VolthaCli.global_request = global_request
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080096 Cmd.__init__(self)
Zsolt Harasztia133a452016-12-22 01:26:57 -080097 self.prompt = '(' + self.colorize(
Zsolt Haraszti80175202016-12-24 00:17:51 -080098 self.colorize(self.prompt, 'blue'), 'bold') + ') '
Zsolt Harasztia133a452016-12-22 01:26:57 -080099 self.channel = None
khenaidoo108f05c2017-07-06 11:15:29 -0400100 self.stub = None
Zsolt Haraszti80175202016-12-24 00:17:51 -0800101 self.device_ids_cache = None
102 self.device_ids_cache_ts = time()
103 self.logical_device_ids_cache = None
104 self.logical_device_ids_cache_ts = time()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800105
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800106 # we override cmd2's method to avoid its optparse conflicting with our
107 # command line parsing
108 def cmdloop(self):
109 self._cmdloop()
110
Zsolt Harasztia133a452016-12-22 01:26:57 -0800111 def load_history(self):
112 """Load saved command history from local history file"""
113 try:
114 with file(self.history_file_name, 'r') as f:
115 for line in f.readlines():
116 stripped_line = line.strip()
117 self.history.append(stripped_line)
118 readline.add_history(stripped_line)
119 except IOError:
120 pass # ignore if file cannot be read
121
122 def save_history(self):
123 try:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800124 with open(self.history_file_name, 'w') as f:
Zsolt Harasztia133a452016-12-22 01:26:57 -0800125 f.write('\n'.join(self.history[-self.max_history_lines:]))
Zsolt Haraszti80175202016-12-24 00:17:51 -0800126 except IOError as e:
127 self.perror('Could not save history in {}: {}'.format(
128 self.history_file_name, e))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800129 else:
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800130 self.poutput('History saved as {}'.format(
Zsolt Haraszti80175202016-12-24 00:17:51 -0800131 self.history_file_name))
132
133 def perror(self, errmsg, statement=None):
134 # Touch it up to make sure error is prefixed and colored
135 Cmd.perror(self, self.colorize('***ERROR: ', 'red') + errmsg,
136 statement)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800137
138 def get_channel(self):
139 if self.channel is None:
140 self.channel = grpc.insecure_channel(self.voltha_grpc)
141 return self.channel
142
khenaidoo108f05c2017-07-06 11:15:29 -0400143 def get_stub(self):
144 if self.stub is None:
145 self.stub = \
146 voltha_pb2.VolthaGlobalServiceStub(self.get_channel()) \
147 if self.global_request else \
148 voltha_pb2.VolthaLocalServiceStub(self.get_channel())
149 return self.stub
150
Zsolt Haraszti80175202016-12-24 00:17:51 -0800151 # ~~~~~~~~~~~~~~~~~ ACTUAL COMMAND IMPLEMENTATIONS ~~~~~~~~~~~~~~~~~~~~~~~~
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800152
Zsolt Haraszti80175202016-12-24 00:17:51 -0800153 def do_reset_history(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800154 """Reset CLI history"""
155 while self.history:
156 self.history.pop()
157
Zsolt Haraszti80175202016-12-24 00:17:51 -0800158 def do_launch(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800159 """If Voltha is not running yet, launch it"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800160 raise NotImplementedError('not implemented yet')
Zsolt Harasztia133a452016-12-22 01:26:57 -0800161
Zsolt Haraszti80175202016-12-24 00:17:51 -0800162 def do_restart(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800163 """Launch Voltha, but if it is already running, terminate it first"""
164 pass
165
Zsolt Haraszti80175202016-12-24 00:17:51 -0800166 def do_adapters(self, line):
167 """List loaded adapter"""
khenaidoo108f05c2017-07-06 11:15:29 -0400168 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800169 res = stub.ListAdapters(Empty())
Sergio Slobodrian6e9fb692017-03-17 14:46:33 -0400170 omit_fields = {'config.log_level', 'logical_device_ids'}
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800171 print_pb_list_as_table('Adapters:', res.items, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800172
173 def get_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400174 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800175 res = stub.ListDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800176 return res.items
Zsolt Harasztia133a452016-12-22 01:26:57 -0800177
Zsolt Haraszti80175202016-12-24 00:17:51 -0800178 def get_logical_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400179 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800180 res = stub.ListLogicalDevices(Empty())
181 return res.items
182
183 def do_devices(self, line):
184 """List devices registered in Voltha"""
185 devices = self.get_devices()
186 omit_fields = {
187 'adapter',
188 'vendor',
189 'model',
190 'hardware_version',
ggowdru236bd952017-06-20 20:32:55 -0700191 'images',
Zsolt Haraszti80175202016-12-24 00:17:51 -0800192 'firmware_version',
Nicolas Palpacuerb83853e2018-06-28 16:11:30 -0400193 'vendor_id'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800194 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800195 print_pb_list_as_table('Devices:', devices, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800196
197 def do_logical_devices(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800198 """List logical devices in Voltha"""
khenaidoo108f05c2017-07-06 11:15:29 -0400199 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800200 res = stub.ListLogicalDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800201 omit_fields = {
202 'desc.mfr_desc',
203 'desc.hw_desc',
204 'desc.sw_desc',
205 'desc.dp_desc',
206 'desc.serial_number',
Sergio Slobodriana95f99b2017-03-21 10:22:47 -0400207 'switch_features.capabilities'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800208 }
Jonathan Hart7d4a23d2018-06-28 07:36:28 -0700209 presfns = {
210 'datapath_id': lambda x: "{0:0{1}x}".format(int(x), 16)
211 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800212 print_pb_list_as_table('Logical devices:', res.items, omit_fields,
Jonathan Hart7d4a23d2018-06-28 07:36:28 -0700213 self.poutput, presfns=presfns)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800214
Zsolt Haraszti80175202016-12-24 00:17:51 -0800215 def do_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800216 """Enter device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800217 device_id = line.strip() or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800218 if not device_id:
219 raise Exception('<device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500220 if device_id not in self.device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500221 self.poutput( self.colorize('Error: ', 'red') +
222 'There is no such device')
223 raise Exception('<device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400224 sub = DeviceCli(device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800225 sub.cmdloop()
226
Zsolt Haraszti80175202016-12-24 00:17:51 -0800227 def do_logical_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800228 """Enter logical device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800229 logical_device_id = line.strip() or self.default_logical_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800230 if not logical_device_id:
231 raise Exception('<logical-device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500232 if logical_device_id not in self.logical_device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500233 self.poutput( self.colorize('Error: ', 'red') +
234 'There is no such device')
235 raise Exception('<logical-device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400236 sub = LogicalDeviceCli(logical_device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800237 sub.cmdloop()
238
Zsolt Haraszti80175202016-12-24 00:17:51 -0800239 def device_ids(self, force_refresh=False):
240 if force_refresh or self.device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400241 (time() - self.device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800242 self.device_ids_cache = [d.id for d in self.get_devices()]
243 self.device_ids_cache_ts = time()
244 return self.device_ids_cache
245
246 def logical_device_ids(self, force_refresh=False):
247 if force_refresh or self.logical_device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400248 (time() - self.logical_device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800249 self.logical_device_ids_cache = [d.id for d
250 in self.get_logical_devices()]
251 self.logical_device_ids_cache_ts = time()
252 return self.logical_device_ids_cache
253
254 def complete_device(self, text, line, begidx, endidx):
255 if not text:
256 completions = self.device_ids()[:]
257 else:
258 completions = [d for d in self.device_ids() if d.startswith(text)]
259 return completions
260
261 def complete_logical_device(self, text, line, begidx, endidx):
262 if not text:
263 completions = self.logical_device_ids()[:]
264 else:
265 completions = [d for d in self.logical_device_ids()
266 if d.startswith(text)]
267 return completions
268
Nikolay Titov89004ec2017-06-19 18:22:42 -0400269 def do_xpon(self, line):
270 """xpon <optional> [device_ID] - Enter xpon level command mode"""
271 device_id = line.strip()
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400272 if device_id:
273 stub = self.get_stub()
274 try:
275 res = stub.GetDevice(voltha_pb2.ID(id=device_id))
276 except Exception:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400277 self.poutput(
278 self.colorize('Error: ', 'red') + 'No device id ' +
279 self.colorize(device_id, 'blue') + ' is found')
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400280 return
281 sub = XponCli(self.get_channel, device_id)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400282 sub.cmdloop()
283
Chip Boling69abce82018-06-18 09:56:23 -0500284 def do_omci(self, line):
285 """omci <device_ID> - Enter OMCI level command mode"""
286
287 device_id = line.strip() or self.default_device_id
288 if not device_id:
289 raise Exception('<device-id> parameter needed')
290 sub = OmciCli(device_id, self.get_stub)
291 sub.cmdloop()
292
Zsolt Haraszti80175202016-12-24 00:17:51 -0800293 def do_pdb(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800294 """Launch PDB debug prompt in CLI (for CLI development)"""
295 from pdb import set_trace
296 set_trace()
297
Jonathan Hartda93ac62018-05-01 11:25:29 -0700298 def do_version(self, line):
299 """Show the VOLTHA core version"""
300 stub = self.get_stub()
301 voltha = stub.GetVoltha(Empty())
302 self.poutput('{}'.format(voltha.version))
303
Zsolt Haraszti80175202016-12-24 00:17:51 -0800304 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800305 """Show connectivity status to Voltha status"""
306 stub = voltha_pb2.HealthServiceStub(self.get_channel())
307 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800308 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800309
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800310 @options([
311 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400312 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800313 make_option('-m', '--mac-address', action='store', dest='mac_address',
314 default='00:0c:e2:31:40:00'),
315 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800316 make_option('-H', '--host_and_port', action='store',
317 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800318 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800319 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800320 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400321 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800322 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800323 if opts.host_and_port:
324 kw['host_and_port'] = opts.host_and_port
325 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800326 kw['ipv4_address'] = opts.ip_address
327 elif opts.mac_address:
Venkata Teludc1a15b2018-07-06 14:31:05 -0500328 kw['mac_address'] = opts.mac_address.lower()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800329 else:
330 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500331 # Pass any extra arguments past '--' to the device as custom arguments
332 kw['extra_args'] = line
333
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800334 device = voltha_pb2.Device(**kw)
335 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800336 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800337 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800338
Khen Nursimulud068d812017-03-06 11:44:18 -0500339 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800340 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500341 Enable a device. If the <id> is not provided, it will be on the last
342 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800343 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800344 device_id = line or self.default_device_id
Venkata Telu0ccc4302018-07-27 15:11:13 -0500345 if device_id not in self.device_ids():
346 self.poutput('Error: There is no such preprovisioned device')
347 return
348
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400349 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400350 stub = self.get_stub()
Venkata Telu0ccc4302018-07-27 15:11:13 -0500351 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
352 if device.admin_state == voltha_pb2.AdminState.ENABLED:
353 self.poutput('Error: Device is already enabled')
354 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400355 stub.EnableDevice(voltha_pb2.ID(id=device_id))
Venkata Telu0ccc4302018-07-27 15:11:13 -0500356 self.poutput('enabling {}'.format(device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800357
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400358 while True:
359 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
360 # If this is an OLT then acquire logical device id
361 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
362 if device.type.endswith('_olt'):
363 assert device.parent_id
364 self.default_logical_device_id = device.parent_id
365 self.poutput('success (logical device id = {})'.format(
366 self.default_logical_device_id))
367 else:
368 self.poutput('success (device id = {})'.format(device.id))
369 break
370 self.poutput('waiting for device to be enabled...')
371 sleep(.5)
Chip Boling69abce82018-06-18 09:56:23 -0500372 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400373 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800374
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800375 complete_activate_olt = complete_device
376
Khen Nursimulud068d812017-03-06 11:44:18 -0500377 def do_reboot(self, line):
378 """
379 Rebooting a device. ID of the device needs to be provided
380 """
381 device_id = line or self.default_device_id
382 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400383 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400384 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400385 stub.RebootDevice(voltha_pb2.ID(id=device_id))
386 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700387 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400388 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500389
sathishg5ae86222017-06-28 15:16:29 +0530390 def do_self_test(self, line):
391 """
392 Self Test a device. ID of the device needs to be provided
393 """
394 device_id = line or self.default_device_id
395 self.poutput('Self Testing {}'.format(device_id))
396 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400397 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530398 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
399 self.poutput('Self Tested {}'.format(device_id))
400 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700401 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530402 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
403
Khen Nursimulud068d812017-03-06 11:44:18 -0500404 def do_delete(self, line):
405 """
406 Deleting a device. ID of the device needs to be provided
407 """
408 device_id = line or self.default_device_id
409 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400410 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400411 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400412 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
413 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700414 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400415 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500416
417 def do_disable(self, line):
418 """
419 Disable a device. ID of the device needs to be provided
420 """
421 device_id = line
Venkata Teluf468de82018-08-07 13:03:58 -0500422 if device_id not in self.device_ids():
423 self.poutput('Error: There is no such device')
424 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400425 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400426 stub = self.get_stub()
Venkata Teluf468de82018-08-07 13:03:58 -0500427 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
428 if device.admin_state == voltha_pb2.AdminState.DISABLED:
429 self.poutput('Error: Device is already disabled')
430 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400431 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Venkata Teluf468de82018-08-07 13:03:58 -0500432 self.poutput('disabling {}'.format(device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500433
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400434 # Do device query and verify that the device admin status is
435 # DISABLED and Operational Status is unknown
436 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700437 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400438 self.poutput('disabled successfully {}'.format(device_id))
439 else:
440 self.poutput('disabling failed {}. Admin State:{} '
441 'Operation State: {}'.format(device_id,
442 device.admin_state,
443 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700444 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400445 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500446
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800447 def do_test(self, line):
448 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400449 sub = TestCli(self.history, self.voltha_grpc,
450 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800451 sub.cmdloop()
452
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400453 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400454 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400455 sub.cmdloop()
456
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800457
458class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400459 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800460 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
461 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400462 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800463 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400464 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800465
466 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400467 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800468 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400469 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800470 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800471
472 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800473 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800474 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800475 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800476 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800477
478 # verify that device is of type simulated_olt
479 device = self.get_device(device_id)
480 assert device.type == 'simulated_olt', (
481 'Cannot use it on this device type (only on simulated_olt type)')
482
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800483 requests.get('http://{}/devices/{}/detect_onus'.format(
484 self.voltha_sim_rest, device_id
485 ))
486
Zsolt Haraszti80175202016-12-24 00:17:51 -0800487 complete_arrive_onus = VolthaCli.complete_device
488
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800489 def get_logical_ports(self, logical_device_id):
490 """
491 Return the NNI port number and the first usable UNI port of logical
492 device, and the vlan associated with the latter.
493 """
khenaidoo108f05c2017-07-06 11:15:29 -0400494 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800495 ports = stub.ListLogicalDevicePorts(
496 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800497 nni = None
498 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800499 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800500 if port.root_port:
501 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800502 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800503 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800504 uni = port.ofp_port.port_no
505 uni_device = self.get_device(port.device_id)
506 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800507 unis.append((uni, vlan))
508
509 assert nni is not None, "No NNI port found"
510 assert unis, "Not a single UNI?"
511
512 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800513
Zsolt Haraszti80175202016-12-24 00:17:51 -0800514 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800515 """
516 Install an EAPOL flow on the given logical device. If device is not
517 given, it will be applied to logical device of the last pre-provisioned
518 OLT device.
519 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800520 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800521
522 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800523 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800524
525 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400526 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800527 for uni_port_no, _ in unis:
528 update = FlowTableUpdate(
529 id=logical_device_id,
530 flow_mod=mk_simple_flow_mod(
531 priority=2000,
532 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
533 actions=[
534 # push_vlan(0x8100),
535 # set_field(vlan_vid(4096 + 4000)),
536 output(ofp.OFPP_CONTROLLER)
537 ]
538 )
539 )
540 res = stub.UpdateLogicalDeviceFlowTable(update)
541 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800542
Zsolt Haraszti80175202016-12-24 00:17:51 -0800543 complete_install_eapol_flow = VolthaCli.complete_logical_device
544
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800545 def do_install_all_controller_bound_flows(self, line):
546 """
547 Install all flow rules for controller bound flows, including EAPOL,
548 IGMP and DHCP. If device is not given, it will be applied to logical
549 device of the last pre-provisioned OLT device.
550 """
551 logical_device_id = line or self.default_logical_device_id
552
553 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800554 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800555
556 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400557 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800558
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800559 for uni_port_no, _ in unis:
560 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
561 id=logical_device_id,
562 flow_mod=mk_simple_flow_mod(
563 priority=2000,
564 match_fields=[
565 in_port(uni_port_no),
566 eth_type(0x888e)
567 ],
568 actions=[output(ofp.OFPP_CONTROLLER)]
569 )
570 ))
571 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
572 id=logical_device_id,
573 flow_mod=mk_simple_flow_mod(
574 priority=1000,
575 match_fields=[
576 in_port(uni_port_no),
577 eth_type(0x800),
578 ip_proto(2)
579 ],
580 actions=[output(ofp.OFPP_CONTROLLER)]
581 )
582 ))
583 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
584 id=logical_device_id,
585 flow_mod=mk_simple_flow_mod(
586 priority=1000,
587 match_fields=[
588 in_port(uni_port_no),
589 eth_type(0x800),
590 ip_proto(17),
591 udp_dst(67)
592 ],
593 actions=[output(ofp.OFPP_CONTROLLER)]
594 )
595 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800596 self.poutput('success')
597
598 complete_install_all_controller_bound_flows = \
599 VolthaCli.complete_logical_device
600
601 def do_install_all_sample_flows(self, line):
602 """
603 Install all flows that are representative of the virtualized access
604 scenario in a PON network.
605 """
606 logical_device_id = line or self.default_logical_device_id
607
608 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800609 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800610
611 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400612 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800613
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800614 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800615 # Controller-bound flows
616 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
617 id=logical_device_id,
618 flow_mod=mk_simple_flow_mod(
619 priority=2000,
620 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
621 actions=[
622 # push_vlan(0x8100),
623 # set_field(vlan_vid(4096 + 4000)),
624 output(ofp.OFPP_CONTROLLER)
625 ]
626 )
627 ))
628 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
629 id=logical_device_id,
630 flow_mod=mk_simple_flow_mod(
631 priority=1000,
632 match_fields=[eth_type(0x800), ip_proto(2)],
633 actions=[output(ofp.OFPP_CONTROLLER)]
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(17), udp_dst(67)],
641 actions=[output(ofp.OFPP_CONTROLLER)]
642 )
643 ))
644
645 # Unicast flows:
646 # Downstream flow 1
647 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
648 id=logical_device_id,
649 flow_mod=mk_simple_flow_mod(
650 priority=500,
651 match_fields=[
652 in_port(nni_port_no),
653 vlan_vid(4096 + 1000),
654 metadata(c_vid) # here to mimic an ONOS artifact
655 ],
656 actions=[pop_vlan()],
657 next_table_id=1
658 )
659 ))
660 # Downstream flow 2
661 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
662 id=logical_device_id,
663 flow_mod=mk_simple_flow_mod(
664 priority=500,
665 table_id=1,
666 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
667 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
668 )
669 ))
670 # Upstream flow 1 for 0-tagged case
671 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
672 id=logical_device_id,
673 flow_mod=mk_simple_flow_mod(
674 priority=500,
675 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
676 actions=[set_field(vlan_vid(4096 + c_vid))],
677 next_table_id=1
678 )
679 ))
680 # Upstream flow 1 for untagged case
681 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
682 id=logical_device_id,
683 flow_mod=mk_simple_flow_mod(
684 priority=500,
685 match_fields=[in_port(uni_port_no), vlan_vid(0)],
686 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
687 next_table_id=1
688 )
689 ))
690 # Upstream flow 2 for s-tag
691 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
692 id=logical_device_id,
693 flow_mod=mk_simple_flow_mod(
694 priority=500,
695 table_id=1,
696 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
697 actions=[
698 push_vlan(0x8100),
699 set_field(vlan_vid(4096 + 1000)),
700 output(nni_port_no)
701 ]
702 )
703 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800704
705 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800706 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800707 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
708 id=logical_device_id,
709 group_mod=mk_multicast_group_mod(
710 group_id=1,
711 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800712 ofp.ofp_bucket(actions=[
713 pop_vlan(),
714 output(unis[0][0])
715 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800716 ]
717 )
718 ))
719 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
720 id=logical_device_id,
721 flow_mod=mk_simple_flow_mod(
722 priority=1000,
723 match_fields=[
724 in_port(nni_port_no),
725 eth_type(0x800),
726 vlan_vid(4096 + 140),
727 ipv4_dst(0xe4010101)
728 ],
729 actions=[group(1)]
730 )
731 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800732
733 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800734 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
735 id=logical_device_id,
736 group_mod=mk_multicast_group_mod(
737 group_id=2,
738 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800739 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400740 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800741 ]
742 )
743 ))
744 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
745 id=logical_device_id,
746 flow_mod=mk_simple_flow_mod(
747 priority=1000,
748 match_fields=[
749 in_port(nni_port_no),
750 eth_type(0x800),
751 vlan_vid(4096 + 140),
752 ipv4_dst(0xe4020202)
753 ],
754 actions=[group(2)]
755 )
756 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800757
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800758 # 3rd with empty bucket
759 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
760 id=logical_device_id,
761 group_mod=mk_multicast_group_mod(
762 group_id=3,
763 buckets=[]
764 )
765 ))
766 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
767 id=logical_device_id,
768 flow_mod=mk_simple_flow_mod(
769 priority=1000,
770 match_fields=[
771 in_port(nni_port_no),
772 eth_type(0x800),
773 vlan_vid(4096 + 140),
774 ipv4_dst(0xe4030303)
775 ],
776 actions=[group(3)]
777 )
778 ))
779
780 self.poutput('success')
781
782 complete_install_all_sample_flows = VolthaCli.complete_logical_device
783
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600784 def do_install_dhcp_flows(self, line):
785 """
786 Install all dhcp flows that are representative of the virtualized access
787 scenario in a PON network.
788 """
789 logical_device_id = line or self.default_logical_device_id
790
791 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800792 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600793
794 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400795 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600796
797 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800798 for uni_port_no, _ in unis:
799 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
800 id=logical_device_id,
801 flow_mod=mk_simple_flow_mod(
802 priority=1000,
803 match_fields=[
804 in_port(uni_port_no),
805 eth_type(0x800),
806 ip_proto(17),
807 udp_dst(67)
808 ],
809 actions=[output(ofp.OFPP_CONTROLLER)]
810 )
811 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600812
813 self.poutput('success')
814
815 complete_install_dhcp_flows = VolthaCli.complete_logical_device
816
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800817 def do_delete_all_flows(self, line):
818 """
819 Remove all flows and flow groups from given logical device
820 """
821 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400822 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800823 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
824 id=logical_device_id,
825 flow_mod=ofp.ofp_flow_mod(
826 command=ofp.OFPFC_DELETE,
827 table_id=ofp.OFPTT_ALL,
828 cookie_mask=0,
829 out_port=ofp.OFPP_ANY,
830 out_group=ofp.OFPG_ANY
831 )
832 ))
833 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
834 id=logical_device_id,
835 group_mod=ofp.ofp_group_mod(
836 command=ofp.OFPGC_DELETE,
837 group_id=ofp.OFPG_ALL
838 )
839 ))
840 self.poutput('success')
841
842 complete_delete_all_flows = VolthaCli.complete_logical_device
843
Zsolt Haraszti80175202016-12-24 00:17:51 -0800844 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800845 """
846 Send an EAPOL upstream from a simulated OLT
847 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800848 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800849 requests.get('http://{}/devices/{}/test_eapol_in'.format(
850 self.voltha_sim_rest, device_id
851 ))
852
Zsolt Haraszti80175202016-12-24 00:17:51 -0800853 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
854
855 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800856 """
857 Send out an an EAPOL start message into the given Unix interface
858 """
859 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800860
861
862if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800863
864 parser = argparse.ArgumentParser()
865
866 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
867 parser.add_argument(
868 '-C', '--consul', action='store', default=defs['consul'], help=_help)
869
870 _help = 'Lookup Voltha endpoints based on service entries in Consul'
871 parser.add_argument(
872 '-L', '--lookup', action='store_true', help=_help)
873
khenaidoo108f05c2017-07-06 11:15:29 -0400874 _help = 'All requests to the Voltha gRPC service are global'
875 parser.add_argument(
876 '-G', '--global_request', action='store_true', help=_help)
877
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800878 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
879 defs['voltha_grpc_endpoint'])
880 parser.add_argument('-g', '--grpc-endpoint', action='store',
881 default=defs['voltha_grpc_endpoint'], help=_help)
882
883 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
884 'testing (default={})'.format(
885 defs['voltha_sim_rest_endpoint'])
886 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
887 default=defs['voltha_sim_rest_endpoint'], help=_help)
888
889 args = parser.parse_args()
890
891 if args.lookup:
892 host = args.consul.split(':')[0].strip()
893 port = int(args.consul.split(':')[1].strip())
894 consul = Consul(host=host, port=port)
895
896 _, services = consul.catalog.service('voltha-grpc')
897 if not services:
898 print('No voltha-grpc service registered in consul; exiting')
899 sys.exit(1)
900 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
901 services[0]['ServicePort'])
902
903 _, services = consul.catalog.service('voltha-sim-rest')
904 if not services:
905 print('No voltha-sim-rest service registered in consul; exiting')
906 sys.exit(1)
907 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
908 services[0]['ServicePort'])
909
khenaidoo108f05c2017-07-06 11:15:29 -0400910 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
911 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800912 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800913 c.load_history()
914 c.cmdloop()
915 c.save_history()