blob: 5dba14499aa3a77798de5e87baecffb0b1017aae [file] [log] [blame]
Zsolt Harasztid036b7e2016-12-23 15:36:01 -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#
17
18"""
19Device level CLI commands
20"""
Sergio Slobodrian901bf4e2017-03-17 12:54:39 -040021from optparse import make_option
22from cmd2 import Cmd, options
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080023from simplejson import dumps
24
Zsolt Haraszti85f12852016-12-24 08:30:58 -080025from cli.table import print_pb_as_table, print_pb_list_as_table
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080026from cli.utils import print_flows, pb2dict
27from voltha.protos import third_party
28
29_ = third_party
30from voltha.protos import voltha_pb2
Sergio Slobodrian901bf4e2017-03-17 12:54:39 -040031from voltha.protos.device_pb2 import PmConfigs, PmConfig, PmGroupConfig
32from google.protobuf.json_format import MessageToDict
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080033
Sergio Slobodrian901bf4e2017-03-17 12:54:39 -040034# Since proto3 won't send fields that are set to 0/false/"" any object that
35# might have those values set in them needs to be replicated here such that the
36# fields can be adequately
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080037
38class DeviceCli(Cmd):
39
40 def __init__(self, get_channel, device_id):
41 Cmd.__init__(self)
42 self.get_channel = get_channel
43 self.device_id = device_id
44 self.prompt = '(' + self.colorize(
45 self.colorize('device {}'.format(device_id), 'red'), 'bold') + ') '
Sergio Slobodrian901bf4e2017-03-17 12:54:39 -040046 self.pm_config_last = None
47 self.pm_config_dirty = False
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080048
Zsolt Haraszti9b485fb2016-12-26 23:11:15 -080049 def cmdloop(self):
50 self._cmdloop()
51
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080052 def get_device(self, depth=0):
53 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
54 res = stub.GetDevice(voltha_pb2.ID(id=self.device_id),
55 metadata=(('get-depth', str(depth)), ))
56 return res
57
Zsolt Haraszti80175202016-12-24 00:17:51 -080058 do_exit = Cmd.do_quit
Zsolt Harasztid036b7e2016-12-23 15:36:01 -080059
Zsolt Haraszti80175202016-12-24 00:17:51 -080060 def do_show(self, line):
61 """Show detailed device information"""
Zsolt Haraszti85f12852016-12-24 08:30:58 -080062 print_pb_as_table('Device {}'.format(self.device_id),
63 self.get_device(depth=-1))
64
65 def do_ports(self, line):
66 """Show ports of device"""
67 device = self.get_device(depth=-1)
68 omit_fields = {
69 }
70 print_pb_list_as_table('Device ports:', device.ports,
71 omit_fields, self.poutput)
Zsolt Haraszti80175202016-12-24 00:17:51 -080072
Sergio Slobodrian901bf4e2017-03-17 12:54:39 -040073 @options([
74 make_option('-f', '--default_freq', action="store", dest='default_freq',
75 type='long', default=None),
76 make_option('-e', '--enable', action='append', dest='enable',
77 default=None),
78 make_option('-d', '--disable', action='append', dest='disable',
79 default=None),
80 ])
81 def do_perf_config(self, line, opts):
82 print(line)
83 """Show and set the performance monitoring configuration of the device"""
84
85 device = self.get_device(depth=-1)
86 if not self.pm_config_last:
87 self.pm_config_last = device.pm_configs
88
89 # Ensure that a valid sub-command was provided
90 if line.strip() not in {"set", "show", "commit", "reset", ""}:
91 self.poutput(self.colorize('Error: ', 'red') + \
92 self.colorize(self.colorize(line.strip(), 'blue'),
93 'bold') + ' is not recognized')
94 return
95
96 # Ensure no options are provided when requesting to view the config
97 if line.strip() == "show" or line.strip() == "":
98 if opts.default_freq or opts.enable or opts.disable:
99 self.poutput(opts.disable)
100 self.poutput(self.colorize('Error: ', 'red') + 'use ' + \
101 self.colorize(self.colorize('"set"', 'blue'),
102 'bold') + ' to change settings')
103 return
104
105 if line.strip() == "set": # Set the supplied values
106 # The defualt frequency
107 if opts.default_freq:
108 self.pm_config_last.default_freq = opts.default_freq
109 self.pm_config_dirty = True
110
111 if self.pm_config_last.grouped:
112 for g in self.pm_config_last.groups:
113 if opts.enable:
114 if g.group_name in opts.enable:
115 g.enabled = True
116 self.pm_config_dirty = True
117 for g in self.pm_config_last.groups:
118 if opts.disable:
119 if g.group_name in opts.disable:
120 g.enabled = False
121 self.pm_config_dirty = True
122 else:
123 for m in self.pm_config_last.metrics:
124 if opts.enable:
125 if m.name in opts.enable:
126 m.enabled = True
127 self.pm_config_dirty = True
128 for m in self.pm_config_last.metrics:
129 if opts.disable:
130 if m.name in opts.disable:
131 m.enabled = False
132 self.pm_config_dirty = True
133 #TODO: Add frequency overrides.
134
135 elif line.strip() == "commit" and self.pm_config_dirty:
136 stub = voltha_pb2.VolthaLocalServiceStub(self.get_channel())
137 stub.UpdateDevicePmConfigs(self.pm_config_last)
138 self.pm_config_last = self.get_device(depth=-1).pm_configs
139 self.pm_config_dirty = False
140 elif line.strip() == "reset" and self.pm_config_dirty:
141 self.pm_config_last = self.get_device(depth=-1).pm_configs
142 self.pm_config_dirty = False
143
144 omit_fields = {'groups', 'metrics', 'id'}
145 print_pb_as_table('PM Config:', self.pm_config_last, omit_fields,
146 self.poutput)
147 if self.pm_config_last.grouped:
148 #self.poutput("Supported metric groups:")
149 for g in self.pm_config_last.groups:
150 if self.pm_config_last.freq_override:
151 omit_fields = {'metrics'}
152 else:
153 omit_fields = {'group_freq','metrics'}
154 print_pb_as_table('', g, omit_fields, self.poutput)
155 if g.enabled:
156 state = 'enabled'
157 else:
158 state = 'disabled'
159 print_pb_list_as_table(
160 'Metric group {} is {}'.format(g.name,state),
161 g.metrics, {'enabled', 'sample_freq'}, self.poutput,
162 dividers=100)
163 else:
164 if self.pm_config_last.freq_override:
165 omit_fields = {}
166 else:
167 omit_fields = {'sample_freq'}
168 print_pb_list_as_table('Supported metrics:', self.pm_config_last.metrics,
169 omit_fields, self.poutput, dividers=100)
170
171
Zsolt Haraszti80175202016-12-24 00:17:51 -0800172 def do_flows(self, line):
Zsolt Harasztid036b7e2016-12-23 15:36:01 -0800173 """Show flow table for device"""
174 device = pb2dict(self.get_device(-1))
175 print_flows(
176 'Device',
177 self.device_id,
178 type=device['type'],
179 flows=device['flows']['items'],
180 groups=device['flow_groups']['items']
181 )
182