blob: b8cb918c67d953a21b9548150092368ac0a13995 [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')
khenaidoo108f05c2017-07-06 11:15:29 -0400216 sub = DeviceCli(device_id, self.get_stub)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800217 sub.cmdloop()
218
Zsolt Haraszti80175202016-12-24 00:17:51 -0800219 def do_logical_device(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800220 """Enter logical device level command mode"""
Zsolt Haraszti80175202016-12-24 00:17:51 -0800221 logical_device_id = line.strip() or self.default_logical_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800222 if not logical_device_id:
223 raise Exception('<logical-device-id> parameter needed')
khenaidoo108f05c2017-07-06 11:15:29 -0400224 sub = LogicalDeviceCli(logical_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 device_ids(self, force_refresh=False):
228 if force_refresh or self.device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400229 (time() - self.device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800230 self.device_ids_cache = [d.id for d in self.get_devices()]
231 self.device_ids_cache_ts = time()
232 return self.device_ids_cache
233
234 def logical_device_ids(self, force_refresh=False):
235 if force_refresh or self.logical_device_ids is None or \
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400236 (time() - self.logical_device_ids_cache_ts) > 1:
Zsolt Haraszti80175202016-12-24 00:17:51 -0800237 self.logical_device_ids_cache = [d.id for d
238 in self.get_logical_devices()]
239 self.logical_device_ids_cache_ts = time()
240 return self.logical_device_ids_cache
241
242 def complete_device(self, text, line, begidx, endidx):
243 if not text:
244 completions = self.device_ids()[:]
245 else:
246 completions = [d for d in self.device_ids() if d.startswith(text)]
247 return completions
248
249 def complete_logical_device(self, text, line, begidx, endidx):
250 if not text:
251 completions = self.logical_device_ids()[:]
252 else:
253 completions = [d for d in self.logical_device_ids()
254 if d.startswith(text)]
255 return completions
256
Nikolay Titov89004ec2017-06-19 18:22:42 -0400257 def do_xpon(self, line):
258 """xpon <optional> [device_ID] - Enter xpon level command mode"""
259 device_id = line.strip()
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400260 if device_id:
261 stub = self.get_stub()
262 try:
263 res = stub.GetDevice(voltha_pb2.ID(id=device_id))
264 except Exception:
Nikolay Titov176f1db2017-08-10 12:38:43 -0400265 self.poutput(
266 self.colorize('Error: ', 'red') + 'No device id ' +
267 self.colorize(device_id, 'blue') + ' is found')
Nikolay Titov3f0c9dd2017-07-17 17:37:25 -0400268 return
269 sub = XponCli(self.get_channel, device_id)
Nikolay Titov89004ec2017-06-19 18:22:42 -0400270 sub.cmdloop()
271
Zsolt Haraszti80175202016-12-24 00:17:51 -0800272 def do_pdb(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800273 """Launch PDB debug prompt in CLI (for CLI development)"""
274 from pdb import set_trace
275 set_trace()
276
Jonathan Hartda93ac62018-05-01 11:25:29 -0700277 def do_version(self, line):
278 """Show the VOLTHA core version"""
279 stub = self.get_stub()
280 voltha = stub.GetVoltha(Empty())
281 self.poutput('{}'.format(voltha.version))
282
Zsolt Haraszti80175202016-12-24 00:17:51 -0800283 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800284 """Show connectivity status to Voltha status"""
285 stub = voltha_pb2.HealthServiceStub(self.get_channel())
286 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800287 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800288
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800289 @options([
290 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400291 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800292 make_option('-m', '--mac-address', action='store', dest='mac_address',
293 default='00:0c:e2:31:40:00'),
294 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800295 make_option('-H', '--host_and_port', action='store',
296 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800297 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800298 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800299 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400300 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800301 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800302 if opts.host_and_port:
303 kw['host_and_port'] = opts.host_and_port
304 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800305 kw['ipv4_address'] = opts.ip_address
306 elif opts.mac_address:
307 kw['mac_address'] = opts.mac_address
308 else:
309 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500310 # Pass any extra arguments past '--' to the device as custom arguments
311 kw['extra_args'] = line
312
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800313 device = voltha_pb2.Device(**kw)
314 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800315 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800316 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800317
Khen Nursimulud068d812017-03-06 11:44:18 -0500318 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800319 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500320 Enable a device. If the <id> is not provided, it will be on the last
321 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800322 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800323 device_id = line or self.default_device_id
Khen Nursimulu29e75502017-03-07 17:26:50 -0500324 self.poutput('enabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400325 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400326 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400327 stub.EnableDevice(voltha_pb2.ID(id=device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800328
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400329 while True:
330 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
331 # If this is an OLT then acquire logical device id
332 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
333 if device.type.endswith('_olt'):
334 assert device.parent_id
335 self.default_logical_device_id = device.parent_id
336 self.poutput('success (logical device id = {})'.format(
337 self.default_logical_device_id))
338 else:
339 self.poutput('success (device id = {})'.format(device.id))
340 break
341 self.poutput('waiting for device to be enabled...')
342 sleep(.5)
ggowdru64d738a2018-05-10 07:08:06 -0700343 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400344 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800345
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800346 complete_activate_olt = complete_device
347
Khen Nursimulud068d812017-03-06 11:44:18 -0500348 def do_reboot(self, line):
349 """
350 Rebooting a device. ID of the device needs to be provided
351 """
352 device_id = line or self.default_device_id
353 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400354 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400355 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400356 stub.RebootDevice(voltha_pb2.ID(id=device_id))
357 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700358 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400359 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500360
sathishg5ae86222017-06-28 15:16:29 +0530361 def do_self_test(self, line):
362 """
363 Self Test a device. ID of the device needs to be provided
364 """
365 device_id = line or self.default_device_id
366 self.poutput('Self Testing {}'.format(device_id))
367 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400368 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530369 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
370 self.poutput('Self Tested {}'.format(device_id))
371 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700372 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530373 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
374
Khen Nursimulud068d812017-03-06 11:44:18 -0500375 def do_delete(self, line):
376 """
377 Deleting a device. ID of the device needs to be provided
378 """
379 device_id = line or self.default_device_id
380 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400381 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400382 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400383 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
384 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700385 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400386 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500387
388 def do_disable(self, line):
389 """
390 Disable a device. ID of the device needs to be provided
391 """
392 device_id = line
393 self.poutput('disabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400394 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400395 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400396 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500397
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400398 # Do device query and verify that the device admin status is
399 # DISABLED and Operational Status is unknown
400 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700401 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400402 self.poutput('disabled successfully {}'.format(device_id))
403 else:
404 self.poutput('disabling failed {}. Admin State:{} '
405 'Operation State: {}'.format(device_id,
406 device.admin_state,
407 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700408 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400409 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500410
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800411 def do_test(self, line):
412 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400413 sub = TestCli(self.history, self.voltha_grpc,
414 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800415 sub.cmdloop()
416
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400417 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400418 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400419 sub.cmdloop()
420
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800421
422class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400423 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800424 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
425 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400426 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800427 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400428 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800429
430 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400431 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800432 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400433 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800434 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800435
436 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800437 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800438 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800439 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800440 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800441
442 # verify that device is of type simulated_olt
443 device = self.get_device(device_id)
444 assert device.type == 'simulated_olt', (
445 'Cannot use it on this device type (only on simulated_olt type)')
446
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800447 requests.get('http://{}/devices/{}/detect_onus'.format(
448 self.voltha_sim_rest, device_id
449 ))
450
Zsolt Haraszti80175202016-12-24 00:17:51 -0800451 complete_arrive_onus = VolthaCli.complete_device
452
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800453 def get_logical_ports(self, logical_device_id):
454 """
455 Return the NNI port number and the first usable UNI port of logical
456 device, and the vlan associated with the latter.
457 """
khenaidoo108f05c2017-07-06 11:15:29 -0400458 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800459 ports = stub.ListLogicalDevicePorts(
460 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800461 nni = None
462 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800463 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800464 if port.root_port:
465 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800466 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800467 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800468 uni = port.ofp_port.port_no
469 uni_device = self.get_device(port.device_id)
470 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800471 unis.append((uni, vlan))
472
473 assert nni is not None, "No NNI port found"
474 assert unis, "Not a single UNI?"
475
476 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800477
Zsolt Haraszti80175202016-12-24 00:17:51 -0800478 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800479 """
480 Install an EAPOL flow on the given logical device. If device is not
481 given, it will be applied to logical device of the last pre-provisioned
482 OLT device.
483 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800484 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800485
486 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800487 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800488
489 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400490 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800491 for uni_port_no, _ in unis:
492 update = FlowTableUpdate(
493 id=logical_device_id,
494 flow_mod=mk_simple_flow_mod(
495 priority=2000,
496 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
497 actions=[
498 # push_vlan(0x8100),
499 # set_field(vlan_vid(4096 + 4000)),
500 output(ofp.OFPP_CONTROLLER)
501 ]
502 )
503 )
504 res = stub.UpdateLogicalDeviceFlowTable(update)
505 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800506
Zsolt Haraszti80175202016-12-24 00:17:51 -0800507 complete_install_eapol_flow = VolthaCli.complete_logical_device
508
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800509 def do_install_all_controller_bound_flows(self, line):
510 """
511 Install all flow rules for controller bound flows, including EAPOL,
512 IGMP and DHCP. If device is not given, it will be applied to logical
513 device of the last pre-provisioned OLT device.
514 """
515 logical_device_id = line or self.default_logical_device_id
516
517 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800518 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800519
520 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400521 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800522
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800523 for uni_port_no, _ in unis:
524 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
525 id=logical_device_id,
526 flow_mod=mk_simple_flow_mod(
527 priority=2000,
528 match_fields=[
529 in_port(uni_port_no),
530 eth_type(0x888e)
531 ],
532 actions=[output(ofp.OFPP_CONTROLLER)]
533 )
534 ))
535 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
536 id=logical_device_id,
537 flow_mod=mk_simple_flow_mod(
538 priority=1000,
539 match_fields=[
540 in_port(uni_port_no),
541 eth_type(0x800),
542 ip_proto(2)
543 ],
544 actions=[output(ofp.OFPP_CONTROLLER)]
545 )
546 ))
547 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
548 id=logical_device_id,
549 flow_mod=mk_simple_flow_mod(
550 priority=1000,
551 match_fields=[
552 in_port(uni_port_no),
553 eth_type(0x800),
554 ip_proto(17),
555 udp_dst(67)
556 ],
557 actions=[output(ofp.OFPP_CONTROLLER)]
558 )
559 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800560 self.poutput('success')
561
562 complete_install_all_controller_bound_flows = \
563 VolthaCli.complete_logical_device
564
565 def do_install_all_sample_flows(self, line):
566 """
567 Install all flows that are representative of the virtualized access
568 scenario in a PON network.
569 """
570 logical_device_id = line or self.default_logical_device_id
571
572 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800573 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800574
575 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400576 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800577
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800578 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800579 # Controller-bound flows
580 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
581 id=logical_device_id,
582 flow_mod=mk_simple_flow_mod(
583 priority=2000,
584 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
585 actions=[
586 # push_vlan(0x8100),
587 # set_field(vlan_vid(4096 + 4000)),
588 output(ofp.OFPP_CONTROLLER)
589 ]
590 )
591 ))
592 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
593 id=logical_device_id,
594 flow_mod=mk_simple_flow_mod(
595 priority=1000,
596 match_fields=[eth_type(0x800), ip_proto(2)],
597 actions=[output(ofp.OFPP_CONTROLLER)]
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(17), udp_dst(67)],
605 actions=[output(ofp.OFPP_CONTROLLER)]
606 )
607 ))
608
609 # Unicast flows:
610 # Downstream flow 1
611 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
612 id=logical_device_id,
613 flow_mod=mk_simple_flow_mod(
614 priority=500,
615 match_fields=[
616 in_port(nni_port_no),
617 vlan_vid(4096 + 1000),
618 metadata(c_vid) # here to mimic an ONOS artifact
619 ],
620 actions=[pop_vlan()],
621 next_table_id=1
622 )
623 ))
624 # Downstream flow 2
625 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
626 id=logical_device_id,
627 flow_mod=mk_simple_flow_mod(
628 priority=500,
629 table_id=1,
630 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
631 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
632 )
633 ))
634 # Upstream flow 1 for 0-tagged case
635 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
636 id=logical_device_id,
637 flow_mod=mk_simple_flow_mod(
638 priority=500,
639 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
640 actions=[set_field(vlan_vid(4096 + c_vid))],
641 next_table_id=1
642 )
643 ))
644 # Upstream flow 1 for untagged case
645 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
646 id=logical_device_id,
647 flow_mod=mk_simple_flow_mod(
648 priority=500,
649 match_fields=[in_port(uni_port_no), vlan_vid(0)],
650 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
651 next_table_id=1
652 )
653 ))
654 # Upstream flow 2 for s-tag
655 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
656 id=logical_device_id,
657 flow_mod=mk_simple_flow_mod(
658 priority=500,
659 table_id=1,
660 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
661 actions=[
662 push_vlan(0x8100),
663 set_field(vlan_vid(4096 + 1000)),
664 output(nni_port_no)
665 ]
666 )
667 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800668
669 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800670 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800671 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
672 id=logical_device_id,
673 group_mod=mk_multicast_group_mod(
674 group_id=1,
675 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800676 ofp.ofp_bucket(actions=[
677 pop_vlan(),
678 output(unis[0][0])
679 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800680 ]
681 )
682 ))
683 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
684 id=logical_device_id,
685 flow_mod=mk_simple_flow_mod(
686 priority=1000,
687 match_fields=[
688 in_port(nni_port_no),
689 eth_type(0x800),
690 vlan_vid(4096 + 140),
691 ipv4_dst(0xe4010101)
692 ],
693 actions=[group(1)]
694 )
695 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800696
697 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800698 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
699 id=logical_device_id,
700 group_mod=mk_multicast_group_mod(
701 group_id=2,
702 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800703 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400704 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800705 ]
706 )
707 ))
708 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
709 id=logical_device_id,
710 flow_mod=mk_simple_flow_mod(
711 priority=1000,
712 match_fields=[
713 in_port(nni_port_no),
714 eth_type(0x800),
715 vlan_vid(4096 + 140),
716 ipv4_dst(0xe4020202)
717 ],
718 actions=[group(2)]
719 )
720 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800721
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800722 # 3rd with empty bucket
723 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
724 id=logical_device_id,
725 group_mod=mk_multicast_group_mod(
726 group_id=3,
727 buckets=[]
728 )
729 ))
730 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
731 id=logical_device_id,
732 flow_mod=mk_simple_flow_mod(
733 priority=1000,
734 match_fields=[
735 in_port(nni_port_no),
736 eth_type(0x800),
737 vlan_vid(4096 + 140),
738 ipv4_dst(0xe4030303)
739 ],
740 actions=[group(3)]
741 )
742 ))
743
744 self.poutput('success')
745
746 complete_install_all_sample_flows = VolthaCli.complete_logical_device
747
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600748 def do_install_dhcp_flows(self, line):
749 """
750 Install all dhcp flows that are representative of the virtualized access
751 scenario in a PON network.
752 """
753 logical_device_id = line or self.default_logical_device_id
754
755 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800756 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600757
758 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400759 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600760
761 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800762 for uni_port_no, _ in unis:
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(uni_port_no),
769 eth_type(0x800),
770 ip_proto(17),
771 udp_dst(67)
772 ],
773 actions=[output(ofp.OFPP_CONTROLLER)]
774 )
775 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600776
777 self.poutput('success')
778
779 complete_install_dhcp_flows = VolthaCli.complete_logical_device
780
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800781 def do_delete_all_flows(self, line):
782 """
783 Remove all flows and flow groups from given logical device
784 """
785 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400786 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800787 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
788 id=logical_device_id,
789 flow_mod=ofp.ofp_flow_mod(
790 command=ofp.OFPFC_DELETE,
791 table_id=ofp.OFPTT_ALL,
792 cookie_mask=0,
793 out_port=ofp.OFPP_ANY,
794 out_group=ofp.OFPG_ANY
795 )
796 ))
797 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
798 id=logical_device_id,
799 group_mod=ofp.ofp_group_mod(
800 command=ofp.OFPGC_DELETE,
801 group_id=ofp.OFPG_ALL
802 )
803 ))
804 self.poutput('success')
805
806 complete_delete_all_flows = VolthaCli.complete_logical_device
807
Zsolt Haraszti80175202016-12-24 00:17:51 -0800808 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800809 """
810 Send an EAPOL upstream from a simulated OLT
811 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800812 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800813 requests.get('http://{}/devices/{}/test_eapol_in'.format(
814 self.voltha_sim_rest, device_id
815 ))
816
Zsolt Haraszti80175202016-12-24 00:17:51 -0800817 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
818
819 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800820 """
821 Send out an an EAPOL start message into the given Unix interface
822 """
823 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800824
825
826if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800827
828 parser = argparse.ArgumentParser()
829
830 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
831 parser.add_argument(
832 '-C', '--consul', action='store', default=defs['consul'], help=_help)
833
834 _help = 'Lookup Voltha endpoints based on service entries in Consul'
835 parser.add_argument(
836 '-L', '--lookup', action='store_true', help=_help)
837
khenaidoo108f05c2017-07-06 11:15:29 -0400838 _help = 'All requests to the Voltha gRPC service are global'
839 parser.add_argument(
840 '-G', '--global_request', action='store_true', help=_help)
841
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800842 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
843 defs['voltha_grpc_endpoint'])
844 parser.add_argument('-g', '--grpc-endpoint', action='store',
845 default=defs['voltha_grpc_endpoint'], help=_help)
846
847 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
848 'testing (default={})'.format(
849 defs['voltha_sim_rest_endpoint'])
850 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
851 default=defs['voltha_sim_rest_endpoint'], help=_help)
852
853 args = parser.parse_args()
854
855 if args.lookup:
856 host = args.consul.split(':')[0].strip()
857 port = int(args.consul.split(':')[1].strip())
858 consul = Consul(host=host, port=port)
859
860 _, services = consul.catalog.service('voltha-grpc')
861 if not services:
862 print('No voltha-grpc service registered in consul; exiting')
863 sys.exit(1)
864 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
865 services[0]['ServicePort'])
866
867 _, services = consul.catalog.service('voltha-sim-rest')
868 if not services:
869 print('No voltha-sim-rest service registered in consul; exiting')
870 sys.exit(1)
871 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
872 services[0]['ServicePort'])
873
khenaidoo108f05c2017-07-06 11:15:29 -0400874 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
875 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800876 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800877 c.load_history()
878 c.cmdloop()
879 c.save_history()