blob: 6ca318ac43e4c7d11493119065e0f569f40aad29 [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:
Nicolas Palpacuer5807dfc2018-08-27 15:47:03 -0400353 if device.oper_status != voltha_pb2.OperStatus.ACTIVATING:
354 self.poutput('Error: Device is already enabled')
355 return
356 else:
357 stub.EnableDevice(voltha_pb2.ID(id=device_id))
358 self.poutput('enabling {}'.format(device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800359
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400360 while True:
361 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
362 # If this is an OLT then acquire logical device id
363 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
364 if device.type.endswith('_olt'):
365 assert device.parent_id
366 self.default_logical_device_id = device.parent_id
367 self.poutput('success (logical device id = {})'.format(
368 self.default_logical_device_id))
369 else:
370 self.poutput('success (device id = {})'.format(device.id))
371 break
372 self.poutput('waiting for device to be enabled...')
373 sleep(.5)
Chip Boling69abce82018-06-18 09:56:23 -0500374 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400375 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800376
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800377 complete_activate_olt = complete_device
378
Khen Nursimulud068d812017-03-06 11:44:18 -0500379 def do_reboot(self, line):
380 """
381 Rebooting a device. ID of the device needs to be provided
382 """
383 device_id = line or self.default_device_id
384 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400385 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400386 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400387 stub.RebootDevice(voltha_pb2.ID(id=device_id))
388 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700389 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400390 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500391
sathishg5ae86222017-06-28 15:16:29 +0530392 def do_self_test(self, line):
393 """
394 Self Test a device. ID of the device needs to be provided
395 """
396 device_id = line or self.default_device_id
397 self.poutput('Self Testing {}'.format(device_id))
398 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400399 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530400 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
401 self.poutput('Self Tested {}'.format(device_id))
402 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700403 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530404 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
405
Khen Nursimulud068d812017-03-06 11:44:18 -0500406 def do_delete(self, line):
407 """
408 Deleting a device. ID of the device needs to be provided
409 """
410 device_id = line or self.default_device_id
411 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400412 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400413 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400414 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
415 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700416 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400417 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500418
419 def do_disable(self, line):
420 """
421 Disable a device. ID of the device needs to be provided
422 """
423 device_id = line
Venkata Teluf468de82018-08-07 13:03:58 -0500424 if device_id not in self.device_ids():
425 self.poutput('Error: There is no such device')
426 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400427 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400428 stub = self.get_stub()
Venkata Teluf468de82018-08-07 13:03:58 -0500429 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
430 if device.admin_state == voltha_pb2.AdminState.DISABLED:
431 self.poutput('Error: Device is already disabled')
432 return
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400433 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Venkata Teluf468de82018-08-07 13:03:58 -0500434 self.poutput('disabling {}'.format(device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500435
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400436 # Do device query and verify that the device admin status is
437 # DISABLED and Operational Status is unknown
438 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700439 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400440 self.poutput('disabled successfully {}'.format(device_id))
441 else:
442 self.poutput('disabling failed {}. Admin State:{} '
443 'Operation State: {}'.format(device_id,
444 device.admin_state,
445 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700446 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400447 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500448
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800449 def do_test(self, line):
450 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400451 sub = TestCli(self.history, self.voltha_grpc,
452 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800453 sub.cmdloop()
454
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400455 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400456 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400457 sub.cmdloop()
458
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800459
460class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400461 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800462 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
463 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400464 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800465 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400466 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800467
468 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400469 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800470 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400471 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800472 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800473
474 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800475 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800476 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800477 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800478 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800479
480 # verify that device is of type simulated_olt
481 device = self.get_device(device_id)
482 assert device.type == 'simulated_olt', (
483 'Cannot use it on this device type (only on simulated_olt type)')
484
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800485 requests.get('http://{}/devices/{}/detect_onus'.format(
486 self.voltha_sim_rest, device_id
487 ))
488
Zsolt Haraszti80175202016-12-24 00:17:51 -0800489 complete_arrive_onus = VolthaCli.complete_device
490
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800491 def get_logical_ports(self, logical_device_id):
492 """
493 Return the NNI port number and the first usable UNI port of logical
494 device, and the vlan associated with the latter.
495 """
khenaidoo108f05c2017-07-06 11:15:29 -0400496 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800497 ports = stub.ListLogicalDevicePorts(
498 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800499 nni = None
500 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800501 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800502 if port.root_port:
503 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800504 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800505 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800506 uni = port.ofp_port.port_no
507 uni_device = self.get_device(port.device_id)
508 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800509 unis.append((uni, vlan))
510
511 assert nni is not None, "No NNI port found"
512 assert unis, "Not a single UNI?"
513
514 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800515
Zsolt Haraszti80175202016-12-24 00:17:51 -0800516 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800517 """
518 Install an EAPOL flow on the given logical device. If device is not
519 given, it will be applied to logical device of the last pre-provisioned
520 OLT device.
521 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800522 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800523
524 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800525 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800526
527 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400528 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800529 for uni_port_no, _ in unis:
530 update = FlowTableUpdate(
531 id=logical_device_id,
532 flow_mod=mk_simple_flow_mod(
533 priority=2000,
534 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
535 actions=[
536 # push_vlan(0x8100),
537 # set_field(vlan_vid(4096 + 4000)),
538 output(ofp.OFPP_CONTROLLER)
539 ]
540 )
541 )
542 res = stub.UpdateLogicalDeviceFlowTable(update)
543 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800544
Zsolt Haraszti80175202016-12-24 00:17:51 -0800545 complete_install_eapol_flow = VolthaCli.complete_logical_device
546
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800547 def do_install_all_controller_bound_flows(self, line):
548 """
549 Install all flow rules for controller bound flows, including EAPOL,
550 IGMP and DHCP. If device is not given, it will be applied to logical
551 device of the last pre-provisioned OLT device.
552 """
553 logical_device_id = line or self.default_logical_device_id
554
555 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800556 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800557
558 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400559 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800560
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800561 for uni_port_no, _ in unis:
562 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
563 id=logical_device_id,
564 flow_mod=mk_simple_flow_mod(
565 priority=2000,
566 match_fields=[
567 in_port(uni_port_no),
568 eth_type(0x888e)
569 ],
570 actions=[output(ofp.OFPP_CONTROLLER)]
571 )
572 ))
573 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
574 id=logical_device_id,
575 flow_mod=mk_simple_flow_mod(
576 priority=1000,
577 match_fields=[
578 in_port(uni_port_no),
579 eth_type(0x800),
580 ip_proto(2)
581 ],
582 actions=[output(ofp.OFPP_CONTROLLER)]
583 )
584 ))
585 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
586 id=logical_device_id,
587 flow_mod=mk_simple_flow_mod(
588 priority=1000,
589 match_fields=[
590 in_port(uni_port_no),
591 eth_type(0x800),
592 ip_proto(17),
593 udp_dst(67)
594 ],
595 actions=[output(ofp.OFPP_CONTROLLER)]
596 )
597 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800598 self.poutput('success')
599
600 complete_install_all_controller_bound_flows = \
601 VolthaCli.complete_logical_device
602
603 def do_install_all_sample_flows(self, line):
604 """
605 Install all flows that are representative of the virtualized access
606 scenario in a PON network.
607 """
608 logical_device_id = line or self.default_logical_device_id
609
610 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800611 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800612
613 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400614 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800615
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800616 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800617 # Controller-bound flows
618 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
619 id=logical_device_id,
620 flow_mod=mk_simple_flow_mod(
621 priority=2000,
622 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
623 actions=[
624 # push_vlan(0x8100),
625 # set_field(vlan_vid(4096 + 4000)),
626 output(ofp.OFPP_CONTROLLER)
627 ]
628 )
629 ))
630 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
631 id=logical_device_id,
632 flow_mod=mk_simple_flow_mod(
633 priority=1000,
634 match_fields=[eth_type(0x800), ip_proto(2)],
635 actions=[output(ofp.OFPP_CONTROLLER)]
636 )
637 ))
638 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
639 id=logical_device_id,
640 flow_mod=mk_simple_flow_mod(
641 priority=1000,
642 match_fields=[eth_type(0x800), ip_proto(17), udp_dst(67)],
643 actions=[output(ofp.OFPP_CONTROLLER)]
644 )
645 ))
646
647 # Unicast flows:
648 # Downstream flow 1
649 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
650 id=logical_device_id,
651 flow_mod=mk_simple_flow_mod(
652 priority=500,
653 match_fields=[
654 in_port(nni_port_no),
655 vlan_vid(4096 + 1000),
656 metadata(c_vid) # here to mimic an ONOS artifact
657 ],
658 actions=[pop_vlan()],
659 next_table_id=1
660 )
661 ))
662 # Downstream flow 2
663 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
664 id=logical_device_id,
665 flow_mod=mk_simple_flow_mod(
666 priority=500,
667 table_id=1,
668 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
669 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
670 )
671 ))
672 # Upstream flow 1 for 0-tagged case
673 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
674 id=logical_device_id,
675 flow_mod=mk_simple_flow_mod(
676 priority=500,
677 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
678 actions=[set_field(vlan_vid(4096 + c_vid))],
679 next_table_id=1
680 )
681 ))
682 # Upstream flow 1 for untagged case
683 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
684 id=logical_device_id,
685 flow_mod=mk_simple_flow_mod(
686 priority=500,
687 match_fields=[in_port(uni_port_no), vlan_vid(0)],
688 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
689 next_table_id=1
690 )
691 ))
692 # Upstream flow 2 for s-tag
693 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
694 id=logical_device_id,
695 flow_mod=mk_simple_flow_mod(
696 priority=500,
697 table_id=1,
698 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
699 actions=[
700 push_vlan(0x8100),
701 set_field(vlan_vid(4096 + 1000)),
702 output(nni_port_no)
703 ]
704 )
705 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800706
707 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800708 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800709 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
710 id=logical_device_id,
711 group_mod=mk_multicast_group_mod(
712 group_id=1,
713 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800714 ofp.ofp_bucket(actions=[
715 pop_vlan(),
716 output(unis[0][0])
717 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800718 ]
719 )
720 ))
721 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
722 id=logical_device_id,
723 flow_mod=mk_simple_flow_mod(
724 priority=1000,
725 match_fields=[
726 in_port(nni_port_no),
727 eth_type(0x800),
728 vlan_vid(4096 + 140),
729 ipv4_dst(0xe4010101)
730 ],
731 actions=[group(1)]
732 )
733 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800734
735 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800736 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
737 id=logical_device_id,
738 group_mod=mk_multicast_group_mod(
739 group_id=2,
740 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800741 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400742 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800743 ]
744 )
745 ))
746 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
747 id=logical_device_id,
748 flow_mod=mk_simple_flow_mod(
749 priority=1000,
750 match_fields=[
751 in_port(nni_port_no),
752 eth_type(0x800),
753 vlan_vid(4096 + 140),
754 ipv4_dst(0xe4020202)
755 ],
756 actions=[group(2)]
757 )
758 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800759
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800760 # 3rd with empty bucket
761 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
762 id=logical_device_id,
763 group_mod=mk_multicast_group_mod(
764 group_id=3,
765 buckets=[]
766 )
767 ))
768 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
769 id=logical_device_id,
770 flow_mod=mk_simple_flow_mod(
771 priority=1000,
772 match_fields=[
773 in_port(nni_port_no),
774 eth_type(0x800),
775 vlan_vid(4096 + 140),
776 ipv4_dst(0xe4030303)
777 ],
778 actions=[group(3)]
779 )
780 ))
781
782 self.poutput('success')
783
784 complete_install_all_sample_flows = VolthaCli.complete_logical_device
785
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600786 def do_install_dhcp_flows(self, line):
787 """
788 Install all dhcp flows that are representative of the virtualized access
789 scenario in a PON network.
790 """
791 logical_device_id = line or self.default_logical_device_id
792
793 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800794 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600795
796 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400797 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600798
799 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800800 for uni_port_no, _ in unis:
801 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
802 id=logical_device_id,
803 flow_mod=mk_simple_flow_mod(
804 priority=1000,
805 match_fields=[
806 in_port(uni_port_no),
807 eth_type(0x800),
808 ip_proto(17),
809 udp_dst(67)
810 ],
811 actions=[output(ofp.OFPP_CONTROLLER)]
812 )
813 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600814
815 self.poutput('success')
816
817 complete_install_dhcp_flows = VolthaCli.complete_logical_device
818
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800819 def do_delete_all_flows(self, line):
820 """
821 Remove all flows and flow groups from given logical device
822 """
823 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400824 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800825 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
826 id=logical_device_id,
827 flow_mod=ofp.ofp_flow_mod(
828 command=ofp.OFPFC_DELETE,
829 table_id=ofp.OFPTT_ALL,
830 cookie_mask=0,
831 out_port=ofp.OFPP_ANY,
832 out_group=ofp.OFPG_ANY
833 )
834 ))
835 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
836 id=logical_device_id,
837 group_mod=ofp.ofp_group_mod(
838 command=ofp.OFPGC_DELETE,
839 group_id=ofp.OFPG_ALL
840 )
841 ))
842 self.poutput('success')
843
844 complete_delete_all_flows = VolthaCli.complete_logical_device
845
Zsolt Haraszti80175202016-12-24 00:17:51 -0800846 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800847 """
848 Send an EAPOL upstream from a simulated OLT
849 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800850 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800851 requests.get('http://{}/devices/{}/test_eapol_in'.format(
852 self.voltha_sim_rest, device_id
853 ))
854
Zsolt Haraszti80175202016-12-24 00:17:51 -0800855 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
856
857 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800858 """
859 Send out an an EAPOL start message into the given Unix interface
860 """
861 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800862
863
864if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800865
866 parser = argparse.ArgumentParser()
867
868 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
869 parser.add_argument(
870 '-C', '--consul', action='store', default=defs['consul'], help=_help)
871
872 _help = 'Lookup Voltha endpoints based on service entries in Consul'
873 parser.add_argument(
874 '-L', '--lookup', action='store_true', help=_help)
875
khenaidoo108f05c2017-07-06 11:15:29 -0400876 _help = 'All requests to the Voltha gRPC service are global'
877 parser.add_argument(
878 '-G', '--global_request', action='store_true', help=_help)
879
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800880 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
881 defs['voltha_grpc_endpoint'])
882 parser.add_argument('-g', '--grpc-endpoint', action='store',
883 default=defs['voltha_grpc_endpoint'], help=_help)
884
885 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
886 'testing (default={})'.format(
887 defs['voltha_sim_rest_endpoint'])
888 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
889 default=defs['voltha_sim_rest_endpoint'], help=_help)
890
891 args = parser.parse_args()
892
893 if args.lookup:
894 host = args.consul.split(':')[0].strip()
895 port = int(args.consul.split(':')[1].strip())
896 consul = Consul(host=host, port=port)
897
898 _, services = consul.catalog.service('voltha-grpc')
899 if not services:
900 print('No voltha-grpc service registered in consul; exiting')
901 sys.exit(1)
902 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
903 services[0]['ServicePort'])
904
905 _, services = consul.catalog.service('voltha-sim-rest')
906 if not services:
907 print('No voltha-sim-rest service registered in consul; exiting')
908 sys.exit(1)
909 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
910 services[0]['ServicePort'])
911
khenaidoo108f05c2017-07-06 11:15:29 -0400912 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
913 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800914 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800915 c.load_history()
916 c.cmdloop()
917 c.save_history()