blob: 544b774caf1ed3169eeb4306ead90868dcbfbeea [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
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040033from cli.alarm_filters import AlarmFiltersCli
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080034from cli.logical_device import LogicalDeviceCli
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040035from cli.table import print_pb_list_as_table
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080036from voltha.core.flow_decomposer import *
Zsolt Harasztia133a452016-12-22 01:26:57 -080037from voltha.protos import third_party
38from voltha.protos import voltha_pb2
Zsolt Haraszti85f12852016-12-24 08:30:58 -080039from voltha.protos.openflow_13_pb2 import FlowTableUpdate, FlowGroupTableUpdate
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080040
Zsolt Harasztia133a452016-12-22 01:26:57 -080041_ = third_party
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040042from cli.utils import pb2dict
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080043
44defs = dict(
45 # config=os.environ.get('CONFIG', './cli.yml'),
46 consul=os.environ.get('CONSUL', 'localhost:8500'),
47 voltha_grpc_endpoint=os.environ.get('VOLTHA_GRPC_ENDPOINT',
48 'localhost:50055'),
49 voltha_sim_rest_endpoint=os.environ.get('VOLTHA_SIM_REST_ENDPOINT',
50 'localhost:18880'),
khenaidoo108f05c2017-07-06 11:15:29 -040051 global_request=os.environ.get('GLOBAL_REQUEST', False)
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080052)
53
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080054banner = """\
Zsolt Haraszti313c4be2016-12-27 11:06:53 -080055 _ _ _ ___ _ ___
56__ _____| | |_| |_ __ _ / __| | |_ _|
57\ V / _ \ | _| ' \/ _` | | (__| |__ | |
58 \_/\___/_|\__|_||_\__,_| \___|____|___|
Zsolt Haraszti80175202016-12-24 00:17:51 -080059(to exit type quit or hit Ctrl-D)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080060"""
Zsolt Harasztia133a452016-12-22 01:26:57 -080061
Zsolt Harasztia133a452016-12-22 01:26:57 -080062
Stephane Barbarie4db8ca22017-04-24 10:30:20 -040063class VolthaCli(Cmd):
Zsolt Harasztia133a452016-12-22 01:26:57 -080064 prompt = 'voltha'
65 history_file_name = '.voltha_cli_history'
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080066
67 # Settable CLI parameters
68 voltha_grpc = 'localhost:50055'
69 voltha_sim_rest = 'localhost:18880'
khenaidoo108f05c2017-07-06 11:15:29 -040070 global_request = False
Zsolt Harasztia133a452016-12-22 01:26:57 -080071 max_history_lines = 500
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080072 default_device_id = None
73 default_logical_device_id = None
Zsolt Harasztia133a452016-12-22 01:26:57 -080074
75 Cmd.settable.update(dict(
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080076 voltha_grpc='Voltha GRPC endpoint in form of <host>:<port>',
77 voltha_sim_rest='Voltha simulation back door for testing in form '
78 'of <host>:<port>',
79 max_history_lines='Maximum number of history lines stored across '
80 'sessions',
81 default_device_id='Device id used when no device id is specified',
82 default_logical_device_id='Logical device id used when no device id '
83 'is specified',
Zsolt Harasztia133a452016-12-22 01:26:57 -080084 ))
85
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080086 # cleanup of superfluous commands from cmd2
Zsolt Haraszti80175202016-12-24 00:17:51 -080087 del Cmd.do_cmdenvironment
Steve Crooks05f24522017-02-27 13:32:27 -050088 del Cmd.do_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080089 del Cmd.do__relative_load
Zsolt Haraszti80175202016-12-24 00:17:51 -080090
khenaidoo108f05c2017-07-06 11:15:29 -040091 def __init__(self, voltha_grpc, voltha_sim_rest, global_request=False):
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080092 VolthaCli.voltha_grpc = voltha_grpc
93 VolthaCli.voltha_sim_rest = voltha_sim_rest
khenaidoo108f05c2017-07-06 11:15:29 -040094 VolthaCli.global_request = global_request
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080095 Cmd.__init__(self)
Zsolt Harasztia133a452016-12-22 01:26:57 -080096 self.prompt = '(' + self.colorize(
Zsolt Haraszti80175202016-12-24 00:17:51 -080097 self.colorize(self.prompt, 'blue'), 'bold') + ') '
Zsolt Harasztia133a452016-12-22 01:26:57 -080098 self.channel = None
khenaidoo108f05c2017-07-06 11:15:29 -040099 self.stub = None
Zsolt Haraszti80175202016-12-24 00:17:51 -0800100 self.device_ids_cache = None
101 self.device_ids_cache_ts = time()
102 self.logical_device_ids_cache = None
103 self.logical_device_ids_cache_ts = time()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800104
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800105 # we override cmd2's method to avoid its optparse conflicting with our
106 # command line parsing
107 def cmdloop(self):
108 self._cmdloop()
109
Zsolt Harasztia133a452016-12-22 01:26:57 -0800110 def load_history(self):
111 """Load saved command history from local history file"""
112 try:
113 with file(self.history_file_name, 'r') as f:
114 for line in f.readlines():
115 stripped_line = line.strip()
116 self.history.append(stripped_line)
117 readline.add_history(stripped_line)
118 except IOError:
119 pass # ignore if file cannot be read
120
121 def save_history(self):
122 try:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800123 with open(self.history_file_name, 'w') as f:
Zsolt Harasztia133a452016-12-22 01:26:57 -0800124 f.write('\n'.join(self.history[-self.max_history_lines:]))
Zsolt Haraszti80175202016-12-24 00:17:51 -0800125 except IOError as e:
126 self.perror('Could not save history in {}: {}'.format(
127 self.history_file_name, e))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800128 else:
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800129 self.poutput('History saved as {}'.format(
Zsolt Haraszti80175202016-12-24 00:17:51 -0800130 self.history_file_name))
131
132 def perror(self, errmsg, statement=None):
133 # Touch it up to make sure error is prefixed and colored
134 Cmd.perror(self, self.colorize('***ERROR: ', 'red') + errmsg,
135 statement)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800136
137 def get_channel(self):
138 if self.channel is None:
139 self.channel = grpc.insecure_channel(self.voltha_grpc)
140 return self.channel
141
khenaidoo108f05c2017-07-06 11:15:29 -0400142 def get_stub(self):
143 if self.stub is None:
144 self.stub = \
145 voltha_pb2.VolthaGlobalServiceStub(self.get_channel()) \
146 if self.global_request else \
147 voltha_pb2.VolthaLocalServiceStub(self.get_channel())
148 return self.stub
149
Zsolt Haraszti80175202016-12-24 00:17:51 -0800150 # ~~~~~~~~~~~~~~~~~ ACTUAL COMMAND IMPLEMENTATIONS ~~~~~~~~~~~~~~~~~~~~~~~~
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800151
Zsolt Haraszti80175202016-12-24 00:17:51 -0800152 def do_reset_history(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800153 """Reset CLI history"""
154 while self.history:
155 self.history.pop()
156
Zsolt Haraszti80175202016-12-24 00:17:51 -0800157 def do_launch(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800158 """If Voltha is not running yet, launch it"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800159 raise NotImplementedError('not implemented yet')
Zsolt Harasztia133a452016-12-22 01:26:57 -0800160
Zsolt Haraszti80175202016-12-24 00:17:51 -0800161 def do_restart(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800162 """Launch Voltha, but if it is already running, terminate it first"""
163 pass
164
Zsolt Haraszti80175202016-12-24 00:17:51 -0800165 def do_adapters(self, line):
166 """List loaded adapter"""
khenaidoo108f05c2017-07-06 11:15:29 -0400167 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800168 res = stub.ListAdapters(Empty())
Sergio Slobodrian6e9fb692017-03-17 14:46:33 -0400169 omit_fields = {'config.log_level', 'logical_device_ids'}
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800170 print_pb_list_as_table('Adapters:', res.items, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800171
172 def get_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400173 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800174 res = stub.ListDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800175 return res.items
Zsolt Harasztia133a452016-12-22 01:26:57 -0800176
Zsolt Haraszti80175202016-12-24 00:17:51 -0800177 def get_logical_devices(self):
khenaidoo108f05c2017-07-06 11:15:29 -0400178 stub = self.get_stub()
Zsolt Haraszti80175202016-12-24 00:17:51 -0800179 res = stub.ListLogicalDevices(Empty())
180 return res.items
181
182 def do_devices(self, line):
183 """List devices registered in Voltha"""
184 devices = self.get_devices()
185 omit_fields = {
186 'adapter',
187 'vendor',
188 'model',
189 'hardware_version',
ggowdru236bd952017-06-20 20:32:55 -0700190 'images',
Zsolt Haraszti80175202016-12-24 00:17:51 -0800191 'firmware_version',
Sergio Slobodriana95f99b2017-03-21 10:22:47 -0400192 'serial_number'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800193 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800194 print_pb_list_as_table('Devices:', devices, omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800195
196 def do_logical_devices(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800197 """List logical devices in Voltha"""
khenaidoo108f05c2017-07-06 11:15:29 -0400198 stub = self.get_stub()
Zsolt Harasztia133a452016-12-22 01:26:57 -0800199 res = stub.ListLogicalDevices(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800200 omit_fields = {
201 'desc.mfr_desc',
202 'desc.hw_desc',
203 'desc.sw_desc',
204 'desc.dp_desc',
205 'desc.serial_number',
Sergio Slobodriana95f99b2017-03-21 10:22:47 -0400206 'switch_features.capabilities'
Zsolt Haraszti80175202016-12-24 00:17:51 -0800207 }
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800208 print_pb_list_as_table('Logical devices:', res.items, omit_fields,
209 self.poutput)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800210
Zsolt Haraszti80175202016-12-24 00:17:51 -0800211 def do_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800212 """Enter device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800213 device_id = line.strip() or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800214 if not device_id:
215 raise Exception('<device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500216 if device_id not in self.device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500217 self.poutput( self.colorize('Error: ', 'red') +
218 'There is no such device')
219 raise Exception('<device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400220 sub = DeviceCli(device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800221 sub.cmdloop()
222
Zsolt Haraszti80175202016-12-24 00:17:51 -0800223 def do_logical_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800224 """Enter logical device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800225 logical_device_id = line.strip() or self.default_logical_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800226 if not logical_device_id:
227 raise Exception('<logical-device-id> parameter needed')
Venkata Telu133b27d2018-06-12 14:22:28 -0500228 if logical_device_id not in self.logical_device_ids():
Venkata Telu35cc4722018-06-01 12:05:30 -0500229 self.poutput( self.colorize('Error: ', 'red') +
230 'There is no such device')
231 raise Exception('<logical-device-id> is not a valid one')
khenaidoo108f05c2017-07-06 11:15:29 -0400232 sub = LogicalDeviceCli(logical_device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800233 sub.cmdloop()
234
Zsolt Haraszti80175202016-12-24 00:17:51 -0800235 def device_ids(self, force_refresh=False):
236 if force_refresh or self.device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400237 (time() - self.device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800238 self.device_ids_cache = [d.id for d in self.get_devices()]
239 self.device_ids_cache_ts = time()
240 return self.device_ids_cache
241
242 def logical_device_ids(self, force_refresh=False):
243 if force_refresh or self.logical_device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400244 (time() - self.logical_device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800245 self.logical_device_ids_cache = [d.id for d
246 in self.get_logical_devices()]
247 self.logical_device_ids_cache_ts = time()
248 return self.logical_device_ids_cache
249
250 def complete_device(self, text, line, begidx, endidx):
251 if not text:
252 completions = self.device_ids()[:]
253 else:
254 completions = [d for d in self.device_ids() if d.startswith(text)]
255 return completions
256
257 def complete_logical_device(self, text, line, begidx, endidx):
258 if not text:
259 completions = self.logical_device_ids()[:]
260 else:
261 completions = [d for d in self.logical_device_ids()
262 if d.startswith(text)]
263 return completions
264
Nikolay Titov89004ec2017-06-19 18:22:42 -0400265 def do_xpon(self, line):
266 """xpon <optional> [device_ID] - Enter xpon level command mode"""
267 device_id = line.strip()
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400268 if device_id:
269 stub = self.get_stub()
270 try:
271 res = stub.GetDevice(voltha_pb2.ID(id=device_id))
272 except Exception:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400273 self.poutput(
274 self.colorize('Error: ', 'red') + 'No device id ' +
275 self.colorize(device_id, 'blue') + ' is found')
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400276 return
277 sub = XponCli(self.get_channel, device_id)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400278 sub.cmdloop()
279
Zsolt Haraszti80175202016-12-24 00:17:51 -0800280 def do_pdb(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800281 """Launch PDB debug prompt in CLI (for CLI development)"""
282 from pdb import set_trace
283 set_trace()
284
Jonathan Hartda93ac62018-05-01 11:25:29 -0700285 def do_version(self, line):
286 """Show the VOLTHA core version"""
287 stub = self.get_stub()
288 voltha = stub.GetVoltha(Empty())
289 self.poutput('{}'.format(voltha.version))
290
Zsolt Haraszti80175202016-12-24 00:17:51 -0800291 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800292 """Show connectivity status to Voltha status"""
293 stub = voltha_pb2.HealthServiceStub(self.get_channel())
294 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800295 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800296
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800297 @options([
298 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400299 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800300 make_option('-m', '--mac-address', action='store', dest='mac_address',
301 default='00:0c:e2:31:40:00'),
302 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800303 make_option('-H', '--host_and_port', action='store',
304 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800305 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800306 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800307 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400308 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800309 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800310 if opts.host_and_port:
311 kw['host_and_port'] = opts.host_and_port
312 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800313 kw['ipv4_address'] = opts.ip_address
314 elif opts.mac_address:
315 kw['mac_address'] = opts.mac_address
316 else:
317 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500318 # Pass any extra arguments past '--' to the device as custom arguments
319 kw['extra_args'] = line
320
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800321 device = voltha_pb2.Device(**kw)
322 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800323 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800324 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800325
Khen Nursimulud068d812017-03-06 11:44:18 -0500326 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800327 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500328 Enable a device. If the <id> is not provided, it will be on the last
329 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800330 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800331 device_id = line or self.default_device_id
Khen Nursimulu29e75502017-03-07 17:26:50 -0500332 self.poutput('enabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400333 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400334 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400335 stub.EnableDevice(voltha_pb2.ID(id=device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800336
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400337 while True:
338 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
339 # If this is an OLT then acquire logical device id
340 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
341 if device.type.endswith('_olt'):
342 assert device.parent_id
343 self.default_logical_device_id = device.parent_id
344 self.poutput('success (logical device id = {})'.format(
345 self.default_logical_device_id))
346 else:
347 self.poutput('success (device id = {})'.format(device.id))
348 break
349 self.poutput('waiting for device to be enabled...')
350 sleep(.5)
ggowdru64d738a2018-05-10 07:08:06 -0700351 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400352 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800353
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800354 complete_activate_olt = complete_device
355
Khen Nursimulud068d812017-03-06 11:44:18 -0500356 def do_reboot(self, line):
357 """
358 Rebooting a device. ID of the device needs to be provided
359 """
360 device_id = line or self.default_device_id
361 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400362 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400363 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400364 stub.RebootDevice(voltha_pb2.ID(id=device_id))
365 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700366 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400367 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500368
sathishg5ae86222017-06-28 15:16:29 +0530369 def do_self_test(self, line):
370 """
371 Self Test a device. ID of the device needs to be provided
372 """
373 device_id = line or self.default_device_id
374 self.poutput('Self Testing {}'.format(device_id))
375 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400376 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530377 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
378 self.poutput('Self Tested {}'.format(device_id))
379 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700380 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530381 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
382
Khen Nursimulud068d812017-03-06 11:44:18 -0500383 def do_delete(self, line):
384 """
385 Deleting a device. ID of the device needs to be provided
386 """
387 device_id = line or self.default_device_id
388 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400389 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400390 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400391 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
392 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700393 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400394 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500395
396 def do_disable(self, line):
397 """
398 Disable a device. ID of the device needs to be provided
399 """
400 device_id = line
401 self.poutput('disabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400402 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400403 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400404 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500405
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400406 # Do device query and verify that the device admin status is
407 # DISABLED and Operational Status is unknown
408 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700409 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400410 self.poutput('disabled successfully {}'.format(device_id))
411 else:
412 self.poutput('disabling failed {}. Admin State:{} '
413 'Operation State: {}'.format(device_id,
414 device.admin_state,
415 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700416 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400417 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500418
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800419 def do_test(self, line):
420 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400421 sub = TestCli(self.history, self.voltha_grpc,
422 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800423 sub.cmdloop()
424
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400425 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400426 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400427 sub.cmdloop()
428
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800429
430class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400431 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800432 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
433 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400434 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800435 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400436 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800437
438 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400439 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800440 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400441 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800442 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800443
444 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800445 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800446 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800447 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800448 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800449
450 # verify that device is of type simulated_olt
451 device = self.get_device(device_id)
452 assert device.type == 'simulated_olt', (
453 'Cannot use it on this device type (only on simulated_olt type)')
454
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800455 requests.get('http://{}/devices/{}/detect_onus'.format(
456 self.voltha_sim_rest, device_id
457 ))
458
Zsolt Haraszti80175202016-12-24 00:17:51 -0800459 complete_arrive_onus = VolthaCli.complete_device
460
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800461 def get_logical_ports(self, logical_device_id):
462 """
463 Return the NNI port number and the first usable UNI port of logical
464 device, and the vlan associated with the latter.
465 """
khenaidoo108f05c2017-07-06 11:15:29 -0400466 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800467 ports = stub.ListLogicalDevicePorts(
468 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800469 nni = None
470 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800471 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800472 if port.root_port:
473 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800474 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800475 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800476 uni = port.ofp_port.port_no
477 uni_device = self.get_device(port.device_id)
478 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800479 unis.append((uni, vlan))
480
481 assert nni is not None, "No NNI port found"
482 assert unis, "Not a single UNI?"
483
484 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800485
Zsolt Haraszti80175202016-12-24 00:17:51 -0800486 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800487 """
488 Install an EAPOL flow on the given logical device. If device is not
489 given, it will be applied to logical device of the last pre-provisioned
490 OLT device.
491 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800492 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800493
494 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800495 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800496
497 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400498 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800499 for uni_port_no, _ in unis:
500 update = FlowTableUpdate(
501 id=logical_device_id,
502 flow_mod=mk_simple_flow_mod(
503 priority=2000,
504 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
505 actions=[
506 # push_vlan(0x8100),
507 # set_field(vlan_vid(4096 + 4000)),
508 output(ofp.OFPP_CONTROLLER)
509 ]
510 )
511 )
512 res = stub.UpdateLogicalDeviceFlowTable(update)
513 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800514
Zsolt Haraszti80175202016-12-24 00:17:51 -0800515 complete_install_eapol_flow = VolthaCli.complete_logical_device
516
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800517 def do_install_all_controller_bound_flows(self, line):
518 """
519 Install all flow rules for controller bound flows, including EAPOL,
520 IGMP and DHCP. If device is not given, it will be applied to logical
521 device of the last pre-provisioned OLT device.
522 """
523 logical_device_id = line or self.default_logical_device_id
524
525 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800526 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800527
528 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400529 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800530
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800531 for uni_port_no, _ in unis:
532 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
533 id=logical_device_id,
534 flow_mod=mk_simple_flow_mod(
535 priority=2000,
536 match_fields=[
537 in_port(uni_port_no),
538 eth_type(0x888e)
539 ],
540 actions=[output(ofp.OFPP_CONTROLLER)]
541 )
542 ))
543 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
544 id=logical_device_id,
545 flow_mod=mk_simple_flow_mod(
546 priority=1000,
547 match_fields=[
548 in_port(uni_port_no),
549 eth_type(0x800),
550 ip_proto(2)
551 ],
552 actions=[output(ofp.OFPP_CONTROLLER)]
553 )
554 ))
555 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
556 id=logical_device_id,
557 flow_mod=mk_simple_flow_mod(
558 priority=1000,
559 match_fields=[
560 in_port(uni_port_no),
561 eth_type(0x800),
562 ip_proto(17),
563 udp_dst(67)
564 ],
565 actions=[output(ofp.OFPP_CONTROLLER)]
566 )
567 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800568 self.poutput('success')
569
570 complete_install_all_controller_bound_flows = \
571 VolthaCli.complete_logical_device
572
573 def do_install_all_sample_flows(self, line):
574 """
575 Install all flows that are representative of the virtualized access
576 scenario in a PON network.
577 """
578 logical_device_id = line or self.default_logical_device_id
579
580 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800581 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800582
583 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400584 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800585
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800586 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800587 # Controller-bound flows
588 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
589 id=logical_device_id,
590 flow_mod=mk_simple_flow_mod(
591 priority=2000,
592 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
593 actions=[
594 # push_vlan(0x8100),
595 # set_field(vlan_vid(4096 + 4000)),
596 output(ofp.OFPP_CONTROLLER)
597 ]
598 )
599 ))
600 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
601 id=logical_device_id,
602 flow_mod=mk_simple_flow_mod(
603 priority=1000,
604 match_fields=[eth_type(0x800), ip_proto(2)],
605 actions=[output(ofp.OFPP_CONTROLLER)]
606 )
607 ))
608 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
609 id=logical_device_id,
610 flow_mod=mk_simple_flow_mod(
611 priority=1000,
612 match_fields=[eth_type(0x800), ip_proto(17), udp_dst(67)],
613 actions=[output(ofp.OFPP_CONTROLLER)]
614 )
615 ))
616
617 # Unicast flows:
618 # Downstream flow 1
619 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
620 id=logical_device_id,
621 flow_mod=mk_simple_flow_mod(
622 priority=500,
623 match_fields=[
624 in_port(nni_port_no),
625 vlan_vid(4096 + 1000),
626 metadata(c_vid) # here to mimic an ONOS artifact
627 ],
628 actions=[pop_vlan()],
629 next_table_id=1
630 )
631 ))
632 # Downstream flow 2
633 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
634 id=logical_device_id,
635 flow_mod=mk_simple_flow_mod(
636 priority=500,
637 table_id=1,
638 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
639 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
640 )
641 ))
642 # Upstream flow 1 for 0-tagged case
643 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
644 id=logical_device_id,
645 flow_mod=mk_simple_flow_mod(
646 priority=500,
647 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
648 actions=[set_field(vlan_vid(4096 + c_vid))],
649 next_table_id=1
650 )
651 ))
652 # Upstream flow 1 for untagged case
653 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
654 id=logical_device_id,
655 flow_mod=mk_simple_flow_mod(
656 priority=500,
657 match_fields=[in_port(uni_port_no), vlan_vid(0)],
658 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
659 next_table_id=1
660 )
661 ))
662 # Upstream flow 2 for s-tag
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(uni_port_no), vlan_vid(4096 + c_vid)],
669 actions=[
670 push_vlan(0x8100),
671 set_field(vlan_vid(4096 + 1000)),
672 output(nni_port_no)
673 ]
674 )
675 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800676
677 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800678 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800679 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
680 id=logical_device_id,
681 group_mod=mk_multicast_group_mod(
682 group_id=1,
683 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800684 ofp.ofp_bucket(actions=[
685 pop_vlan(),
686 output(unis[0][0])
687 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800688 ]
689 )
690 ))
691 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
692 id=logical_device_id,
693 flow_mod=mk_simple_flow_mod(
694 priority=1000,
695 match_fields=[
696 in_port(nni_port_no),
697 eth_type(0x800),
698 vlan_vid(4096 + 140),
699 ipv4_dst(0xe4010101)
700 ],
701 actions=[group(1)]
702 )
703 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800704
705 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800706 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
707 id=logical_device_id,
708 group_mod=mk_multicast_group_mod(
709 group_id=2,
710 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800711 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400712 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
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(0xe4020202)
725 ],
726 actions=[group(2)]
727 )
728 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800729
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800730 # 3rd with empty bucket
731 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
732 id=logical_device_id,
733 group_mod=mk_multicast_group_mod(
734 group_id=3,
735 buckets=[]
736 )
737 ))
738 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
739 id=logical_device_id,
740 flow_mod=mk_simple_flow_mod(
741 priority=1000,
742 match_fields=[
743 in_port(nni_port_no),
744 eth_type(0x800),
745 vlan_vid(4096 + 140),
746 ipv4_dst(0xe4030303)
747 ],
748 actions=[group(3)]
749 )
750 ))
751
752 self.poutput('success')
753
754 complete_install_all_sample_flows = VolthaCli.complete_logical_device
755
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600756 def do_install_dhcp_flows(self, line):
757 """
758 Install all dhcp flows that are representative of the virtualized access
759 scenario in a PON network.
760 """
761 logical_device_id = line or self.default_logical_device_id
762
763 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800764 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600765
766 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400767 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600768
769 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800770 for uni_port_no, _ in unis:
771 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
772 id=logical_device_id,
773 flow_mod=mk_simple_flow_mod(
774 priority=1000,
775 match_fields=[
776 in_port(uni_port_no),
777 eth_type(0x800),
778 ip_proto(17),
779 udp_dst(67)
780 ],
781 actions=[output(ofp.OFPP_CONTROLLER)]
782 )
783 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600784
785 self.poutput('success')
786
787 complete_install_dhcp_flows = VolthaCli.complete_logical_device
788
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800789 def do_delete_all_flows(self, line):
790 """
791 Remove all flows and flow groups from given logical device
792 """
793 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400794 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800795 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
796 id=logical_device_id,
797 flow_mod=ofp.ofp_flow_mod(
798 command=ofp.OFPFC_DELETE,
799 table_id=ofp.OFPTT_ALL,
800 cookie_mask=0,
801 out_port=ofp.OFPP_ANY,
802 out_group=ofp.OFPG_ANY
803 )
804 ))
805 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
806 id=logical_device_id,
807 group_mod=ofp.ofp_group_mod(
808 command=ofp.OFPGC_DELETE,
809 group_id=ofp.OFPG_ALL
810 )
811 ))
812 self.poutput('success')
813
814 complete_delete_all_flows = VolthaCli.complete_logical_device
815
Zsolt Haraszti80175202016-12-24 00:17:51 -0800816 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800817 """
818 Send an EAPOL upstream from a simulated OLT
819 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800820 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800821 requests.get('http://{}/devices/{}/test_eapol_in'.format(
822 self.voltha_sim_rest, device_id
823 ))
824
Zsolt Haraszti80175202016-12-24 00:17:51 -0800825 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
826
827 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800828 """
829 Send out an an EAPOL start message into the given Unix interface
830 """
831 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800832
833
834if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800835
836 parser = argparse.ArgumentParser()
837
838 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
839 parser.add_argument(
840 '-C', '--consul', action='store', default=defs['consul'], help=_help)
841
842 _help = 'Lookup Voltha endpoints based on service entries in Consul'
843 parser.add_argument(
844 '-L', '--lookup', action='store_true', help=_help)
845
khenaidoo108f05c2017-07-06 11:15:29 -0400846 _help = 'All requests to the Voltha gRPC service are global'
847 parser.add_argument(
848 '-G', '--global_request', action='store_true', help=_help)
849
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800850 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
851 defs['voltha_grpc_endpoint'])
852 parser.add_argument('-g', '--grpc-endpoint', action='store',
853 default=defs['voltha_grpc_endpoint'], help=_help)
854
855 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
856 'testing (default={})'.format(
857 defs['voltha_sim_rest_endpoint'])
858 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
859 default=defs['voltha_sim_rest_endpoint'], help=_help)
860
861 args = parser.parse_args()
862
863 if args.lookup:
864 host = args.consul.split(':')[0].strip()
865 port = int(args.consul.split(':')[1].strip())
866 consul = Consul(host=host, port=port)
867
868 _, services = consul.catalog.service('voltha-grpc')
869 if not services:
870 print('No voltha-grpc service registered in consul; exiting')
871 sys.exit(1)
872 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
873 services[0]['ServicePort'])
874
875 _, services = consul.catalog.service('voltha-sim-rest')
876 if not services:
877 print('No voltha-sim-rest service registered in consul; exiting')
878 sys.exit(1)
879 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
880 services[0]['ServicePort'])
881
khenaidoo108f05c2017-07-06 11:15:29 -0400882 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
883 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800884 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800885 c.load_history()
886 c.cmdloop()
887 c.save_history()