blob: a1c72263fa52ec3761c153e243cc51e83a6ae64d [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
Zsolt Haraszti80175202016-12-24 00:17:51 -0800277 def do_health(self, line):
Zsolt Harasztia133a452016-12-22 01:26:57 -0800278 """Show connectivity status to Voltha status"""
279 stub = voltha_pb2.HealthServiceStub(self.get_channel())
280 res = stub.GetHealthStatus(Empty())
Zsolt Haraszti80175202016-12-24 00:17:51 -0800281 self.poutput(dumps(pb2dict(res), indent=4))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800282
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800283 @options([
284 make_option('-t', '--device-type', action="store", dest='device_type',
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400285 help="Device type", default='simulated_olt'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800286 make_option('-m', '--mac-address', action='store', dest='mac_address',
287 default='00:0c:e2:31:40:00'),
288 make_option('-i', '--ip-address', action='store', dest='ip_address'),
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800289 make_option('-H', '--host_and_port', action='store',
290 dest='host_and_port'),
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800291 ])
Zsolt Haraszti80175202016-12-24 00:17:51 -0800292 def do_preprovision_olt(self, line, opts):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800293 """Preprovision a new OLT with given device type"""
khenaidoo108f05c2017-07-06 11:15:29 -0400294 stub = self.get_stub()
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800295 kw = dict(type=opts.device_type)
Zsolt Haraszti656ecc62016-12-28 15:08:23 -0800296 if opts.host_and_port:
297 kw['host_and_port'] = opts.host_and_port
298 elif opts.ip_address:
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800299 kw['ipv4_address'] = opts.ip_address
300 elif opts.mac_address:
301 kw['mac_address'] = opts.mac_address
302 else:
303 raise Exception('Either IP address or Mac Address is needed')
Chip Boling90b224d2017-06-02 11:51:48 -0500304 # Pass any extra arguments past '--' to the device as custom arguments
305 kw['extra_args'] = line
306
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800307 device = voltha_pb2.Device(**kw)
308 device = stub.CreateDevice(device)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800309 self.poutput('success (device id = {})'.format(device.id))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800310 self.default_device_id = device.id
Zsolt Harasztia133a452016-12-22 01:26:57 -0800311
Khen Nursimulud068d812017-03-06 11:44:18 -0500312 def do_enable(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800313 """
Khen Nursimulud068d812017-03-06 11:44:18 -0500314 Enable a device. If the <id> is not provided, it will be on the last
315 pre-provisioned device.
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800316 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800317 device_id = line or self.default_device_id
Khen Nursimulu29e75502017-03-07 17:26:50 -0500318 self.poutput('enabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400319 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400320 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400321 stub.EnableDevice(voltha_pb2.ID(id=device_id))
Zsolt Harasztia133a452016-12-22 01:26:57 -0800322
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400323 while True:
324 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
325 # If this is an OLT then acquire logical device id
326 if device.oper_status == voltha_pb2.OperStatus.ACTIVE:
327 if device.type.endswith('_olt'):
328 assert device.parent_id
329 self.default_logical_device_id = device.parent_id
330 self.poutput('success (logical device id = {})'.format(
331 self.default_logical_device_id))
332 else:
333 self.poutput('success (device id = {})'.format(device.id))
334 break
335 self.poutput('waiting for device to be enabled...')
336 sleep(.5)
ggowdru64d738a2018-05-10 07:08:06 -0700337 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400338 self.poutput('Error enabling {}. Error:{}'.format(device_id, e))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800339
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800340 complete_activate_olt = complete_device
341
Khen Nursimulud068d812017-03-06 11:44:18 -0500342 def do_reboot(self, line):
343 """
344 Rebooting a device. ID of the device needs to be provided
345 """
346 device_id = line or self.default_device_id
347 self.poutput('rebooting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400348 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400349 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400350 stub.RebootDevice(voltha_pb2.ID(id=device_id))
351 self.poutput('rebooted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700352 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400353 self.poutput('Error rebooting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500354
sathishg5ae86222017-06-28 15:16:29 +0530355 def do_self_test(self, line):
356 """
357 Self Test a device. ID of the device needs to be provided
358 """
359 device_id = line or self.default_device_id
360 self.poutput('Self Testing {}'.format(device_id))
361 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400362 stub = self.get_stub()
sathishg5ae86222017-06-28 15:16:29 +0530363 res = stub.SelfTest(voltha_pb2.ID(id=device_id))
364 self.poutput('Self Tested {}'.format(device_id))
365 self.poutput(dumps(pb2dict(res), indent=4))
ggowdru64d738a2018-05-10 07:08:06 -0700366 except Exception as e:
sathishg5ae86222017-06-28 15:16:29 +0530367 self.poutput('Error in self test {}. Error:{}'.format(device_id, e))
368
Khen Nursimulud068d812017-03-06 11:44:18 -0500369 def do_delete(self, line):
370 """
371 Deleting a device. ID of the device needs to be provided
372 """
373 device_id = line or self.default_device_id
374 self.poutput('deleting {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400375 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400376 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400377 stub.DeleteDevice(voltha_pb2.ID(id=device_id))
378 self.poutput('deleted {}'.format(device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700379 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400380 self.poutput('Error deleting {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500381
382 def do_disable(self, line):
383 """
384 Disable a device. ID of the device needs to be provided
385 """
386 device_id = line
387 self.poutput('disabling {}'.format(device_id))
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400388 try:
khenaidoo108f05c2017-07-06 11:15:29 -0400389 stub = self.get_stub()
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400390 stub.DisableDevice(voltha_pb2.ID(id=device_id))
Khen Nursimulud068d812017-03-06 11:44:18 -0500391
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400392 # Do device query and verify that the device admin status is
393 # DISABLED and Operational Status is unknown
394 device = stub.GetDevice(voltha_pb2.ID(id=device_id))
ggowdru64d738a2018-05-10 07:08:06 -0700395 if device.admin_state == voltha_pb2.AdminState.DISABLED:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400396 self.poutput('disabled successfully {}'.format(device_id))
397 else:
398 self.poutput('disabling failed {}. Admin State:{} '
399 'Operation State: {}'.format(device_id,
400 device.admin_state,
401 device.oper_status))
ggowdru64d738a2018-05-10 07:08:06 -0700402 except Exception as e:
Khen Nursimuluc60afa12017-03-13 14:33:50 -0400403 self.poutput('Error disabling {}. Error:{}'.format(device_id, e))
Khen Nursimulud068d812017-03-06 11:44:18 -0500404
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800405 def do_test(self, line):
406 """Enter test mode, which makes a bunch on new commands available"""
khenaidoo108f05c2017-07-06 11:15:29 -0400407 sub = TestCli(self.history, self.voltha_grpc,
408 self.get_stub, self.voltha_sim_rest)
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800409 sub.cmdloop()
410
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400411 def do_alarm_filters(self, line):
khenaidoo108f05c2017-07-06 11:15:29 -0400412 sub = AlarmFiltersCli(self.get_stub)
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400413 sub.cmdloop()
414
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800415
416class TestCli(VolthaCli):
khenaidoo108f05c2017-07-06 11:15:29 -0400417 def __init__(self, history, voltha_grpc, get_stub, voltha_sim_rest):
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800418 VolthaCli.__init__(self, voltha_grpc, voltha_sim_rest)
419 self.history = history
khenaidoo108f05c2017-07-06 11:15:29 -0400420 self.get_stub = get_stub
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800421 self.prompt = '(' + self.colorize(self.colorize('test', 'cyan'),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400422 'bold') + ') '
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800423
424 def get_device(self, device_id, depth=0):
khenaidoo108f05c2017-07-06 11:15:29 -0400425 stub = self.get_stub()
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800426 res = stub.GetDevice(voltha_pb2.ID(id=device_id),
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400427 metadata=(('get-depth', str(depth)),))
Zsolt Haraszti50cae7d2017-01-08 22:27:07 -0800428 return res
Zsolt Haraszti80175202016-12-24 00:17:51 -0800429
430 def do_arrive_onus(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800431 """
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800432 Simulate the arrival of ONUs (available only on simulated_olt)
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800433 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800434 device_id = line or self.default_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800435
436 # verify that device is of type simulated_olt
437 device = self.get_device(device_id)
438 assert device.type == 'simulated_olt', (
439 'Cannot use it on this device type (only on simulated_olt type)')
440
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800441 requests.get('http://{}/devices/{}/detect_onus'.format(
442 self.voltha_sim_rest, device_id
443 ))
444
Zsolt Haraszti80175202016-12-24 00:17:51 -0800445 complete_arrive_onus = VolthaCli.complete_device
446
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800447 def get_logical_ports(self, logical_device_id):
448 """
449 Return the NNI port number and the first usable UNI port of logical
450 device, and the vlan associated with the latter.
451 """
khenaidoo108f05c2017-07-06 11:15:29 -0400452 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800453 ports = stub.ListLogicalDevicePorts(
454 voltha_pb2.ID(id=logical_device_id)).items
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800455 nni = None
456 unis = []
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800457 for port in ports:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800458 if port.root_port:
459 assert nni is None, "There shall be only one root port"
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800460 nni = port.ofp_port.port_no
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800461 else:
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800462 uni = port.ofp_port.port_no
463 uni_device = self.get_device(port.device_id)
464 vlan = uni_device.vlan
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800465 unis.append((uni, vlan))
466
467 assert nni is not None, "No NNI port found"
468 assert unis, "Not a single UNI?"
469
470 return nni, unis
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800471
Zsolt Haraszti80175202016-12-24 00:17:51 -0800472 def do_install_eapol_flow(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800473 """
474 Install an EAPOL flow on the given logical device. If device is not
475 given, it will be applied to logical device of the last pre-provisioned
476 OLT device.
477 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800478 logical_device_id = line or self.default_logical_device_id
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800479
480 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800481 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800482
483 # construct and push flow rule
khenaidoo108f05c2017-07-06 11:15:29 -0400484 stub = self.get_stub()
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800485 for uni_port_no, _ in unis:
486 update = FlowTableUpdate(
487 id=logical_device_id,
488 flow_mod=mk_simple_flow_mod(
489 priority=2000,
490 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
491 actions=[
492 # push_vlan(0x8100),
493 # set_field(vlan_vid(4096 + 4000)),
494 output(ofp.OFPP_CONTROLLER)
495 ]
496 )
497 )
498 res = stub.UpdateLogicalDeviceFlowTable(update)
499 self.poutput('success for uni {} ({})'.format(uni_port_no, res))
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800500
Zsolt Haraszti80175202016-12-24 00:17:51 -0800501 complete_install_eapol_flow = VolthaCli.complete_logical_device
502
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800503 def do_install_all_controller_bound_flows(self, line):
504 """
505 Install all flow rules for controller bound flows, including EAPOL,
506 IGMP and DHCP. If device is not given, it will be applied to logical
507 device of the last pre-provisioned OLT device.
508 """
509 logical_device_id = line or self.default_logical_device_id
510
511 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800512 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800513
514 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400515 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800516
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800517 for uni_port_no, _ in unis:
518 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
519 id=logical_device_id,
520 flow_mod=mk_simple_flow_mod(
521 priority=2000,
522 match_fields=[
523 in_port(uni_port_no),
524 eth_type(0x888e)
525 ],
526 actions=[output(ofp.OFPP_CONTROLLER)]
527 )
528 ))
529 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
530 id=logical_device_id,
531 flow_mod=mk_simple_flow_mod(
532 priority=1000,
533 match_fields=[
534 in_port(uni_port_no),
535 eth_type(0x800),
536 ip_proto(2)
537 ],
538 actions=[output(ofp.OFPP_CONTROLLER)]
539 )
540 ))
541 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
542 id=logical_device_id,
543 flow_mod=mk_simple_flow_mod(
544 priority=1000,
545 match_fields=[
546 in_port(uni_port_no),
547 eth_type(0x800),
548 ip_proto(17),
549 udp_dst(67)
550 ],
551 actions=[output(ofp.OFPP_CONTROLLER)]
552 )
553 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800554 self.poutput('success')
555
556 complete_install_all_controller_bound_flows = \
557 VolthaCli.complete_logical_device
558
559 def do_install_all_sample_flows(self, line):
560 """
561 Install all flows that are representative of the virtualized access
562 scenario in a PON network.
563 """
564 logical_device_id = line or self.default_logical_device_id
565
566 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800567 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800568
569 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400570 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800571
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800572 for uni_port_no, c_vid in unis:
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800573 # Controller-bound flows
574 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
575 id=logical_device_id,
576 flow_mod=mk_simple_flow_mod(
577 priority=2000,
578 match_fields=[in_port(uni_port_no), eth_type(0x888e)],
579 actions=[
580 # push_vlan(0x8100),
581 # set_field(vlan_vid(4096 + 4000)),
582 output(ofp.OFPP_CONTROLLER)
583 ]
584 )
585 ))
586 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
587 id=logical_device_id,
588 flow_mod=mk_simple_flow_mod(
589 priority=1000,
590 match_fields=[eth_type(0x800), ip_proto(2)],
591 actions=[output(ofp.OFPP_CONTROLLER)]
592 )
593 ))
594 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
595 id=logical_device_id,
596 flow_mod=mk_simple_flow_mod(
597 priority=1000,
598 match_fields=[eth_type(0x800), ip_proto(17), udp_dst(67)],
599 actions=[output(ofp.OFPP_CONTROLLER)]
600 )
601 ))
602
603 # Unicast flows:
604 # Downstream flow 1
605 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
606 id=logical_device_id,
607 flow_mod=mk_simple_flow_mod(
608 priority=500,
609 match_fields=[
610 in_port(nni_port_no),
611 vlan_vid(4096 + 1000),
612 metadata(c_vid) # here to mimic an ONOS artifact
613 ],
614 actions=[pop_vlan()],
615 next_table_id=1
616 )
617 ))
618 # Downstream flow 2
619 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
620 id=logical_device_id,
621 flow_mod=mk_simple_flow_mod(
622 priority=500,
623 table_id=1,
624 match_fields=[in_port(nni_port_no), vlan_vid(4096 + c_vid)],
625 actions=[set_field(vlan_vid(4096 + 0)), output(uni_port_no)]
626 )
627 ))
628 # Upstream flow 1 for 0-tagged case
629 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
630 id=logical_device_id,
631 flow_mod=mk_simple_flow_mod(
632 priority=500,
633 match_fields=[in_port(uni_port_no), vlan_vid(4096 + 0)],
634 actions=[set_field(vlan_vid(4096 + c_vid))],
635 next_table_id=1
636 )
637 ))
638 # Upstream flow 1 for untagged case
639 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
640 id=logical_device_id,
641 flow_mod=mk_simple_flow_mod(
642 priority=500,
643 match_fields=[in_port(uni_port_no), vlan_vid(0)],
644 actions=[push_vlan(0x8100), set_field(vlan_vid(4096 + c_vid))],
645 next_table_id=1
646 )
647 ))
648 # Upstream flow 2 for s-tag
649 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
650 id=logical_device_id,
651 flow_mod=mk_simple_flow_mod(
652 priority=500,
653 table_id=1,
654 match_fields=[in_port(uni_port_no), vlan_vid(4096 + c_vid)],
655 actions=[
656 push_vlan(0x8100),
657 set_field(vlan_vid(4096 + 1000)),
658 output(nni_port_no)
659 ]
660 )
661 ))
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800662
663 # Push a few multicast flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800664 # 1st with one bucket for our uni 0
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800665 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
666 id=logical_device_id,
667 group_mod=mk_multicast_group_mod(
668 group_id=1,
669 buckets=[
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800670 ofp.ofp_bucket(actions=[
671 pop_vlan(),
672 output(unis[0][0])
673 ])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800674 ]
675 )
676 ))
677 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
678 id=logical_device_id,
679 flow_mod=mk_simple_flow_mod(
680 priority=1000,
681 match_fields=[
682 in_port(nni_port_no),
683 eth_type(0x800),
684 vlan_vid(4096 + 140),
685 ipv4_dst(0xe4010101)
686 ],
687 actions=[group(1)]
688 )
689 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800690
691 # 2nd with one bucket for uni 0 and 1
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800692 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
693 id=logical_device_id,
694 group_mod=mk_multicast_group_mod(
695 group_id=2,
696 buckets=[
Nathan Knuth6b7b6ff2017-02-12 03:30:48 -0800697 ofp.ofp_bucket(actions=[pop_vlan(), output(unis[0][0])])
Stephane Barbarie4db8ca22017-04-24 10:30:20 -0400698 # ofp.ofp_bucket(actions=[pop_vlan(), output(unis[1][0])])
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800699 ]
700 )
701 ))
702 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
703 id=logical_device_id,
704 flow_mod=mk_simple_flow_mod(
705 priority=1000,
706 match_fields=[
707 in_port(nni_port_no),
708 eth_type(0x800),
709 vlan_vid(4096 + 140),
710 ipv4_dst(0xe4020202)
711 ],
712 actions=[group(2)]
713 )
714 ))
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800715
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800716 # 3rd with empty bucket
717 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
718 id=logical_device_id,
719 group_mod=mk_multicast_group_mod(
720 group_id=3,
721 buckets=[]
722 )
723 ))
724 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
725 id=logical_device_id,
726 flow_mod=mk_simple_flow_mod(
727 priority=1000,
728 match_fields=[
729 in_port(nni_port_no),
730 eth_type(0x800),
731 vlan_vid(4096 + 140),
732 ipv4_dst(0xe4030303)
733 ],
734 actions=[group(3)]
735 )
736 ))
737
738 self.poutput('success')
739
740 complete_install_all_sample_flows = VolthaCli.complete_logical_device
741
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600742 def do_install_dhcp_flows(self, line):
743 """
744 Install all dhcp flows that are representative of the virtualized access
745 scenario in a PON network.
746 """
747 logical_device_id = line or self.default_logical_device_id
748
749 # gather NNI and UNI port IDs
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800750 nni_port_no, unis = self.get_logical_ports(logical_device_id)
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600751
752 # construct and push flow rules
khenaidoo108f05c2017-07-06 11:15:29 -0400753 stub = self.get_stub()
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600754
755 # Controller-bound flows
Zsolt Harasztib9a5f752017-02-11 06:07:08 -0800756 for uni_port_no, _ in unis:
757 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
758 id=logical_device_id,
759 flow_mod=mk_simple_flow_mod(
760 priority=1000,
761 match_fields=[
762 in_port(uni_port_no),
763 eth_type(0x800),
764 ip_proto(17),
765 udp_dst(67)
766 ],
767 actions=[output(ofp.OFPP_CONTROLLER)]
768 )
769 ))
Nathan Knuth5f4163e2017-01-11 18:21:10 -0600770
771 self.poutput('success')
772
773 complete_install_dhcp_flows = VolthaCli.complete_logical_device
774
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800775 def do_delete_all_flows(self, line):
776 """
777 Remove all flows and flow groups from given logical device
778 """
779 logical_device_id = line or self.default_logical_device_id
khenaidoo108f05c2017-07-06 11:15:29 -0400780 stub = self.get_stub()
Zsolt Haraszti85f12852016-12-24 08:30:58 -0800781 stub.UpdateLogicalDeviceFlowTable(FlowTableUpdate(
782 id=logical_device_id,
783 flow_mod=ofp.ofp_flow_mod(
784 command=ofp.OFPFC_DELETE,
785 table_id=ofp.OFPTT_ALL,
786 cookie_mask=0,
787 out_port=ofp.OFPP_ANY,
788 out_group=ofp.OFPG_ANY
789 )
790 ))
791 stub.UpdateLogicalDeviceFlowGroupTable(FlowGroupTableUpdate(
792 id=logical_device_id,
793 group_mod=ofp.ofp_group_mod(
794 command=ofp.OFPGC_DELETE,
795 group_id=ofp.OFPG_ALL
796 )
797 ))
798 self.poutput('success')
799
800 complete_delete_all_flows = VolthaCli.complete_logical_device
801
Zsolt Haraszti80175202016-12-24 00:17:51 -0800802 def do_send_simulated_upstream_eapol(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800803 """
804 Send an EAPOL upstream from a simulated OLT
805 """
Zsolt Haraszti80175202016-12-24 00:17:51 -0800806 device_id = line or self.default_device_id
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800807 requests.get('http://{}/devices/{}/test_eapol_in'.format(
808 self.voltha_sim_rest, device_id
809 ))
810
Zsolt Haraszti80175202016-12-24 00:17:51 -0800811 complete_send_simulated_upstream_eapol = VolthaCli.complete_device
812
813 def do_inject_eapol_start(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800814 """
815 Send out an an EAPOL start message into the given Unix interface
816 """
817 pass
Zsolt Harasztia133a452016-12-22 01:26:57 -0800818
819
820if __name__ == '__main__':
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800821
822 parser = argparse.ArgumentParser()
823
824 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
825 parser.add_argument(
826 '-C', '--consul', action='store', default=defs['consul'], help=_help)
827
828 _help = 'Lookup Voltha endpoints based on service entries in Consul'
829 parser.add_argument(
830 '-L', '--lookup', action='store_true', help=_help)
831
khenaidoo108f05c2017-07-06 11:15:29 -0400832 _help = 'All requests to the Voltha gRPC service are global'
833 parser.add_argument(
834 '-G', '--global_request', action='store_true', help=_help)
835
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -0800836 _help = '<hostname>:<port> of Voltha gRPC service (default={})'.format(
837 defs['voltha_grpc_endpoint'])
838 parser.add_argument('-g', '--grpc-endpoint', action='store',
839 default=defs['voltha_grpc_endpoint'], help=_help)
840
841 _help = '<hostname>:<port> of Voltha simulated adapter backend for ' \
842 'testing (default={})'.format(
843 defs['voltha_sim_rest_endpoint'])
844 parser.add_argument('-s', '--sim-rest-endpoint', action='store',
845 default=defs['voltha_sim_rest_endpoint'], help=_help)
846
847 args = parser.parse_args()
848
849 if args.lookup:
850 host = args.consul.split(':')[0].strip()
851 port = int(args.consul.split(':')[1].strip())
852 consul = Consul(host=host, port=port)
853
854 _, services = consul.catalog.service('voltha-grpc')
855 if not services:
856 print('No voltha-grpc service registered in consul; exiting')
857 sys.exit(1)
858 args.grpc_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
859 services[0]['ServicePort'])
860
861 _, services = consul.catalog.service('voltha-sim-rest')
862 if not services:
863 print('No voltha-sim-rest service registered in consul; exiting')
864 sys.exit(1)
865 args.sim_rest_endpoint = '{}:{}'.format(services[0]['ServiceAddress'],
866 services[0]['ServicePort'])
867
khenaidoo108f05c2017-07-06 11:15:29 -0400868 c = VolthaCli(args.grpc_endpoint, args.sim_rest_endpoint,
869 args.global_request)
Zsolt Haraszti80175202016-12-24 00:17:51 -0800870 c.poutput(banner)
Zsolt Harasztia133a452016-12-22 01:26:57 -0800871 c.load_history()
872 c.cmdloop()
873 c.save_history()