blob: 58bf6e427210f9d838567a00039b9d892c24083e [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001/*
2 * Copyright 2019-present Ciena Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package commands
17
18import (
19 "context"
20 "fmt"
David Bainbridge7052fe82020-03-25 10:37:00 -070021 "os"
22 "strconv"
23 "strings"
Girish Gowdra610acb42021-01-27 13:33:57 -080024 "time"
David Bainbridge7052fe82020-03-25 10:37:00 -070025
Scott Baker9173ed82020-05-19 08:30:12 -070026 "github.com/golang/protobuf/ptypes/empty"
Zack Williamse940c7a2019-08-21 14:25:39 -070027 flags "github.com/jessevdk/go-flags"
Scott Baker2b0ad652019-08-21 14:57:07 -070028 "github.com/opencord/voltctl/pkg/format"
kesavand8ec4fc02021-01-27 09:10:22 -050029 "github.com/opencord/voltha-protos/v4/go/common"
30 "github.com/opencord/voltha-protos/v4/go/extension"
31 "github.com/opencord/voltha-protos/v4/go/voltha"
Zack Williamse940c7a2019-08-21 14:25:39 -070032)
33
34const (
David K. Bainbridge89003c42020-02-27 17:22:49 -080035 DEFAULT_DEVICE_FORMAT = "table{{ .Id }}\t{{.Type}}\t{{.Root}}\t{{.ParentId}}\t{{.SerialNumber}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.ConnectStatus}}\t{{.Reason}}"
Zack Williamse940c7a2019-08-21 14:25:39 -070036 DEFAULT_DEVICE_PORTS_FORMAT = "table{{.PortNo}}\t{{.Label}}\t{{.Type}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.DeviceId}}\t{{.Peers}}"
37 DEFAULT_DEVICE_INSPECT_FORMAT = `ID: {{.Id}}
38 TYPE: {{.Type}}
39 ROOT: {{.Root}}
40 PARENTID: {{.ParentId}}
41 SERIALNUMBER: {{.SerialNumber}}
42 VLAN: {{.Vlan}}
43 ADMINSTATE: {{.AdminState}}
44 OPERSTATUS: {{.OperStatus}}
45 CONNECTSTATUS: {{.ConnectStatus}}`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000046 DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT = "table{{.DefaultFreq}}\t{{.Grouped}}\t{{.FreqOverride}}"
47 DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT = "table{{.Name}}\t{{.Type}}\t{{.Enabled}}\t{{.SampleFreq}}"
48 DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT = "table{{.GroupName}}\t{{.Enabled}}\t{{.GroupFreq}}"
49 DEFAULT_DEVICE_VALUE_GET_FORMAT = "table{{.Name}}\t{{.Result}}"
Andrea Campanella791d88b2021-01-08 13:29:00 +010050 DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT = "table{{.Name}}\t{{.Url}}\t{{.Crc}}\t{{.DownloadState}}\t{{.ImageVersion}}\t{{.LocalDir}}\t{{.ImageState}}\t{{.FileSize}}"
kesavand8ec4fc02021-01-27 09:10:22 -050051 DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT = `
52 TXBYTES: {{.TxBytes}}
53 TXPACKETS: {{.TxPackets}}
54 TXERRPACKETS: {{.TxErrorPackets}}
55 TXBCASTPACKETS: {{.TxBcastPackets}}
56 TXUCASTPACKETS: {{.TxUcastPackets}}
57 TXMCASTPACKETS: {{.TxMcastPackets}}
58 RXBYTES: {{.RxBytes}}
59 RXPACKETS: {{.RxPackets}}
60 RXERRPACKETS: {{.RxErrorPackets}}
61 RXBCASTPACKETS: {{.RxBcastPackets}}
62 RXUCASTPACKETS: {{.RxUcastPackets}}
63 RXMCASTPACKETS: {{.RxMcastPackets}}`
kesavand6d1131f2021-02-05 22:38:15 +053064 DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT = `
65 ADMIN_STATE: {{.AdmState}}
66 OPERATIONAL_STATE: {{.OperState}}
67 CONFIG_IND: {{.ConfigInd}}`
Zack Williamse940c7a2019-08-21 14:25:39 -070068)
69
70type DeviceList struct {
71 ListOutputOptions
72}
73
74type DeviceCreate struct {
David Bainbridge1a514392020-06-23 11:12:51 -070075 DeviceType string `short:"t" required:"true" long:"devicetype" description:"Device type"`
David Bainbridge835dd0e2020-04-01 10:30:09 -070076 MACAddress string `short:"m" long:"macaddress" default:"" description:"MAC Address"`
Zack Williamse940c7a2019-08-21 14:25:39 -070077 IPAddress string `short:"i" long:"ipaddress" default:"" description:"IP Address"`
78 HostAndPort string `short:"H" long:"hostandport" default:"" description:"Host and port"`
79}
80
81type DeviceId string
82
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000083type MetricName string
84type GroupName string
kesavand12cd8eb2020-01-20 22:25:22 -050085type PortNum uint32
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -080086type ValueFlag string
kesavand12cd8eb2020-01-20 22:25:22 -050087
Zack Williamse940c7a2019-08-21 14:25:39 -070088type DeviceDelete struct {
Himani Chawla9933ddc2020-10-12 23:53:27 +053089 Force bool `long:"force" description:"Delete device forcefully"`
90 Args struct {
Zack Williamse940c7a2019-08-21 14:25:39 -070091 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
92 } `positional-args:"yes"`
93}
94
95type DeviceEnable struct {
96 Args struct {
97 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
98 } `positional-args:"yes"`
99}
100
101type DeviceDisable struct {
102 Args struct {
103 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
104 } `positional-args:"yes"`
105}
106
107type DeviceReboot struct {
108 Args struct {
109 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
110 } `positional-args:"yes"`
111}
112
113type DeviceFlowList struct {
114 ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530115 FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700116 Args struct {
117 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
118 } `positional-args:"yes"`
119}
120
121type DevicePortList struct {
122 ListOutputOptions
123 Args struct {
124 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
125 } `positional-args:"yes"`
126}
127
128type DeviceInspect struct {
129 OutputOptionsJson
130 Args struct {
131 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
132 } `positional-args:"yes"`
133}
134
kesavand12cd8eb2020-01-20 22:25:22 -0500135type DevicePortEnable struct {
136 Args struct {
137 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
138 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
139 } `positional-args:"yes"`
140}
141
142type DevicePortDisable struct {
143 Args struct {
144 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
145 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
146 } `positional-args:"yes"`
147}
148
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000149type DevicePmConfigsGet struct {
150 ListOutputOptions
151 Args struct {
152 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
153 } `positional-args:"yes"`
154}
155
156type DevicePmConfigMetricList struct {
157 ListOutputOptions
158 Args struct {
159 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
160 } `positional-args:"yes"`
161}
162
163type DevicePmConfigGroupList struct {
164 ListOutputOptions
165 Args struct {
166 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
167 } `positional-args:"yes"`
168}
169
170type DevicePmConfigGroupMetricList struct {
171 ListOutputOptions
172 Args struct {
173 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
174 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
175 } `positional-args:"yes"`
176}
177
178type DevicePmConfigFrequencySet struct {
179 OutputOptions
180 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800181 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
182 Interval time.Duration `positional-arg-name:"INTERVAL" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000183 } `positional-args:"yes"`
184}
185
186type DevicePmConfigMetricEnable struct {
187 Args struct {
188 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
189 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
190 } `positional-args:"yes"`
191}
192
193type DevicePmConfigMetricDisable struct {
194 Args struct {
195 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
196 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
197 } `positional-args:"yes"`
198}
199
200type DevicePmConfigGroupEnable struct {
201 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800202 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
203 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000204 } `positional-args:"yes"`
205}
206
207type DevicePmConfigGroupDisable struct {
208 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800209 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
210 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
211 } `positional-args:"yes"`
212}
213
214type DevicePmConfigGroupFrequencySet struct {
215 OutputOptions
216 Args struct {
217 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
218 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
219 Interval time.Duration `positional-arg-name:"INTERVAL" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000220 } `positional-args:"yes"`
221}
222
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800223type DeviceGetExtValue struct {
224 ListOutputOptions
225 Args struct {
226 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
227 Valueflag ValueFlag `positional-arg-name:"VALUE_FLAG" required:"yes"`
228 } `positional-args:"yes"`
229}
Rohan Agrawald7df3772020-06-29 11:23:36 +0000230
231type DevicePmConfigSetMaxSkew struct {
232 Args struct {
233 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
234 MaxSkew uint32 `positional-arg-name:"MAX_SKEW" required:"yes"`
235 } `positional-args:"yes"`
236}
237
Andrea Campanella791d88b2021-01-08 13:29:00 +0100238type DeviceOnuListImages struct {
239 ListOutputOptions
240 Args struct {
241 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
242 } `positional-args:"yes"`
243}
244
245type DeviceOnuDownloadImage struct {
246 Args struct {
247 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
248 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
249 Url string `positional-arg-name:"IMAGE_URL" required:"yes"`
250 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
251 Crc uint32 `positional-arg-name:"IMAGE_CRC" required:"yes"`
252 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
253 } `positional-args:"yes"`
254}
255
256type DeviceOnuActivateImageUpdate struct {
257 Args struct {
258 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
259 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
260 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
261 SaveConfig bool `positional-arg-name:"SAVE_EXISTING_CONFIG"`
262 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
Andrea Campanella7b2ecf42021-02-25 12:27:15 +0100263 } `positional-args:"yes"`
kesavand8ec4fc02021-01-27 09:10:22 -0500264}
265type DeviceGetPortStats struct {
266 ListOutputOptions
267 Args struct {
268 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
269 PortNo uint32 `positional-arg-name:"PORT_NO" required:"yes"`
270 PortType string `positional-arg-name:"PORT_TYPE" required:"yes"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100271 } `positional-args:"yes"`
272}
kesavand6d1131f2021-02-05 22:38:15 +0530273type UniStatus struct {
274 ListOutputOptions
275 Args struct {
276 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
277 UniIndex uint32 `positional-arg-name:"UNI_INDEX" required:"yes"`
278 } `positional-args:"yes"`
279}
Zack Williamse940c7a2019-08-21 14:25:39 -0700280type DeviceOpts struct {
281 List DeviceList `command:"list"`
282 Create DeviceCreate `command:"create"`
283 Delete DeviceDelete `command:"delete"`
284 Enable DeviceEnable `command:"enable"`
285 Disable DeviceDisable `command:"disable"`
286 Flows DeviceFlowList `command:"flows"`
kesavand12cd8eb2020-01-20 22:25:22 -0500287 Port struct {
288 List DevicePortList `command:"list"`
289 Enable DevicePortEnable `command:"enable"`
290 Disable DevicePortDisable `command:"disable"`
291 } `command:"port"`
292 Inspect DeviceInspect `command:"inspect"`
293 Reboot DeviceReboot `command:"reboot"`
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800294 Value struct {
295 Get DeviceGetExtValue `command:"get"`
296 } `command:"value"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000297 PmConfig struct {
Rohan Agrawald7df3772020-06-29 11:23:36 +0000298 Get DevicePmConfigsGet `command:"get"`
299 MaxSkew struct {
300 Set DevicePmConfigSetMaxSkew `command:"set"`
301 } `command:"maxskew"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000302 Frequency struct {
303 Set DevicePmConfigFrequencySet `command:"set"`
304 } `command:"frequency"`
305 Metric struct {
306 List DevicePmConfigMetricList `command:"list"`
307 Enable DevicePmConfigMetricEnable `command:"enable"`
308 Disable DevicePmConfigMetricDisable `command:"disable"`
309 } `command:"metric"`
310 Group struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800311 List DevicePmConfigGroupList `command:"list"`
312 Enable DevicePmConfigGroupEnable `command:"enable"`
313 Disable DevicePmConfigGroupDisable `command:"disable"`
314 Set DevicePmConfigGroupFrequencySet `command:"set"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000315 } `command:"group"`
316 GroupMetric struct {
317 List DevicePmConfigGroupMetricList `command:"list"`
318 } `command:"groupmetric"`
319 } `command:"pmconfig"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100320 Image struct {
321 Get DeviceOnuListImages `command:"list"`
322 Download DeviceOnuDownloadImage `command:"download"`
323 Activate DeviceOnuActivateImageUpdate `command:"activate"`
324 } `command:"image"`
kesavand8ec4fc02021-01-27 09:10:22 -0500325 GetExtVal struct {
kesavand6d1131f2021-02-05 22:38:15 +0530326 Stats DeviceGetPortStats `command:"portstats"`
327 UniStatus UniStatus `command:"unistatus"`
kesavand8ec4fc02021-01-27 09:10:22 -0500328 } `command:"getextval"`
Zack Williamse940c7a2019-08-21 14:25:39 -0700329}
330
331var deviceOpts = DeviceOpts{}
332
333func RegisterDeviceCommands(parser *flags.Parser) {
David Bainbridge12f036f2019-10-15 22:09:04 +0000334 if _, err := parser.AddCommand("device", "device commands", "Commands to query and manipulate VOLTHA devices", &deviceOpts); err != nil {
David Bainbridgea6722342019-10-24 23:55:53 +0000335 Error.Fatalf("Unexpected error while attempting to register device commands : %s", err)
David Bainbridge12f036f2019-10-15 22:09:04 +0000336 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700337}
338
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000339func (i *MetricName) Complete(match string) []flags.Completion {
340 conn, err := NewConnection()
341 if err != nil {
342 return nil
343 }
344 defer conn.Close()
345
346 client := voltha.NewVolthaServiceClient(conn)
347
348 var deviceId string
349found:
350 for i := len(os.Args) - 1; i >= 0; i -= 1 {
351 switch os.Args[i] {
352 case "enable":
353 fallthrough
354 case "disable":
355 if len(os.Args) > i+1 {
356 deviceId = os.Args[i+1]
357 } else {
358 return nil
359 }
360 break found
361 default:
362 }
363 }
364
365 if len(deviceId) == 0 {
366 return nil
367 }
368
369 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
370 defer cancel()
371
372 id := voltha.ID{Id: string(deviceId)}
373
374 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
375
376 if err != nil {
377 return nil
378 }
379
380 list := make([]flags.Completion, 0)
381 for _, metrics := range pmconfigs.Metrics {
382 if strings.HasPrefix(metrics.Name, match) {
383 list = append(list, flags.Completion{Item: metrics.Name})
384 }
385 }
386
387 return list
388}
389
390func (i *GroupName) Complete(match string) []flags.Completion {
391 conn, err := NewConnection()
392 if err != nil {
393 return nil
394 }
395 defer conn.Close()
396
397 client := voltha.NewVolthaServiceClient(conn)
398
399 var deviceId string
400found:
401 for i := len(os.Args) - 1; i >= 0; i -= 1 {
402 switch os.Args[i] {
403 case "list":
404 fallthrough
405 case "enable":
406 fallthrough
407 case "disable":
408 if len(os.Args) > i+1 {
409 deviceId = os.Args[i+1]
410 } else {
411 return nil
412 }
413 break found
414 default:
415 }
416 }
417
418 if len(deviceId) == 0 {
419 return nil
420 }
421
422 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
423 defer cancel()
424
425 id := voltha.ID{Id: string(deviceId)}
426
427 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
428
429 if err != nil {
430 return nil
431 }
432
433 list := make([]flags.Completion, 0)
434 for _, group := range pmconfigs.Groups {
435 if strings.HasPrefix(group.GroupName, match) {
436 list = append(list, flags.Completion{Item: group.GroupName})
437 }
438 }
439 return list
440}
441
kesavand12cd8eb2020-01-20 22:25:22 -0500442func (i *PortNum) Complete(match string) []flags.Completion {
443 conn, err := NewConnection()
444 if err != nil {
445 return nil
446 }
447 defer conn.Close()
448
Scott Baker9173ed82020-05-19 08:30:12 -0700449 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500450
451 /*
452 * The command line args when completing for PortNum will be a DeviceId
453 * followed by one or more PortNums. So walk the argument list from the
454 * end and find the first argument that is enable/disable as those are
455 * the subcommands that come before the positional arguments. It would
456 * be nice if this package gave us the list of optional arguments
457 * already parsed.
458 */
459 var deviceId string
460found:
461 for i := len(os.Args) - 1; i >= 0; i -= 1 {
462 switch os.Args[i] {
463 case "enable":
464 fallthrough
465 case "disable":
466 if len(os.Args) > i+1 {
467 deviceId = os.Args[i+1]
468 } else {
469 return nil
470 }
471 break found
472 default:
473 }
474 }
475
476 if len(deviceId) == 0 {
477 return nil
478 }
479
kesavand12cd8eb2020-01-20 22:25:22 -0500480 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
481 defer cancel()
kesavand12cd8eb2020-01-20 22:25:22 -0500482
Scott Baker9173ed82020-05-19 08:30:12 -0700483 id := voltha.ID{Id: string(deviceId)}
kesavand12cd8eb2020-01-20 22:25:22 -0500484
Scott Baker9173ed82020-05-19 08:30:12 -0700485 ports, err := client.ListDevicePorts(ctx, &id)
kesavand12cd8eb2020-01-20 22:25:22 -0500486 if err != nil {
487 return nil
488 }
489
490 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700491 for _, item := range ports.Items {
492 pn := strconv.FormatUint(uint64(item.PortNo), 10)
kesavand12cd8eb2020-01-20 22:25:22 -0500493 if strings.HasPrefix(pn, match) {
494 list = append(list, flags.Completion{Item: pn})
495 }
496 }
497
498 return list
499}
500
Zack Williamse940c7a2019-08-21 14:25:39 -0700501func (i *DeviceId) Complete(match string) []flags.Completion {
502 conn, err := NewConnection()
503 if err != nil {
504 return nil
505 }
506 defer conn.Close()
507
Scott Baker9173ed82020-05-19 08:30:12 -0700508 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700509
510 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
511 defer cancel()
512
Scott Baker9173ed82020-05-19 08:30:12 -0700513 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700514 if err != nil {
515 return nil
516 }
517
518 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700519 for _, item := range devices.Items {
520 if strings.HasPrefix(item.Id, match) {
521 list = append(list, flags.Completion{Item: item.Id})
Zack Williamse940c7a2019-08-21 14:25:39 -0700522 }
523 }
524
525 return list
526}
527
528func (options *DeviceList) Execute(args []string) error {
529
530 conn, err := NewConnection()
531 if err != nil {
532 return err
533 }
534 defer conn.Close()
535
Scott Baker9173ed82020-05-19 08:30:12 -0700536 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700537
538 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
539 defer cancel()
540
Scott Baker9173ed82020-05-19 08:30:12 -0700541 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700542 if err != nil {
543 return err
544 }
545
546 outputFormat := CharReplacer.Replace(options.Format)
547 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000548 outputFormat = GetCommandOptionWithDefault("device-list", "format", DEFAULT_DEVICE_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700549 }
550 if options.Quiet {
551 outputFormat = "{{.Id}}"
552 }
553
David Bainbridgea6722342019-10-24 23:55:53 +0000554 orderBy := options.OrderBy
555 if orderBy == "" {
556 orderBy = GetCommandOptionWithDefault("device-list", "order", "")
557 }
558
Scott Baker9173ed82020-05-19 08:30:12 -0700559 // Make sure json output prints an empty list, not "null"
560 if devices.Items == nil {
561 devices.Items = make([]*voltha.Device, 0)
Zack Williamse940c7a2019-08-21 14:25:39 -0700562 }
563
564 result := CommandResult{
565 Format: format.Format(outputFormat),
566 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000567 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700568 OutputAs: toOutputType(options.OutputAs),
569 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700570 Data: devices.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700571 }
572
573 GenerateOutput(&result)
574 return nil
575}
576
577func (options *DeviceCreate) Execute(args []string) error {
578
Scott Baker9173ed82020-05-19 08:30:12 -0700579 device := voltha.Device{}
Zack Williamse940c7a2019-08-21 14:25:39 -0700580 if options.HostAndPort != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700581 device.Address = &voltha.Device_HostAndPort{HostAndPort: options.HostAndPort}
Zack Williamse940c7a2019-08-21 14:25:39 -0700582 } else if options.IPAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700583 device.Address = &voltha.Device_Ipv4Address{Ipv4Address: options.IPAddress}
Hardik Windlassce1de342020-02-04 21:58:07 +0000584 }
585 if options.MACAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700586 device.MacAddress = strings.ToLower(options.MACAddress)
Zack Williamse940c7a2019-08-21 14:25:39 -0700587 }
588 if options.DeviceType != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700589 device.Type = options.DeviceType
Zack Williamse940c7a2019-08-21 14:25:39 -0700590 }
591
592 conn, err := NewConnection()
593 if err != nil {
594 return err
595 }
596 defer conn.Close()
597
Scott Baker9173ed82020-05-19 08:30:12 -0700598 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700599
600 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
601 defer cancel()
602
Scott Baker9173ed82020-05-19 08:30:12 -0700603 createdDevice, err := client.CreateDevice(ctx, &device)
Zack Williamse940c7a2019-08-21 14:25:39 -0700604 if err != nil {
605 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700606 }
607
Scott Baker9173ed82020-05-19 08:30:12 -0700608 fmt.Printf("%s\n", createdDevice.Id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700609
610 return nil
611}
612
613func (options *DeviceDelete) Execute(args []string) error {
614
615 conn, err := NewConnection()
616 if err != nil {
617 return err
618 }
619 defer conn.Close()
620
Scott Baker9173ed82020-05-19 08:30:12 -0700621 client := voltha.NewVolthaServiceClient(conn)
David Bainbridge7052fe82020-03-25 10:37:00 -0700622 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700623 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700624 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
625 defer cancel()
626
Scott Baker9173ed82020-05-19 08:30:12 -0700627 id := voltha.ID{Id: string(i)}
Himani Chawla9933ddc2020-10-12 23:53:27 +0530628 if options.Force {
629 _, err = client.ForceDeleteDevice(ctx, &id)
630 } else {
631 _, err = client.DeleteDevice(ctx, &id)
632 }
Scott Baker9173ed82020-05-19 08:30:12 -0700633
Zack Williamse940c7a2019-08-21 14:25:39 -0700634 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000635 Error.Printf("Error while deleting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700636 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700637 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700638 }
639 fmt.Printf("%s\n", i)
640 }
641
David Bainbridge7052fe82020-03-25 10:37:00 -0700642 if lastErr != nil {
643 return NoReportErr
644 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700645 return nil
646}
647
648func (options *DeviceEnable) Execute(args []string) error {
649 conn, err := NewConnection()
650 if err != nil {
651 return err
652 }
653 defer conn.Close()
654
Scott Baker9173ed82020-05-19 08:30:12 -0700655 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700656
David Bainbridge7052fe82020-03-25 10:37:00 -0700657 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700658 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700659 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
660 defer cancel()
661
Scott Baker9173ed82020-05-19 08:30:12 -0700662 id := voltha.ID{Id: string(i)}
663
664 _, err := client.EnableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700665 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000666 Error.Printf("Error while enabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700667 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700668 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700669 }
670 fmt.Printf("%s\n", i)
671 }
672
David Bainbridge7052fe82020-03-25 10:37:00 -0700673 if lastErr != nil {
674 return NoReportErr
675 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700676 return nil
677}
678
679func (options *DeviceDisable) Execute(args []string) error {
680 conn, err := NewConnection()
681 if err != nil {
682 return err
683 }
684 defer conn.Close()
685
Scott Baker9173ed82020-05-19 08:30:12 -0700686 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700687
David Bainbridge7052fe82020-03-25 10:37:00 -0700688 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700689 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700690 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
691 defer cancel()
692
Scott Baker9173ed82020-05-19 08:30:12 -0700693 id := voltha.ID{Id: string(i)}
694
695 _, err := client.DisableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700696 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000697 Error.Printf("Error while disabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700698 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700699 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700700 }
701 fmt.Printf("%s\n", i)
702 }
703
David Bainbridge7052fe82020-03-25 10:37:00 -0700704 if lastErr != nil {
705 return NoReportErr
706 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700707 return nil
708}
709
710func (options *DeviceReboot) Execute(args []string) error {
711 conn, err := NewConnection()
712 if err != nil {
713 return err
714 }
715 defer conn.Close()
716
Scott Baker9173ed82020-05-19 08:30:12 -0700717 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700718
David Bainbridge7052fe82020-03-25 10:37:00 -0700719 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700720 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700721 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
722 defer cancel()
723
Scott Baker9173ed82020-05-19 08:30:12 -0700724 id := voltha.ID{Id: string(i)}
725
726 _, err := client.RebootDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700727 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000728 Error.Printf("Error while rebooting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700729 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700730 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700731 }
732 fmt.Printf("%s\n", i)
733 }
734
David Bainbridge7052fe82020-03-25 10:37:00 -0700735 if lastErr != nil {
736 return NoReportErr
737 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700738 return nil
739}
740
741func (options *DevicePortList) Execute(args []string) error {
742
743 conn, err := NewConnection()
744 if err != nil {
745 return err
746 }
747 defer conn.Close()
748
Scott Baker9173ed82020-05-19 08:30:12 -0700749 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700750
751 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
752 defer cancel()
753
Scott Baker9173ed82020-05-19 08:30:12 -0700754 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700755
Scott Baker9173ed82020-05-19 08:30:12 -0700756 ports, err := client.ListDevicePorts(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700757 if err != nil {
758 return err
759 }
760
761 outputFormat := CharReplacer.Replace(options.Format)
762 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000763 outputFormat = GetCommandOptionWithDefault("device-ports", "format", DEFAULT_DEVICE_PORTS_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700764 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700765
David Bainbridgea6722342019-10-24 23:55:53 +0000766 orderBy := options.OrderBy
767 if orderBy == "" {
768 orderBy = GetCommandOptionWithDefault("device-ports", "order", "")
769 }
770
Zack Williamse940c7a2019-08-21 14:25:39 -0700771 result := CommandResult{
772 Format: format.Format(outputFormat),
773 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000774 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700775 OutputAs: toOutputType(options.OutputAs),
776 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700777 Data: ports.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700778 }
779
780 GenerateOutput(&result)
781 return nil
782}
783
784func (options *DeviceFlowList) Execute(args []string) error {
785 fl := &FlowList{}
786 fl.ListOutputOptions = options.ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530787 fl.FlowIdOptions = options.FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700788 fl.Args.Id = string(options.Args.Id)
David Bainbridgea6722342019-10-24 23:55:53 +0000789 fl.Method = "device-flows"
Zack Williamse940c7a2019-08-21 14:25:39 -0700790 return fl.Execute(args)
791}
792
793func (options *DeviceInspect) Execute(args []string) error {
794 if len(args) > 0 {
795 return fmt.Errorf("only a single argument 'DEVICE_ID' can be provided")
796 }
797
798 conn, err := NewConnection()
799 if err != nil {
800 return err
801 }
802 defer conn.Close()
803
Scott Baker9173ed82020-05-19 08:30:12 -0700804 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700805
806 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
807 defer cancel()
808
Scott Baker9173ed82020-05-19 08:30:12 -0700809 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700810
Scott Baker9173ed82020-05-19 08:30:12 -0700811 device, err := client.GetDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700812 if err != nil {
813 return err
814 }
815
Zack Williamse940c7a2019-08-21 14:25:39 -0700816 outputFormat := CharReplacer.Replace(options.Format)
817 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000818 outputFormat = GetCommandOptionWithDefault("device-inspect", "format", DEFAULT_DEVICE_INSPECT_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700819 }
820 if options.Quiet {
821 outputFormat = "{{.Id}}"
822 }
823
824 result := CommandResult{
825 Format: format.Format(outputFormat),
826 OutputAs: toOutputType(options.OutputAs),
827 NameLimit: options.NameLimit,
828 Data: device,
829 }
830 GenerateOutput(&result)
831 return nil
832}
kesavand12cd8eb2020-01-20 22:25:22 -0500833
834/*Device Port Enable */
835func (options *DevicePortEnable) Execute(args []string) error {
836 conn, err := NewConnection()
837 if err != nil {
838 return err
839 }
840 defer conn.Close()
841
Scott Baker9173ed82020-05-19 08:30:12 -0700842 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500843
kesavand12cd8eb2020-01-20 22:25:22 -0500844 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
845 defer cancel()
846
Scott Baker9173ed82020-05-19 08:30:12 -0700847 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
848
849 _, err = client.EnablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500850 if err != nil {
851 Error.Printf("Error enabling port number %v on device Id %s,err=%s\n", options.Args.PortId, options.Args.Id, ErrorToString(err))
852 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500853 }
854
855 return nil
856}
857
Scott Baker9173ed82020-05-19 08:30:12 -0700858/*Device Port Disable */
kesavand12cd8eb2020-01-20 22:25:22 -0500859func (options *DevicePortDisable) Execute(args []string) error {
860 conn, err := NewConnection()
861 if err != nil {
862 return err
863 }
864 defer conn.Close()
865
Scott Baker9173ed82020-05-19 08:30:12 -0700866 client := voltha.NewVolthaServiceClient(conn)
867
kesavand12cd8eb2020-01-20 22:25:22 -0500868 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
869 defer cancel()
870
Scott Baker9173ed82020-05-19 08:30:12 -0700871 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
872
873 _, err = client.DisablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500874 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700875 Error.Printf("Error enabling port number %v on device Id %s,err=%s\n", options.Args.PortId, options.Args.Id, ErrorToString(err))
kesavand12cd8eb2020-01-20 22:25:22 -0500876 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500877 }
Scott Baker9173ed82020-05-19 08:30:12 -0700878
kesavand12cd8eb2020-01-20 22:25:22 -0500879 return nil
880}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800881
Rohan Agrawald7df3772020-06-29 11:23:36 +0000882func (options *DevicePmConfigSetMaxSkew) Execute(args []string) error {
883 conn, err := NewConnection()
884 if err != nil {
885 return err
886 }
887 defer conn.Close()
888
889 client := voltha.NewVolthaServiceClient(conn)
890
891 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
892 defer cancel()
893
894 id := voltha.ID{Id: string(options.Args.Id)}
895
896 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
897 if err != nil {
898 return err
899 }
900
901 pmConfigs.MaxSkew = options.Args.MaxSkew
902
903 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
904 if err != nil {
905 return err
906 }
907
908 return nil
909}
910
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000911func (options *DevicePmConfigsGet) Execute(args []string) error {
912
913 conn, err := NewConnection()
914 if err != nil {
915 return err
916 }
917 defer conn.Close()
918
919 client := voltha.NewVolthaServiceClient(conn)
920
921 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
922 defer cancel()
923
924 id := voltha.ID{Id: string(options.Args.Id)}
925
926 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
927 if err != nil {
928 return err
929 }
930
931 outputFormat := CharReplacer.Replace(options.Format)
932 if outputFormat == "" {
933 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
934 }
935
936 orderBy := options.OrderBy
937 if orderBy == "" {
938 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
939 }
940
941 result := CommandResult{
942 Format: format.Format(outputFormat),
943 Filter: options.Filter,
944 OrderBy: orderBy,
945 OutputAs: toOutputType(options.OutputAs),
946 NameLimit: options.NameLimit,
947 Data: pmConfigs,
948 }
949
950 GenerateOutput(&result)
951 return nil
952
953}
954
955func (options *DevicePmConfigMetricList) Execute(args []string) error {
956
957 conn, err := NewConnection()
958 if err != nil {
959 return err
960 }
961 defer conn.Close()
962
963 client := voltha.NewVolthaServiceClient(conn)
964
965 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
966 defer cancel()
967
968 id := voltha.ID{Id: string(options.Args.Id)}
969
970 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
971 if err != nil {
972 return err
973 }
974
975 if !pmConfigs.Grouped {
976 for _, metric := range pmConfigs.Metrics {
977 if metric.SampleFreq == 0 {
978 metric.SampleFreq = pmConfigs.DefaultFreq
979 }
980 }
Rohan Agrawalbca69122020-06-17 14:59:03 +0000981 outputFormat := CharReplacer.Replace(options.Format)
982 if outputFormat == "" {
983 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
984 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000985
Rohan Agrawalbca69122020-06-17 14:59:03 +0000986 orderBy := options.OrderBy
987 if orderBy == "" {
988 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
989 }
990
991 result := CommandResult{
992 Format: format.Format(outputFormat),
993 Filter: options.Filter,
994 OrderBy: orderBy,
995 OutputAs: toOutputType(options.OutputAs),
996 NameLimit: options.NameLimit,
997 Data: pmConfigs.Metrics,
998 }
999
1000 GenerateOutput(&result)
1001 return nil
1002 } else {
1003 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001004 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001005}
1006
1007func (options *DevicePmConfigMetricEnable) Execute(args []string) error {
1008
1009 conn, err := NewConnection()
1010 if err != nil {
1011 return err
1012 }
1013 defer conn.Close()
1014
1015 client := voltha.NewVolthaServiceClient(conn)
1016
1017 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1018 defer cancel()
1019
1020 id := voltha.ID{Id: string(options.Args.Id)}
1021
1022 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1023 if err != nil {
1024 return err
1025 }
1026
1027 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001028 metrics := make(map[string]struct{})
1029 for _, metric := range pmConfigs.Metrics {
1030 metrics[metric.Name] = struct{}{}
1031 }
1032
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001033 for _, metric := range pmConfigs.Metrics {
1034 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001035 if _, exist := metrics[string(mName)]; !exist {
1036 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1037 }
1038
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001039 if string(mName) == metric.Name && !metric.Enabled {
1040 metric.Enabled = true
1041 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1042 if err != nil {
1043 return err
1044 }
1045 }
1046 }
1047 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001048 } else {
1049 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001050 }
1051 return nil
1052}
1053
1054func (options *DevicePmConfigMetricDisable) Execute(args []string) error {
1055
1056 conn, err := NewConnection()
1057 if err != nil {
1058 return err
1059 }
1060 defer conn.Close()
1061
1062 client := voltha.NewVolthaServiceClient(conn)
1063
1064 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1065 defer cancel()
1066
1067 id := voltha.ID{Id: string(options.Args.Id)}
1068
1069 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1070 if err != nil {
1071 return err
1072 }
1073
1074 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001075 metrics := make(map[string]struct{})
1076 for _, metric := range pmConfigs.Metrics {
1077 metrics[metric.Name] = struct{}{}
1078 }
1079
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001080 for _, metric := range pmConfigs.Metrics {
1081 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001082 if _, have := metrics[string(mName)]; !have {
1083 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1084 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001085 if string(mName) == metric.Name && metric.Enabled {
1086 metric.Enabled = false
1087 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1088 if err != nil {
1089 return err
1090 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001091 } else {
1092 return fmt.Errorf("Metric '%s' cannot be disabled", string(mName))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001093 }
1094 }
1095 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001096 } else {
1097 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001098 }
1099 return nil
1100}
1101
1102func (options *DevicePmConfigGroupEnable) Execute(args []string) error {
1103
1104 conn, err := NewConnection()
1105 if err != nil {
1106 return err
1107 }
1108 defer conn.Close()
1109
1110 client := voltha.NewVolthaServiceClient(conn)
1111
1112 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1113 defer cancel()
1114
1115 id := voltha.ID{Id: string(options.Args.Id)}
1116
1117 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1118 if err != nil {
1119 return err
1120 }
1121
1122 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001123 groups := make(map[string]struct{})
1124 for _, group := range pmConfigs.Groups {
1125 groups[group.GroupName] = struct{}{}
1126 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001127 for _, group := range pmConfigs.Groups {
Girish Gowdra610acb42021-01-27 13:33:57 -08001128 if _, have := groups[string(options.Args.Group)]; !have {
1129 return fmt.Errorf("Group Name '%s' does not exist", options.Args.Group)
1130 }
1131 if string(options.Args.Group) == group.GroupName && !group.Enabled {
1132 group.Enabled = true
1133 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1134 if err != nil {
1135 return err
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001136 }
1137 }
1138 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001139 } else {
1140 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001141 }
1142 return nil
1143}
1144
1145func (options *DevicePmConfigGroupDisable) Execute(args []string) error {
1146
1147 conn, err := NewConnection()
1148 if err != nil {
1149 return err
1150 }
1151 defer conn.Close()
1152
1153 client := voltha.NewVolthaServiceClient(conn)
1154
1155 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1156 defer cancel()
1157
1158 id := voltha.ID{Id: string(options.Args.Id)}
1159
1160 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1161 if err != nil {
1162 return err
1163 }
1164
1165 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001166 groups := make(map[string]struct{})
1167 for _, group := range pmConfigs.Groups {
1168 groups[group.GroupName] = struct{}{}
1169 }
1170
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001171 for _, group := range pmConfigs.Groups {
Girish Gowdra610acb42021-01-27 13:33:57 -08001172 if _, have := groups[string(options.Args.Group)]; !have {
1173 return fmt.Errorf("Group Name '%s' does not exist", options.Args.Group)
1174 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001175
Girish Gowdra610acb42021-01-27 13:33:57 -08001176 if string(options.Args.Group) == group.GroupName && group.Enabled {
1177 group.Enabled = false
1178 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1179 if err != nil {
1180 return err
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001181 }
1182 }
1183 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001184 } else {
1185 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001186 }
1187 return nil
1188}
1189
Girish Gowdra610acb42021-01-27 13:33:57 -08001190func (options *DevicePmConfigGroupFrequencySet) Execute(args []string) error {
1191
1192 conn, err := NewConnection()
1193 if err != nil {
1194 return err
1195 }
1196 defer conn.Close()
1197
1198 client := voltha.NewVolthaServiceClient(conn)
1199
1200 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1201 defer cancel()
1202
1203 id := voltha.ID{Id: string(options.Args.Id)}
1204
1205 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1206 if err != nil {
1207 return err
1208 }
1209
1210 if pmConfigs.Grouped {
1211 groups := make(map[string]struct{})
1212 for _, group := range pmConfigs.Groups {
1213 groups[group.GroupName] = struct{}{}
1214 }
1215
1216 for _, group := range pmConfigs.Groups {
1217 if _, have := groups[string(options.Args.Group)]; !have {
1218 return fmt.Errorf("group name '%s' does not exist", options.Args.Group)
1219 }
1220
1221 if string(options.Args.Group) == group.GroupName {
1222 if !group.Enabled {
1223 return fmt.Errorf("group '%s' is not enabled", options.Args.Group)
1224 }
1225 group.GroupFreq = uint32(options.Args.Interval.Seconds())
1226 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1227 if err != nil {
1228 return err
1229 }
1230 }
1231 }
1232 } else {
1233 return fmt.Errorf("device '%s' does not have group metrics", options.Args.Id)
1234 }
1235 return nil
1236}
1237
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001238func (options *DevicePmConfigGroupList) Execute(args []string) error {
1239
1240 conn, err := NewConnection()
1241 if err != nil {
1242 return err
1243 }
1244 defer conn.Close()
1245
1246 client := voltha.NewVolthaServiceClient(conn)
1247
1248 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1249 defer cancel()
1250
1251 id := voltha.ID{Id: string(options.Args.Id)}
1252
1253 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1254 if err != nil {
1255 return err
1256 }
1257
1258 if pmConfigs.Grouped {
1259 for _, group := range pmConfigs.Groups {
1260 if group.GroupFreq == 0 {
1261 group.GroupFreq = pmConfigs.DefaultFreq
1262 }
1263 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001264 outputFormat := CharReplacer.Replace(options.Format)
1265 if outputFormat == "" {
1266 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT)
1267 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001268
Rohan Agrawalbca69122020-06-17 14:59:03 +00001269 orderBy := options.OrderBy
1270 if orderBy == "" {
1271 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1272 }
1273
1274 result := CommandResult{
1275 Format: format.Format(outputFormat),
1276 Filter: options.Filter,
1277 OrderBy: orderBy,
1278 OutputAs: toOutputType(options.OutputAs),
1279 NameLimit: options.NameLimit,
1280 Data: pmConfigs.Groups,
1281 }
1282
1283 GenerateOutput(&result)
1284 } else {
1285 return fmt.Errorf("Device '%s' does not have Group Metrics", string(options.Args.Id))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001286 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001287 return nil
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001288}
1289
1290func (options *DevicePmConfigGroupMetricList) Execute(args []string) error {
1291
1292 var metrics []*voltha.PmConfig
1293 conn, err := NewConnection()
1294 if err != nil {
1295 return err
1296 }
1297 defer conn.Close()
1298
1299 client := voltha.NewVolthaServiceClient(conn)
1300
1301 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1302 defer cancel()
1303
1304 id := voltha.ID{Id: string(options.Args.Id)}
1305
1306 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1307 if err != nil {
1308 return err
1309 }
1310
1311 for _, groups := range pmConfigs.Groups {
1312
1313 if string(options.Args.Group) == groups.GroupName {
1314 for _, metric := range groups.Metrics {
1315 if metric.SampleFreq == 0 && groups.GroupFreq == 0 {
1316 metric.SampleFreq = pmConfigs.DefaultFreq
1317 } else {
1318 metric.SampleFreq = groups.GroupFreq
1319 }
1320 }
1321 metrics = groups.Metrics
1322 }
1323 }
1324
1325 outputFormat := CharReplacer.Replace(options.Format)
1326 if outputFormat == "" {
1327 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
1328 }
1329
1330 orderBy := options.OrderBy
1331 if orderBy == "" {
1332 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1333 }
1334
1335 result := CommandResult{
1336 Format: format.Format(outputFormat),
1337 Filter: options.Filter,
1338 OrderBy: orderBy,
1339 OutputAs: toOutputType(options.OutputAs),
1340 NameLimit: options.NameLimit,
1341 Data: metrics,
1342 }
1343
1344 GenerateOutput(&result)
1345 return nil
1346
1347}
1348
1349func (options *DevicePmConfigFrequencySet) Execute(args []string) error {
1350
1351 conn, err := NewConnection()
1352 if err != nil {
1353 return err
1354 }
1355 defer conn.Close()
1356
1357 client := voltha.NewVolthaServiceClient(conn)
1358
1359 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1360 defer cancel()
1361
1362 id := voltha.ID{Id: string(options.Args.Id)}
1363
1364 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1365 if err != nil {
1366 return err
1367 }
1368
Girish Gowdra610acb42021-01-27 13:33:57 -08001369 pmConfigs.DefaultFreq = uint32(options.Args.Interval.Seconds())
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001370
1371 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1372 if err != nil {
1373 return err
1374 }
1375
1376 outputFormat := CharReplacer.Replace(options.Format)
1377 if outputFormat == "" {
1378 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
1379 }
1380 if options.Quiet {
1381 outputFormat = "{{.Id}}"
1382 }
1383
1384 result := CommandResult{
1385 Format: format.Format(outputFormat),
1386 OutputAs: toOutputType(options.OutputAs),
1387 NameLimit: options.NameLimit,
1388 Data: pmConfigs,
1389 }
1390
1391 GenerateOutput(&result)
1392 return nil
1393
1394}
1395
Andrea Campanella791d88b2021-01-08 13:29:00 +01001396func (options *DeviceOnuListImages) Execute(args []string) error {
1397
1398 conn, err := NewConnection()
1399 if err != nil {
1400 return err
1401 }
1402 defer conn.Close()
1403
1404 client := voltha.NewVolthaServiceClient(conn)
1405
1406 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1407 defer cancel()
1408
1409 id := common.ID{Id: string(options.Args.Id)}
1410
1411 imageDownloads, err := client.ListImageDownloads(ctx, &id)
1412 if err != nil {
1413 return err
1414 }
1415
1416 outputFormat := CharReplacer.Replace(options.Format)
1417 if outputFormat == "" {
1418 outputFormat = GetCommandOptionWithDefault("device-image-list", "format", DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT)
1419 }
1420
1421 if options.Quiet {
1422 outputFormat = "{{.Id}}"
1423 }
1424
1425 //TODO orderby
1426
1427 // Make sure json output prints an empty list, not "null"
1428 if imageDownloads.Items == nil {
1429 imageDownloads.Items = make([]*voltha.ImageDownload, 0)
1430 }
1431
1432 result := CommandResult{
1433 Format: format.Format(outputFormat),
1434 OutputAs: toOutputType(options.OutputAs),
1435 NameLimit: options.NameLimit,
1436 Data: imageDownloads.Items,
1437 }
1438
1439 GenerateOutput(&result)
1440 return nil
1441
1442}
1443
1444func (options *DeviceOnuDownloadImage) Execute(args []string) error {
1445
1446 conn, err := NewConnection()
1447 if err != nil {
1448 return err
1449 }
1450 defer conn.Close()
1451
1452 client := voltha.NewVolthaServiceClient(conn)
1453
1454 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1455 defer cancel()
1456
1457 downloadImage := voltha.ImageDownload{
1458 Id: string(options.Args.Id),
1459 Name: options.Args.Name,
1460 Url: options.Args.Url,
1461 Crc: options.Args.Crc,
1462 LocalDir: options.Args.LocalDir,
1463 }
1464
1465 _, err = client.DownloadImage(ctx, &downloadImage)
1466 if err != nil {
1467 return err
1468 }
1469
1470 return nil
1471
1472}
1473
1474func (options *DeviceOnuActivateImageUpdate) Execute(args []string) error {
1475
1476 conn, err := NewConnection()
1477 if err != nil {
1478 return err
1479 }
1480 defer conn.Close()
1481
1482 client := voltha.NewVolthaServiceClient(conn)
1483
1484 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1485 defer cancel()
1486
1487 downloadImage := voltha.ImageDownload{
1488 Id: string(options.Args.Id),
1489 Name: options.Args.Name,
1490 ImageVersion: options.Args.ImageVersion,
1491 SaveConfig: options.Args.SaveConfig,
1492 LocalDir: options.Args.LocalDir,
1493 }
1494
1495 _, err = client.ActivateImageUpdate(ctx, &downloadImage)
1496 if err != nil {
1497 return err
1498 }
1499
1500 return nil
1501
1502}
1503
Scott Baker9173ed82020-05-19 08:30:12 -07001504type ReturnValueRow struct {
1505 Name string `json:"name"`
1506 Result interface{} `json:"result"`
1507}
1508
kesavand8ec4fc02021-01-27 09:10:22 -05001509func (options *DeviceGetPortStats) Execute(args []string) error {
1510 conn, err := NewConnection()
1511 if err != nil {
1512 return err
1513 }
1514 defer conn.Close()
1515 client := extension.NewExtensionClient(conn)
1516 var portType extension.GetOltPortCounters_PortType
1517
1518 if options.Args.PortType == "pon" {
1519 portType = extension.GetOltPortCounters_Port_PON_OLT
1520 } else if options.Args.PortType == "nni" {
1521
1522 portType = extension.GetOltPortCounters_Port_ETHERNET_NNI
1523 } else {
1524 return fmt.Errorf("expected interface type pon/nni, provided %s", options.Args.PortType)
1525 }
1526
1527 singleGetValReq := extension.SingleGetValueRequest{
1528 TargetId: string(options.Args.Id),
1529 Request: &extension.GetValueRequest{
1530 Request: &extension.GetValueRequest_OltPortInfo{
1531 OltPortInfo: &extension.GetOltPortCounters{
1532 PortNo: options.Args.PortNo,
1533 PortType: portType,
1534 },
1535 },
1536 },
1537 }
1538
1539 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1540 defer cancel()
1541 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1542 if err != nil {
1543 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1544 return err
1545 }
1546
1547 if rv.Response.Status != extension.GetValueResponse_OK {
1548 return fmt.Errorf("failed to get port stats %v", rv.Response.ErrReason.String())
1549 }
1550
1551 outputFormat := CharReplacer.Replace(options.Format)
1552 if outputFormat == "" {
1553 outputFormat = GetCommandOptionWithDefault("device-get-port-status", "format", DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT)
1554 }
1555
1556 result := CommandResult{
1557 Format: format.Format(outputFormat),
1558 OutputAs: toOutputType(options.OutputAs),
1559 NameLimit: options.NameLimit,
1560 Data: rv.GetResponse().GetPortCoutners(),
1561 }
1562 GenerateOutput(&result)
1563 return nil
1564}
1565
kesavand6d1131f2021-02-05 22:38:15 +05301566func (options *UniStatus) Execute(args []string) error {
1567 conn, err := NewConnection()
1568 if err != nil {
1569 return err
1570 }
1571 defer conn.Close()
1572 client := extension.NewExtensionClient(conn)
1573
1574 singleGetValReq := extension.SingleGetValueRequest{
1575 TargetId: string(options.Args.Id),
1576 Request: &extension.GetValueRequest{
1577 Request: &extension.GetValueRequest_UniInfo{
1578 UniInfo: &extension.GetOnuUniInfoRequest{
1579 UniIndex: options.Args.UniIndex,
1580 },
1581 },
1582 },
1583 }
1584 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1585 defer cancel()
1586 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1587 if err != nil {
1588 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1589 return err
1590 }
1591 if rv.Response.Status != extension.GetValueResponse_OK {
1592 return fmt.Errorf("failed to get uni status %v", rv.Response.ErrReason.String())
1593 }
1594 outputFormat := CharReplacer.Replace(options.Format)
1595 if outputFormat == "" {
1596 outputFormat = GetCommandOptionWithDefault("device-get-uni-status", "format", DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT)
1597 }
1598 result := CommandResult{
1599 Format: format.Format(outputFormat),
1600 OutputAs: toOutputType(options.OutputAs),
1601 NameLimit: options.NameLimit,
1602 Data: rv.GetResponse().GetUniInfo(),
1603 }
1604 GenerateOutput(&result)
1605 return nil
1606}
1607
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001608/*Device get Onu Distance */
1609func (options *DeviceGetExtValue) Execute(args []string) error {
1610 conn, err := NewConnection()
1611 if err != nil {
1612 return err
1613 }
1614 defer conn.Close()
1615
Scott Baker9173ed82020-05-19 08:30:12 -07001616 client := voltha.NewVolthaServiceClient(conn)
1617
1618 valueflag, okay := common.ValueType_Type_value[string(options.Args.Valueflag)]
1619 if !okay {
1620 Error.Printf("Unknown valueflag %s\n", options.Args.Valueflag)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001621 }
1622
Scott Baker9173ed82020-05-19 08:30:12 -07001623 val := voltha.ValueSpecifier{Id: string(options.Args.Id), Value: common.ValueType_Type(valueflag)}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001624
1625 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1626 defer cancel()
1627
Scott Baker9173ed82020-05-19 08:30:12 -07001628 rv, err := client.GetExtValue(ctx, &val)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001629 if err != nil {
1630 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1631 return err
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001632 }
1633
Scott Baker9173ed82020-05-19 08:30:12 -07001634 var rows []ReturnValueRow
1635 for name, num := range common.ValueType_Type_value {
1636 if num == 0 {
1637 // EMPTY is not a real value
1638 continue
1639 }
1640 if (rv.Error & uint32(num)) != 0 {
1641 row := ReturnValueRow{Name: name, Result: "Error"}
1642 rows = append(rows, row)
1643 }
1644 if (rv.Unsupported & uint32(num)) != 0 {
1645 row := ReturnValueRow{Name: name, Result: "Unsupported"}
1646 rows = append(rows, row)
1647 }
1648 if (rv.Set & uint32(num)) != 0 {
1649 switch name {
1650 case "DISTANCE":
1651 row := ReturnValueRow{Name: name, Result: rv.Distance}
1652 rows = append(rows, row)
1653 default:
1654 row := ReturnValueRow{Name: name, Result: "Unimplemented-in-voltctl"}
1655 rows = append(rows, row)
1656 }
1657 }
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001658 }
1659
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001660 outputFormat := CharReplacer.Replace(options.Format)
1661 if outputFormat == "" {
1662 outputFormat = GetCommandOptionWithDefault("device-value-get", "format", DEFAULT_DEVICE_VALUE_GET_FORMAT)
1663 }
1664
1665 result := CommandResult{
1666 Format: format.Format(outputFormat),
1667 OutputAs: toOutputType(options.OutputAs),
1668 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -07001669 Data: rows,
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001670 }
1671 GenerateOutput(&result)
1672 return nil
1673}