blob: 218d3843dea1107ac06ec73cb1109ddfcc1037cb [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 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800209 print_pb_list_as_table('Logical devices:', res.items, omit_fields,
210 self.poutput)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800211
Zsolt Haraszti80175202016-12-24 00:17:51 -0800212 def do_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800213 """Enter device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800214 device_id = line.strip() or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800215 if not device_id:
216 raise Exception('<device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500217 if device_id not in self.device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500218 self.poutput( self.colorize('Error: ', 'red') +
219 'There is no such device')
220 raise Exception('<device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400221 sub = DeviceCli(device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800222 sub.cmdloop()
223
Zsolt Haraszti80175202016-12-24 00:17:51 -0800224 def do_logical_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800225 """Enter logical device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800226 logical_device_id = line.strip() or self.default_logical_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800227 if not logical_device_id:
228 raise Exception('<logical-device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500229 if logical_device_id not in self.logical_device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500230 self.poutput( self.colorize('Error: ', 'red') +
231 'There is no such device')
232 raise Exception('<logical-device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400233 sub = LogicalDeviceCli(logical_device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800234 sub.cmdloop()
235
Zsolt Haraszti80175202016-12-24 00:17:51 -0800236 def device_ids(self, force_refresh=False):
237 if force_refresh or self.device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400238 (time() - self.device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800239 self.device_ids_cache = [d.id for d in self.get_devices()]
240 self.device_ids_cache_ts = time()
241 return self.device_ids_cache
242
243 def logical_device_ids(self, force_refresh=False):
244 if force_refresh or self.logical_device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400245 (time() - self.logical_device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800246 self.logical_device_ids_cache = [d.id for d
247 in self.get_logical_devices()]
248 self.logical_device_ids_cache_ts = time()
249 return self.logical_device_ids_cache
250
251 def complete_device(self, text, line, begidx, endidx):
252 if not text:
253 completions = self.device_ids()[:]
254 else:
255 completions = [d for d in self.device_ids() if d.startswith(text)]
256 return completions
257
258 def complete_logical_device(self, text, line, begidx, endidx):
259 if not text:
260 completions = self.logical_device_ids()[:]
261 else:
262 completions = [d for d in self.logical_device_ids()
263 if d.startswith(text)]
264 return completions
265
Nikolay Titov89004ec2017-06-19 18:22:42 -0400266 def do_xpon(self, line):
267 """xpon <optional> [device_ID] - Enter xpon level command mode"""
268 device_id = line.strip()
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400269 if device_id:
270 stub = self.get_stub()
271 try:
272 res = stub.GetDevice(voltha_pb2.ID(id=device_id))
273 except Exception:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400274 self.poutput(
275 self.colorize('Error: ', 'red') + 'No device id ' +
276 self.colorize(device_id, 'blue') + ' is found')
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400277 return
278 sub = XponCli(self.get_channel, device_id)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400279 sub.cmdloop()
280
Chip Boling69abce82018-06-18 09:56:23 -0500281 def do_omci(self, line):
282 """omci <device_ID> - Enter OMCI level command mode"""
283
284 device_id = line.strip() or self.default_device_id
285 if not device_id:
286 raise Exception('<device-id> parameter needed')
287 sub = OmciCli(device_id, self.get_stub)
288 sub.cmdloop()
289
Zsolt Haraszti80175202016-12-24 00:17:51 -0800290 def do_pdb(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800291 """Launch PDB debug prompt in CLI (for CLI development)"""
292 from pdb import set_trace
293 set_trace()
294
Jonathan Hartda93ac62018-05-01 11:25:29 -0700295 def do_version(self, line):
296 """Show the VOLTHA core version"""
297 stub = self.get_stub()
298 voltha = stub.GetVoltha(Empty())
299 self.poutput('{}'.format(voltha.version))
300
Zsolt Haraszti80175202016-12-24 00:17:51 -0800301 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800302 """Show connectivity status to Voltha status"""
303 stub = voltha_pb2.HealthServiceStub(self.get_channel())
304 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800305 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800306
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800307 @options([
308 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400309 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800310 make_option('-m', '--mac-address', action='store', dest='mac_address',
311 default='00:0c:e2:31:40:00'),
312 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800313 make_option('-H', '--host_and_port', action='store',
314 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800315 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800316 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800317 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400318 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800319 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800320 if opts.host_and_port:
321 kw['host_and_port'] = opts.host_and_port
322 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800323 kw['ipv4_address'] = opts.ip_address
324 elif opts.mac_address:
Venkata Teludc1a15b2018-07-06 14:31:05 -0500325 kw['mac_address'] = opts.mac_address.lower()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800326 else:
327 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500328 # Pass any extra arguments past '--' to the device as custom arguments
329 kw['extra_args'] = line
330
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800331 device = voltha_pb2.Device(**kw)
332 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800333 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800334 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800335
Khen Nursimulud068d812017-03-06 11:44:18 -0500336 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800337 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500338 Enable a device. If the <id> is not provided, it will be on the last
339 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800340 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800341 device_id = line or self.default_device_id
Venkata Telu0ccc4302018-07-27 15:11:13 -0500342 if device_id not in self.device_ids():
343 self.poutput('Error: There is no such preprovisioned device')
344 return
345
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400346 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400347 stub = self.get_stub()
Venkata Telu0ccc4302018-07-27 15:11:13 -0500348 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
349 if device.admin_state == voltha_pb2.AdminState.ENABLED:
350 self.poutput('Error: Device is already enabled')
351 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400352 stub.EnableDevice(voltha_pb2.ID(id=device_id))
Venkata Telu0ccc4302018-07-27 15:11:13 -0500353 self.poutput('enabling {}'.format(device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800354
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400355 while True:
356 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
357 # If this is an OLT then acquire logical device id
358 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
359 if device.type.endswith('_olt'):
360 assert device.parent_id
361 self.default_logical_device_id = device.parent_id
362 self.poutput('success (logical device id = {})'.format(
363 self.default_logical_device_id))
364 else:
365 self.poutput('success (device id = {})'.format(device.id))
366 break
367 self.poutput('waiting for device to be enabled...')
368 sleep(.5)
Chip Boling69abce82018-06-18 09:56:23 -0500369 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400370 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800371
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800372 complete_activate_olt = complete_device
373
Khen Nursimulud068d812017-03-06 11:44:18 -0500374 def do_reboot(self, line):
375 """
376 Rebooting a device. ID of the device needs to be provided
377 """
378 device_id = line or self.default_device_id
379 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400380 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400381 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400382 stub.RebootDevice(voltha_pb2.ID(id=device_id))
383 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700384 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400385 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500386
sathishg5ae86222017-06-28 15:16:29 +0530387 def do_self_test(self, line):
388 """
389 Self Test a device. ID of the device needs to be provided
390 """
391 device_id = line or self.default_device_id
392 self.poutput('Self Testing {}'.format(device_id))
393 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400394 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530395 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
396 self.poutput('Self Tested {}'.format(device_id))
397 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700398 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530399 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
400
Khen Nursimulud068d812017-03-06 11:44:18 -0500401 def do_delete(self, line):
402 """
403 Deleting a device. ID of the device needs to be provided
404 """
405 device_id = line or self.default_device_id
406 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400407 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400408 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400409 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
410 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700411 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400412 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500413
414 def do_disable(self, line):
415 """
416 Disable a device. ID of the device needs to be provided
417 """
418 device_id = line
Venkata Teluf468de82018-08-07 13:03:58 -0500419 if device_id not in self.device_ids():
420 self.poutput('Error: There is no such device')
421 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400422 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400423 stub = self.get_stub()
Venkata Teluf468de82018-08-07 13:03:58 -0500424 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
425 if device.admin_state == voltha_pb2.AdminState.DISABLED:
426 self.poutput('Error: Device is already disabled')
427 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400428 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Venkata Teluf468de82018-08-07 13:03:58 -0500429 self.poutput('disabling {}'.format(device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500430
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400431 # Do device query and verify that the device admin status is
432 # DISABLED and Operational Status is unknown
433 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700434 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400435 self.poutput('disabled successfully {}'.format(device_id))
436 else:
437 self.poutput('disabling failed {}. Admin State:{} '
438 'Operation State: {}'.format(device_id,
439 device.admin_state,
440 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700441 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400442 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500443
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800444 def do_test(self, line):
445 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400446 sub = TestCli(self.history, self.voltha_grpc,
447 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800448 sub.cmdloop()
449
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400450 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400451 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400452 sub.cmdloop()
453
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800454
455class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400456 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800457 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
458 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400459 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800460 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400461 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800462
463 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400464 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800465 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400466 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800467 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800468
469 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800470 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800471 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800472 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800473 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800474
475 # verify that device is of type simulated_olt
476 device = self.get_device(device_id)
477 assert device.type == 'simulated_olt', (
478 'Cannot use it on this device type (only on simulated_olt type)')
479
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800480 requests.get('http://{}/devices/{}/detect_onus'.format(
481 self.voltha_sim_rest, device_id
482 ))
483
Zsolt Haraszti80175202016-12-24 00:17:51 -0800484 complete_arrive_onus = VolthaCli.complete_device
485
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800486 def get_logical_ports(self, logical_device_id):
487 """
488 Return the NNI port number and the first usable UNI port of logical
489 device, and the vlan associated with the latter.
490 """
khenaidoo108f05c2017-07-06 11:15:29 -0400491 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800492 ports = stub.ListLogicalDevicePorts(
493 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800494 nni = None
495 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800496 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800497 if port.root_port:
498 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800499 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800500 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800501 uni = port.ofp_port.port_no
502 uni_device = self.get_device(port.device_id)
503 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800504 unis.append((uni, vlan))
505
506 assert nni is not None, "No NNI port found"
507 assert unis, "Not a single UNI?"
508
509 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800510
Zsolt Haraszti80175202016-12-24 00:17:51 -0800511 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800512 """
513 Install an EAPOL flow on the given logical device. If device is not
514 given, it will be applied to logical device of the last pre-provisioned
515 OLT device.
516 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800517 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800518
519 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800520 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800521
522 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400523 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800524 for uni_port_no, _ in unis:
525 update = FlowTableUpdate(
526 id=logical_device_id,
527 flow_mod=mk_simple_flow_mod(
528 priority=2000,
529 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
530 actions=[
531 # push_vlan(0x8100),
532 # set_field(vlan_vid(4096 + 4000)),
533 output(ofp.OFPP_CONTROLLER)
534 ]
535 )
536 )
537 res = stub.UpdateLogicalDeviceFlowTable(update)
538 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800539
Zsolt Haraszti80175202016-12-24 00:17:51 -0800540 complete_install_eapol_flow = VolthaCli.complete_logical_device
541
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800542 def do_install_all_controller_bound_flows(self, line):
543 """
544 Install all flow rules for controller bound flows, including EAPOL,
545 IGMP and DHCP. If device is not given, it will be applied to logical
546 device of the last pre-provisioned OLT device.
547 """
548 logical_device_id = line or self.default_logical_device_id
549
550 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800551 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800552
553 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400554 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800555
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800556 for uni_port_no, _ in unis:
557 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
558 id=logical_device_id,
559 flow_mod=mk_simple_flow_mod(
560 priority=2000,
561 match_fields=[
562 in_port(uni_port_no),
563 eth_type(0x888e)
564 ],
565 actions=[output(ofp.OFPP_CONTROLLER)]
566 )
567 ))
568 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
569 id=logical_device_id,
570 flow_mod=mk_simple_flow_mod(
571 priority=1000,
572 match_fields=[
573 in_port(uni_port_no),
574 eth_type(0x800),
575 ip_proto(2)
576 ],
577 actions=[output(ofp.OFPP_CONTROLLER)]
578 )
579 ))
580 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
581 id=logical_device_id,
582 flow_mod=mk_simple_flow_mod(
583 priority=1000,
584 match_fields=[
585 in_port(uni_port_no),
586 eth_type(0x800),
587 ip_proto(17),
588 udp_dst(67)
589 ],
590 actions=[output(ofp.OFPP_CONTROLLER)]
591 )
592 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800593 self.poutput('success')
594
595 complete_install_all_controller_bound_flows = \
596 VolthaCli.complete_logical_device
597
598 def do_install_all_sample_flows(self, line):
599 """
600 Install all flows that are representative of the virtualized access
601 scenario in a PON network.
602 """
603 logical_device_id = line or self.default_logical_device_id
604
605 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800606 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800607
608 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400609 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800610
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800611 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800612 # Controller-bound flows
613 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
614 id=logical_device_id,
615 flow_mod=mk_simple_flow_mod(
616 priority=2000,
617 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
618 actions=[
619 # push_vlan(0x8100),
620 # set_field(vlan_vid(4096 + 4000)),
621 output(ofp.OFPP_CONTROLLER)
622 ]
623 )
624 ))
625 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
626 id=logical_device_id,
627 flow_mod=mk_simple_flow_mod(
628 priority=1000,
629 match_fields=[eth_type(0x800), ip_proto(2)],
630 actions=[output(ofp.OFPP_CONTROLLER)]
631 )
632 ))
633 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
634 id=logical_device_id,
635 flow_mod=mk_simple_flow_mod(
636 priority=1000,
637 match_fields=[eth_type(0x800), ip_proto(17), udp_dst(67)],
638 actions=[output(ofp.OFPP_CONTROLLER)]
639 )
640 ))
641
642 # Unicast flows:
643 # Downstream flow 1
644 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
645 id=logical_device_id,
646 flow_mod=mk_simple_flow_mod(
647 priority=500,
648 match_fields=[
649 in_port(nni_port_no),
650 vlan_vid(4096 + 1000),
651 metadata(c_vid) # here to mimic an ONOS artifact
652 ],
653 actions=[pop_vlan()],
654 next_table_id=1
655 )
656 ))
657 # Downstream flow 2
658 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
659 id=logical_device_id,
660 flow_mod=mk_simple_flow_mod(
661 priority=500,
662 table_id=1,
663 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
664 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
665 )
666 ))
667 # Upstream flow 1 for 0-tagged case
668 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
669 id=logical_device_id,
670 flow_mod=mk_simple_flow_mod(
671 priority=500,
672 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
673 actions=[set_field(vlan_vid(4096 + c_vid))],
674 next_table_id=1
675 )
676 ))
677 # Upstream flow 1 for untagged case
678 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
679 id=logical_device_id,
680 flow_mod=mk_simple_flow_mod(
681 priority=500,
682 match_fields=[in_port(uni_port_no), vlan_vid(0)],
683 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
684 next_table_id=1
685 )
686 ))
687 # Upstream flow 2 for s-tag
688 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
689 id=logical_device_id,
690 flow_mod=mk_simple_flow_mod(
691 priority=500,
692 table_id=1,
693 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
694 actions=[
695 push_vlan(0x8100),
696 set_field(vlan_vid(4096 + 1000)),
697 output(nni_port_no)
698 ]
699 )
700 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800701
702 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800703 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800704 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
705 id=logical_device_id,
706 group_mod=mk_multicast_group_mod(
707 group_id=1,
708 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800709 ofp.ofp_bucket(actions=[
710 pop_vlan(),
711 output(unis[0][0])
712 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800713 ]
714 )
715 ))
716 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
717 id=logical_device_id,
718 flow_mod=mk_simple_flow_mod(
719 priority=1000,
720 match_fields=[
721 in_port(nni_port_no),
722 eth_type(0x800),
723 vlan_vid(4096 + 140),
724 ipv4_dst(0xe4010101)
725 ],
726 actions=[group(1)]
727 )
728 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800729
730 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800731 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
732 id=logical_device_id,
733 group_mod=mk_multicast_group_mod(
734 group_id=2,
735 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800736 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400737 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800738 ]
739 )
740 ))
741 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
742 id=logical_device_id,
743 flow_mod=mk_simple_flow_mod(
744 priority=1000,
745 match_fields=[
746 in_port(nni_port_no),
747 eth_type(0x800),
748 vlan_vid(4096 + 140),
749 ipv4_dst(0xe4020202)
750 ],
751 actions=[group(2)]
752 )
753 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800754
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800755 # 3rd with empty bucket
756 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
757 id=logical_device_id,
758 group_mod=mk_multicast_group_mod(
759 group_id=3,
760 buckets=[]
761 )
762 ))
763 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
764 id=logical_device_id,
765 flow_mod=mk_simple_flow_mod(
766 priority=1000,
767 match_fields=[
768 in_port(nni_port_no),
769 eth_type(0x800),
770 vlan_vid(4096 + 140),
771 ipv4_dst(0xe4030303)
772 ],
773 actions=[group(3)]
774 )
775 ))
776
777 self.poutput('success')
778
779 complete_install_all_sample_flows = VolthaCli.complete_logical_device
780
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600781 def do_install_dhcp_flows(self, line):
782 """
783 Install all dhcp flows that are representative of the virtualized access
784 scenario in a PON network.
785 """
786 logical_device_id = line or self.default_logical_device_id
787
788 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800789 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600790
791 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400792 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600793
794 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800795 for uni_port_no, _ in unis:
796 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
797 id=logical_device_id,
798 flow_mod=mk_simple_flow_mod(
799 priority=1000,
800 match_fields=[
801 in_port(uni_port_no),
802 eth_type(0x800),
803 ip_proto(17),
804 udp_dst(67)
805 ],
806 actions=[output(ofp.OFPP_CONTROLLER)]
807 )
808 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600809
810 self.poutput('success')
811
812 complete_install_dhcp_flows = VolthaCli.complete_logical_device
813
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800814 def do_delete_all_flows(self, line):
815 """
816 Remove all flows and flow groups from given logical device
817 """
818 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400819 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800820 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
821 id=logical_device_id,
822 flow_mod=ofp.ofp_flow_mod(
823 command=ofp.OFPFC_DELETE,
824 table_id=ofp.OFPTT_ALL,
825 cookie_mask=0,
826 out_port=ofp.OFPP_ANY,
827 out_group=ofp.OFPG_ANY
828 )
829 ))
830 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
831 id=logical_device_id,
832 group_mod=ofp.ofp_group_mod(
833 command=ofp.OFPGC_DELETE,
834 group_id=ofp.OFPG_ALL
835 )
836 ))
837 self.poutput('success')
838
839 complete_delete_all_flows = VolthaCli.complete_logical_device
840
Zsolt Haraszti80175202016-12-24 00:17:51 -0800841 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800842 """
843 Send an EAPOL upstream from a simulated OLT
844 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800845 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800846 requests.get('http://{}/devices/{}/test_eapol_in'.format(
847 self.voltha_sim_rest, device_id
848 ))
849
Zsolt Haraszti80175202016-12-24 00:17:51 -0800850 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
851
852 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800853 """
854 Send out an an EAPOL start message into the given Unix interface
855 """
856 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800857
858
859if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800860
861 parser = argparse.ArgumentParser()
862
863 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
864 parser.add_argument(
865 '-C', '--consul', action='store', default=defs['consul'], help=_help)
866
867 _help = 'Lookup Voltha endpoints based on service entries in Consul'
868 parser.add_argument(
869 '-L', '--lookup', action='store_true', help=_help)
870
khenaidoo108f05c2017-07-06 11:15:29 -0400871 _help = 'All requests to the Voltha gRPC service are global'
872 parser.add_argument(
873 '-G', '--global_request', action='store_true', help=_help)
874
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800875 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
876 defs['voltha_grpc_endpoint'])
877 parser.add_argument('-g', '--grpc-endpoint', action='store',
878 default=defs['voltha_grpc_endpoint'], help=_help)
879
880 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
881 'testing (default={})'.format(
882 defs['voltha_sim_rest_endpoint'])
883 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
884 default=defs['voltha_sim_rest_endpoint'], help=_help)
885
886 args = parser.parse_args()
887
888 if args.lookup:
889 host = args.consul.split(':')[0].strip()
890 port = int(args.consul.split(':')[1].strip())
891 consul = Consul(host=host, port=port)
892
893 _, services = consul.catalog.service('voltha-grpc')
894 if not services:
895 print('No voltha-grpc service registered in consul; exiting')
896 sys.exit(1)
897 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
898 services[0]['ServicePort'])
899
900 _, services = consul.catalog.service('voltha-sim-rest')
901 if not services:
902 print('No voltha-sim-rest service registered in consul; exiting')
903 sys.exit(1)
904 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
905 services[0]['ServicePort'])
906
khenaidoo108f05c2017-07-06 11:15:29 -0400907 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
908 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800909 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800910 c.load_history()
911 c.cmdloop()
912 c.save_history()