blob: f04ab4e13cef7b0130a27fb7a09b974f81f39187 [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"
24
Scott Baker9173ed82020-05-19 08:30:12 -070025 "github.com/golang/protobuf/ptypes/empty"
Zack Williamse940c7a2019-08-21 14:25:39 -070026 flags "github.com/jessevdk/go-flags"
Scott Baker2b0ad652019-08-21 14:57:07 -070027 "github.com/opencord/voltctl/pkg/format"
kesavand8ec4fc02021-01-27 09:10:22 -050028 "github.com/opencord/voltha-protos/v4/go/common"
29 "github.com/opencord/voltha-protos/v4/go/extension"
30 "github.com/opencord/voltha-protos/v4/go/voltha"
Zack Williamse940c7a2019-08-21 14:25:39 -070031)
32
33const (
David K. Bainbridge89003c42020-02-27 17:22:49 -080034 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 -070035 DEFAULT_DEVICE_PORTS_FORMAT = "table{{.PortNo}}\t{{.Label}}\t{{.Type}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.DeviceId}}\t{{.Peers}}"
36 DEFAULT_DEVICE_INSPECT_FORMAT = `ID: {{.Id}}
37 TYPE: {{.Type}}
38 ROOT: {{.Root}}
39 PARENTID: {{.ParentId}}
40 SERIALNUMBER: {{.SerialNumber}}
41 VLAN: {{.Vlan}}
42 ADMINSTATE: {{.AdminState}}
43 OPERSTATUS: {{.OperStatus}}
44 CONNECTSTATUS: {{.ConnectStatus}}`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000045 DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT = "table{{.DefaultFreq}}\t{{.Grouped}}\t{{.FreqOverride}}"
46 DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT = "table{{.Name}}\t{{.Type}}\t{{.Enabled}}\t{{.SampleFreq}}"
47 DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT = "table{{.GroupName}}\t{{.Enabled}}\t{{.GroupFreq}}"
48 DEFAULT_DEVICE_VALUE_GET_FORMAT = "table{{.Name}}\t{{.Result}}"
Andrea Campanella791d88b2021-01-08 13:29:00 +010049 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 -050050 DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT = `
51 TXBYTES: {{.TxBytes}}
52 TXPACKETS: {{.TxPackets}}
53 TXERRPACKETS: {{.TxErrorPackets}}
54 TXBCASTPACKETS: {{.TxBcastPackets}}
55 TXUCASTPACKETS: {{.TxUcastPackets}}
56 TXMCASTPACKETS: {{.TxMcastPackets}}
57 RXBYTES: {{.RxBytes}}
58 RXPACKETS: {{.RxPackets}}
59 RXERRPACKETS: {{.RxErrorPackets}}
60 RXBCASTPACKETS: {{.RxBcastPackets}}
61 RXUCASTPACKETS: {{.RxUcastPackets}}
62 RXMCASTPACKETS: {{.RxMcastPackets}}`
Zack Williamse940c7a2019-08-21 14:25:39 -070063)
64
65type DeviceList struct {
66 ListOutputOptions
67}
68
69type DeviceCreate struct {
David Bainbridge1a514392020-06-23 11:12:51 -070070 DeviceType string `short:"t" required:"true" long:"devicetype" description:"Device type"`
David Bainbridge835dd0e2020-04-01 10:30:09 -070071 MACAddress string `short:"m" long:"macaddress" default:"" description:"MAC Address"`
Zack Williamse940c7a2019-08-21 14:25:39 -070072 IPAddress string `short:"i" long:"ipaddress" default:"" description:"IP Address"`
73 HostAndPort string `short:"H" long:"hostandport" default:"" description:"Host and port"`
74}
75
76type DeviceId string
77
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000078type MetricName string
79type GroupName string
kesavand12cd8eb2020-01-20 22:25:22 -050080type PortNum uint32
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -080081type ValueFlag string
kesavand12cd8eb2020-01-20 22:25:22 -050082
Zack Williamse940c7a2019-08-21 14:25:39 -070083type DeviceDelete struct {
Himani Chawla9933ddc2020-10-12 23:53:27 +053084 Force bool `long:"force" description:"Delete device forcefully"`
85 Args struct {
Zack Williamse940c7a2019-08-21 14:25:39 -070086 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
87 } `positional-args:"yes"`
88}
89
90type DeviceEnable struct {
91 Args struct {
92 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
93 } `positional-args:"yes"`
94}
95
96type DeviceDisable struct {
97 Args struct {
98 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
99 } `positional-args:"yes"`
100}
101
102type DeviceReboot struct {
103 Args struct {
104 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
105 } `positional-args:"yes"`
106}
107
108type DeviceFlowList struct {
109 ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530110 FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700111 Args struct {
112 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
113 } `positional-args:"yes"`
114}
115
116type DevicePortList struct {
117 ListOutputOptions
118 Args struct {
119 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
120 } `positional-args:"yes"`
121}
122
123type DeviceInspect struct {
124 OutputOptionsJson
125 Args struct {
126 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
127 } `positional-args:"yes"`
128}
129
kesavand12cd8eb2020-01-20 22:25:22 -0500130type DevicePortEnable struct {
131 Args struct {
132 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
133 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
134 } `positional-args:"yes"`
135}
136
137type DevicePortDisable struct {
138 Args struct {
139 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
140 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
141 } `positional-args:"yes"`
142}
143
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000144type DevicePmConfigsGet struct {
145 ListOutputOptions
146 Args struct {
147 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
148 } `positional-args:"yes"`
149}
150
151type DevicePmConfigMetricList struct {
152 ListOutputOptions
153 Args struct {
154 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
155 } `positional-args:"yes"`
156}
157
158type DevicePmConfigGroupList struct {
159 ListOutputOptions
160 Args struct {
161 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
162 } `positional-args:"yes"`
163}
164
165type DevicePmConfigGroupMetricList struct {
166 ListOutputOptions
167 Args struct {
168 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
169 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
170 } `positional-args:"yes"`
171}
172
173type DevicePmConfigFrequencySet struct {
174 OutputOptions
175 Args struct {
176 Frequency uint32 `positional-arg-name:"FREQUENCY" required:"yes"`
177 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
178 } `positional-args:"yes"`
179}
180
181type DevicePmConfigMetricEnable struct {
182 Args struct {
183 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
184 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
185 } `positional-args:"yes"`
186}
187
188type DevicePmConfigMetricDisable struct {
189 Args struct {
190 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
191 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
192 } `positional-args:"yes"`
193}
194
195type DevicePmConfigGroupEnable struct {
196 Args struct {
197 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
198 Groups []GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
199 } `positional-args:"yes"`
200}
201
202type DevicePmConfigGroupDisable struct {
203 Args struct {
204 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
205 Groups []GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
206 } `positional-args:"yes"`
207}
208
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800209type DeviceGetExtValue struct {
210 ListOutputOptions
211 Args struct {
212 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
213 Valueflag ValueFlag `positional-arg-name:"VALUE_FLAG" required:"yes"`
214 } `positional-args:"yes"`
215}
Rohan Agrawald7df3772020-06-29 11:23:36 +0000216
217type DevicePmConfigSetMaxSkew struct {
218 Args struct {
219 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
220 MaxSkew uint32 `positional-arg-name:"MAX_SKEW" required:"yes"`
221 } `positional-args:"yes"`
222}
223
Andrea Campanella791d88b2021-01-08 13:29:00 +0100224type DeviceOnuListImages struct {
225 ListOutputOptions
226 Args struct {
227 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
228 } `positional-args:"yes"`
229}
230
231type DeviceOnuDownloadImage struct {
232 Args struct {
233 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
234 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
235 Url string `positional-arg-name:"IMAGE_URL" required:"yes"`
236 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
237 Crc uint32 `positional-arg-name:"IMAGE_CRC" required:"yes"`
238 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
239 } `positional-args:"yes"`
240}
241
242type DeviceOnuActivateImageUpdate struct {
243 Args struct {
244 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
245 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
246 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
247 SaveConfig bool `positional-arg-name:"SAVE_EXISTING_CONFIG"`
248 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
kesavand8ec4fc02021-01-27 09:10:22 -0500249 }
250}
251type DeviceGetPortStats struct {
252 ListOutputOptions
253 Args struct {
254 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
255 PortNo uint32 `positional-arg-name:"PORT_NO" required:"yes"`
256 PortType string `positional-arg-name:"PORT_TYPE" required:"yes"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100257 } `positional-args:"yes"`
258}
259
Zack Williamse940c7a2019-08-21 14:25:39 -0700260type DeviceOpts struct {
261 List DeviceList `command:"list"`
262 Create DeviceCreate `command:"create"`
263 Delete DeviceDelete `command:"delete"`
264 Enable DeviceEnable `command:"enable"`
265 Disable DeviceDisable `command:"disable"`
266 Flows DeviceFlowList `command:"flows"`
kesavand12cd8eb2020-01-20 22:25:22 -0500267 Port struct {
268 List DevicePortList `command:"list"`
269 Enable DevicePortEnable `command:"enable"`
270 Disable DevicePortDisable `command:"disable"`
271 } `command:"port"`
272 Inspect DeviceInspect `command:"inspect"`
273 Reboot DeviceReboot `command:"reboot"`
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800274 Value struct {
275 Get DeviceGetExtValue `command:"get"`
276 } `command:"value"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000277 PmConfig struct {
Rohan Agrawald7df3772020-06-29 11:23:36 +0000278 Get DevicePmConfigsGet `command:"get"`
279 MaxSkew struct {
280 Set DevicePmConfigSetMaxSkew `command:"set"`
281 } `command:"maxskew"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000282 Frequency struct {
283 Set DevicePmConfigFrequencySet `command:"set"`
284 } `command:"frequency"`
285 Metric struct {
286 List DevicePmConfigMetricList `command:"list"`
287 Enable DevicePmConfigMetricEnable `command:"enable"`
288 Disable DevicePmConfigMetricDisable `command:"disable"`
289 } `command:"metric"`
290 Group struct {
291 List DevicePmConfigGroupList `command:"list"`
292 Enable DevicePmConfigGroupEnable `command:"enable"`
293 Disable DevicePmConfigGroupDisable `command:"disable"`
294 } `command:"group"`
295 GroupMetric struct {
296 List DevicePmConfigGroupMetricList `command:"list"`
297 } `command:"groupmetric"`
298 } `command:"pmconfig"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100299 Image struct {
300 Get DeviceOnuListImages `command:"list"`
301 Download DeviceOnuDownloadImage `command:"download"`
302 Activate DeviceOnuActivateImageUpdate `command:"activate"`
303 } `command:"image"`
kesavand8ec4fc02021-01-27 09:10:22 -0500304 GetExtVal struct {
305 Stats DeviceGetPortStats `command:"portstats"`
306 } `command:"getextval"`
Zack Williamse940c7a2019-08-21 14:25:39 -0700307}
308
309var deviceOpts = DeviceOpts{}
310
311func RegisterDeviceCommands(parser *flags.Parser) {
David Bainbridge12f036f2019-10-15 22:09:04 +0000312 if _, err := parser.AddCommand("device", "device commands", "Commands to query and manipulate VOLTHA devices", &deviceOpts); err != nil {
David Bainbridgea6722342019-10-24 23:55:53 +0000313 Error.Fatalf("Unexpected error while attempting to register device commands : %s", err)
David Bainbridge12f036f2019-10-15 22:09:04 +0000314 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700315}
316
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000317func (i *MetricName) Complete(match string) []flags.Completion {
318 conn, err := NewConnection()
319 if err != nil {
320 return nil
321 }
322 defer conn.Close()
323
324 client := voltha.NewVolthaServiceClient(conn)
325
326 var deviceId string
327found:
328 for i := len(os.Args) - 1; i >= 0; i -= 1 {
329 switch os.Args[i] {
330 case "enable":
331 fallthrough
332 case "disable":
333 if len(os.Args) > i+1 {
334 deviceId = os.Args[i+1]
335 } else {
336 return nil
337 }
338 break found
339 default:
340 }
341 }
342
343 if len(deviceId) == 0 {
344 return nil
345 }
346
347 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
348 defer cancel()
349
350 id := voltha.ID{Id: string(deviceId)}
351
352 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
353
354 if err != nil {
355 return nil
356 }
357
358 list := make([]flags.Completion, 0)
359 for _, metrics := range pmconfigs.Metrics {
360 if strings.HasPrefix(metrics.Name, match) {
361 list = append(list, flags.Completion{Item: metrics.Name})
362 }
363 }
364
365 return list
366}
367
368func (i *GroupName) Complete(match string) []flags.Completion {
369 conn, err := NewConnection()
370 if err != nil {
371 return nil
372 }
373 defer conn.Close()
374
375 client := voltha.NewVolthaServiceClient(conn)
376
377 var deviceId string
378found:
379 for i := len(os.Args) - 1; i >= 0; i -= 1 {
380 switch os.Args[i] {
381 case "list":
382 fallthrough
383 case "enable":
384 fallthrough
385 case "disable":
386 if len(os.Args) > i+1 {
387 deviceId = os.Args[i+1]
388 } else {
389 return nil
390 }
391 break found
392 default:
393 }
394 }
395
396 if len(deviceId) == 0 {
397 return nil
398 }
399
400 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
401 defer cancel()
402
403 id := voltha.ID{Id: string(deviceId)}
404
405 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
406
407 if err != nil {
408 return nil
409 }
410
411 list := make([]flags.Completion, 0)
412 for _, group := range pmconfigs.Groups {
413 if strings.HasPrefix(group.GroupName, match) {
414 list = append(list, flags.Completion{Item: group.GroupName})
415 }
416 }
417 return list
418}
419
kesavand12cd8eb2020-01-20 22:25:22 -0500420func (i *PortNum) Complete(match string) []flags.Completion {
421 conn, err := NewConnection()
422 if err != nil {
423 return nil
424 }
425 defer conn.Close()
426
Scott Baker9173ed82020-05-19 08:30:12 -0700427 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500428
429 /*
430 * The command line args when completing for PortNum will be a DeviceId
431 * followed by one or more PortNums. So walk the argument list from the
432 * end and find the first argument that is enable/disable as those are
433 * the subcommands that come before the positional arguments. It would
434 * be nice if this package gave us the list of optional arguments
435 * already parsed.
436 */
437 var deviceId string
438found:
439 for i := len(os.Args) - 1; i >= 0; i -= 1 {
440 switch os.Args[i] {
441 case "enable":
442 fallthrough
443 case "disable":
444 if len(os.Args) > i+1 {
445 deviceId = os.Args[i+1]
446 } else {
447 return nil
448 }
449 break found
450 default:
451 }
452 }
453
454 if len(deviceId) == 0 {
455 return nil
456 }
457
kesavand12cd8eb2020-01-20 22:25:22 -0500458 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
459 defer cancel()
kesavand12cd8eb2020-01-20 22:25:22 -0500460
Scott Baker9173ed82020-05-19 08:30:12 -0700461 id := voltha.ID{Id: string(deviceId)}
kesavand12cd8eb2020-01-20 22:25:22 -0500462
Scott Baker9173ed82020-05-19 08:30:12 -0700463 ports, err := client.ListDevicePorts(ctx, &id)
kesavand12cd8eb2020-01-20 22:25:22 -0500464 if err != nil {
465 return nil
466 }
467
468 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700469 for _, item := range ports.Items {
470 pn := strconv.FormatUint(uint64(item.PortNo), 10)
kesavand12cd8eb2020-01-20 22:25:22 -0500471 if strings.HasPrefix(pn, match) {
472 list = append(list, flags.Completion{Item: pn})
473 }
474 }
475
476 return list
477}
478
Zack Williamse940c7a2019-08-21 14:25:39 -0700479func (i *DeviceId) Complete(match string) []flags.Completion {
480 conn, err := NewConnection()
481 if err != nil {
482 return nil
483 }
484 defer conn.Close()
485
Scott Baker9173ed82020-05-19 08:30:12 -0700486 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700487
488 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
489 defer cancel()
490
Scott Baker9173ed82020-05-19 08:30:12 -0700491 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700492 if err != nil {
493 return nil
494 }
495
496 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700497 for _, item := range devices.Items {
498 if strings.HasPrefix(item.Id, match) {
499 list = append(list, flags.Completion{Item: item.Id})
Zack Williamse940c7a2019-08-21 14:25:39 -0700500 }
501 }
502
503 return list
504}
505
506func (options *DeviceList) Execute(args []string) error {
507
508 conn, err := NewConnection()
509 if err != nil {
510 return err
511 }
512 defer conn.Close()
513
Scott Baker9173ed82020-05-19 08:30:12 -0700514 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700515
516 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
517 defer cancel()
518
Scott Baker9173ed82020-05-19 08:30:12 -0700519 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700520 if err != nil {
521 return err
522 }
523
524 outputFormat := CharReplacer.Replace(options.Format)
525 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000526 outputFormat = GetCommandOptionWithDefault("device-list", "format", DEFAULT_DEVICE_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700527 }
528 if options.Quiet {
529 outputFormat = "{{.Id}}"
530 }
531
David Bainbridgea6722342019-10-24 23:55:53 +0000532 orderBy := options.OrderBy
533 if orderBy == "" {
534 orderBy = GetCommandOptionWithDefault("device-list", "order", "")
535 }
536
Scott Baker9173ed82020-05-19 08:30:12 -0700537 // Make sure json output prints an empty list, not "null"
538 if devices.Items == nil {
539 devices.Items = make([]*voltha.Device, 0)
Zack Williamse940c7a2019-08-21 14:25:39 -0700540 }
541
542 result := CommandResult{
543 Format: format.Format(outputFormat),
544 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000545 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700546 OutputAs: toOutputType(options.OutputAs),
547 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700548 Data: devices.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700549 }
550
551 GenerateOutput(&result)
552 return nil
553}
554
555func (options *DeviceCreate) Execute(args []string) error {
556
Scott Baker9173ed82020-05-19 08:30:12 -0700557 device := voltha.Device{}
Zack Williamse940c7a2019-08-21 14:25:39 -0700558 if options.HostAndPort != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700559 device.Address = &voltha.Device_HostAndPort{HostAndPort: options.HostAndPort}
Zack Williamse940c7a2019-08-21 14:25:39 -0700560 } else if options.IPAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700561 device.Address = &voltha.Device_Ipv4Address{Ipv4Address: options.IPAddress}
Hardik Windlassce1de342020-02-04 21:58:07 +0000562 }
563 if options.MACAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700564 device.MacAddress = strings.ToLower(options.MACAddress)
Zack Williamse940c7a2019-08-21 14:25:39 -0700565 }
566 if options.DeviceType != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700567 device.Type = options.DeviceType
Zack Williamse940c7a2019-08-21 14:25:39 -0700568 }
569
570 conn, err := NewConnection()
571 if err != nil {
572 return err
573 }
574 defer conn.Close()
575
Scott Baker9173ed82020-05-19 08:30:12 -0700576 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700577
578 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
579 defer cancel()
580
Scott Baker9173ed82020-05-19 08:30:12 -0700581 createdDevice, err := client.CreateDevice(ctx, &device)
Zack Williamse940c7a2019-08-21 14:25:39 -0700582 if err != nil {
583 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700584 }
585
Scott Baker9173ed82020-05-19 08:30:12 -0700586 fmt.Printf("%s\n", createdDevice.Id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700587
588 return nil
589}
590
591func (options *DeviceDelete) Execute(args []string) error {
592
593 conn, err := NewConnection()
594 if err != nil {
595 return err
596 }
597 defer conn.Close()
598
Scott Baker9173ed82020-05-19 08:30:12 -0700599 client := voltha.NewVolthaServiceClient(conn)
David Bainbridge7052fe82020-03-25 10:37:00 -0700600 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700601 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700602 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
603 defer cancel()
604
Scott Baker9173ed82020-05-19 08:30:12 -0700605 id := voltha.ID{Id: string(i)}
Himani Chawla9933ddc2020-10-12 23:53:27 +0530606 if options.Force {
607 _, err = client.ForceDeleteDevice(ctx, &id)
608 } else {
609 _, err = client.DeleteDevice(ctx, &id)
610 }
Scott Baker9173ed82020-05-19 08:30:12 -0700611
Zack Williamse940c7a2019-08-21 14:25:39 -0700612 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000613 Error.Printf("Error while deleting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700614 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700615 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700616 }
617 fmt.Printf("%s\n", i)
618 }
619
David Bainbridge7052fe82020-03-25 10:37:00 -0700620 if lastErr != nil {
621 return NoReportErr
622 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700623 return nil
624}
625
626func (options *DeviceEnable) Execute(args []string) error {
627 conn, err := NewConnection()
628 if err != nil {
629 return err
630 }
631 defer conn.Close()
632
Scott Baker9173ed82020-05-19 08:30:12 -0700633 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700634
David Bainbridge7052fe82020-03-25 10:37:00 -0700635 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700636 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700637 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
638 defer cancel()
639
Scott Baker9173ed82020-05-19 08:30:12 -0700640 id := voltha.ID{Id: string(i)}
641
642 _, err := client.EnableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700643 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000644 Error.Printf("Error while enabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700645 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700646 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700647 }
648 fmt.Printf("%s\n", i)
649 }
650
David Bainbridge7052fe82020-03-25 10:37:00 -0700651 if lastErr != nil {
652 return NoReportErr
653 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700654 return nil
655}
656
657func (options *DeviceDisable) Execute(args []string) error {
658 conn, err := NewConnection()
659 if err != nil {
660 return err
661 }
662 defer conn.Close()
663
Scott Baker9173ed82020-05-19 08:30:12 -0700664 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700665
David Bainbridge7052fe82020-03-25 10:37:00 -0700666 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700667 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700668 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
669 defer cancel()
670
Scott Baker9173ed82020-05-19 08:30:12 -0700671 id := voltha.ID{Id: string(i)}
672
673 _, err := client.DisableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700674 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000675 Error.Printf("Error while disabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700676 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700677 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700678 }
679 fmt.Printf("%s\n", i)
680 }
681
David Bainbridge7052fe82020-03-25 10:37:00 -0700682 if lastErr != nil {
683 return NoReportErr
684 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700685 return nil
686}
687
688func (options *DeviceReboot) Execute(args []string) error {
689 conn, err := NewConnection()
690 if err != nil {
691 return err
692 }
693 defer conn.Close()
694
Scott Baker9173ed82020-05-19 08:30:12 -0700695 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700696
David Bainbridge7052fe82020-03-25 10:37:00 -0700697 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700698 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700699 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
700 defer cancel()
701
Scott Baker9173ed82020-05-19 08:30:12 -0700702 id := voltha.ID{Id: string(i)}
703
704 _, err := client.RebootDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700705 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000706 Error.Printf("Error while rebooting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700707 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700708 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700709 }
710 fmt.Printf("%s\n", i)
711 }
712
David Bainbridge7052fe82020-03-25 10:37:00 -0700713 if lastErr != nil {
714 return NoReportErr
715 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700716 return nil
717}
718
719func (options *DevicePortList) Execute(args []string) error {
720
721 conn, err := NewConnection()
722 if err != nil {
723 return err
724 }
725 defer conn.Close()
726
Scott Baker9173ed82020-05-19 08:30:12 -0700727 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700728
729 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
730 defer cancel()
731
Scott Baker9173ed82020-05-19 08:30:12 -0700732 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700733
Scott Baker9173ed82020-05-19 08:30:12 -0700734 ports, err := client.ListDevicePorts(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700735 if err != nil {
736 return err
737 }
738
739 outputFormat := CharReplacer.Replace(options.Format)
740 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000741 outputFormat = GetCommandOptionWithDefault("device-ports", "format", DEFAULT_DEVICE_PORTS_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700742 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700743
David Bainbridgea6722342019-10-24 23:55:53 +0000744 orderBy := options.OrderBy
745 if orderBy == "" {
746 orderBy = GetCommandOptionWithDefault("device-ports", "order", "")
747 }
748
Zack Williamse940c7a2019-08-21 14:25:39 -0700749 result := CommandResult{
750 Format: format.Format(outputFormat),
751 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000752 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700753 OutputAs: toOutputType(options.OutputAs),
754 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700755 Data: ports.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700756 }
757
758 GenerateOutput(&result)
759 return nil
760}
761
762func (options *DeviceFlowList) Execute(args []string) error {
763 fl := &FlowList{}
764 fl.ListOutputOptions = options.ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530765 fl.FlowIdOptions = options.FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700766 fl.Args.Id = string(options.Args.Id)
David Bainbridgea6722342019-10-24 23:55:53 +0000767 fl.Method = "device-flows"
Zack Williamse940c7a2019-08-21 14:25:39 -0700768 return fl.Execute(args)
769}
770
771func (options *DeviceInspect) Execute(args []string) error {
772 if len(args) > 0 {
773 return fmt.Errorf("only a single argument 'DEVICE_ID' can be provided")
774 }
775
776 conn, err := NewConnection()
777 if err != nil {
778 return err
779 }
780 defer conn.Close()
781
Scott Baker9173ed82020-05-19 08:30:12 -0700782 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700783
784 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
785 defer cancel()
786
Scott Baker9173ed82020-05-19 08:30:12 -0700787 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700788
Scott Baker9173ed82020-05-19 08:30:12 -0700789 device, err := client.GetDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700790 if err != nil {
791 return err
792 }
793
Zack Williamse940c7a2019-08-21 14:25:39 -0700794 outputFormat := CharReplacer.Replace(options.Format)
795 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000796 outputFormat = GetCommandOptionWithDefault("device-inspect", "format", DEFAULT_DEVICE_INSPECT_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700797 }
798 if options.Quiet {
799 outputFormat = "{{.Id}}"
800 }
801
802 result := CommandResult{
803 Format: format.Format(outputFormat),
804 OutputAs: toOutputType(options.OutputAs),
805 NameLimit: options.NameLimit,
806 Data: device,
807 }
808 GenerateOutput(&result)
809 return nil
810}
kesavand12cd8eb2020-01-20 22:25:22 -0500811
812/*Device Port Enable */
813func (options *DevicePortEnable) Execute(args []string) error {
814 conn, err := NewConnection()
815 if err != nil {
816 return err
817 }
818 defer conn.Close()
819
Scott Baker9173ed82020-05-19 08:30:12 -0700820 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500821
kesavand12cd8eb2020-01-20 22:25:22 -0500822 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
823 defer cancel()
824
Scott Baker9173ed82020-05-19 08:30:12 -0700825 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
826
827 _, err = client.EnablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500828 if err != nil {
829 Error.Printf("Error enabling port number %v on device Id %s,err=%s\n", options.Args.PortId, options.Args.Id, ErrorToString(err))
830 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500831 }
832
833 return nil
834}
835
Scott Baker9173ed82020-05-19 08:30:12 -0700836/*Device Port Disable */
kesavand12cd8eb2020-01-20 22:25:22 -0500837func (options *DevicePortDisable) Execute(args []string) error {
838 conn, err := NewConnection()
839 if err != nil {
840 return err
841 }
842 defer conn.Close()
843
Scott Baker9173ed82020-05-19 08:30:12 -0700844 client := voltha.NewVolthaServiceClient(conn)
845
kesavand12cd8eb2020-01-20 22:25:22 -0500846 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
847 defer cancel()
848
Scott Baker9173ed82020-05-19 08:30:12 -0700849 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
850
851 _, err = client.DisablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500852 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700853 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 -0500854 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500855 }
Scott Baker9173ed82020-05-19 08:30:12 -0700856
kesavand12cd8eb2020-01-20 22:25:22 -0500857 return nil
858}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800859
Rohan Agrawald7df3772020-06-29 11:23:36 +0000860func (options *DevicePmConfigSetMaxSkew) Execute(args []string) error {
861 conn, err := NewConnection()
862 if err != nil {
863 return err
864 }
865 defer conn.Close()
866
867 client := voltha.NewVolthaServiceClient(conn)
868
869 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
870 defer cancel()
871
872 id := voltha.ID{Id: string(options.Args.Id)}
873
874 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
875 if err != nil {
876 return err
877 }
878
879 pmConfigs.MaxSkew = options.Args.MaxSkew
880
881 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
882 if err != nil {
883 return err
884 }
885
886 return nil
887}
888
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000889func (options *DevicePmConfigsGet) Execute(args []string) error {
890
891 conn, err := NewConnection()
892 if err != nil {
893 return err
894 }
895 defer conn.Close()
896
897 client := voltha.NewVolthaServiceClient(conn)
898
899 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
900 defer cancel()
901
902 id := voltha.ID{Id: string(options.Args.Id)}
903
904 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
905 if err != nil {
906 return err
907 }
908
909 outputFormat := CharReplacer.Replace(options.Format)
910 if outputFormat == "" {
911 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
912 }
913
914 orderBy := options.OrderBy
915 if orderBy == "" {
916 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
917 }
918
919 result := CommandResult{
920 Format: format.Format(outputFormat),
921 Filter: options.Filter,
922 OrderBy: orderBy,
923 OutputAs: toOutputType(options.OutputAs),
924 NameLimit: options.NameLimit,
925 Data: pmConfigs,
926 }
927
928 GenerateOutput(&result)
929 return nil
930
931}
932
933func (options *DevicePmConfigMetricList) Execute(args []string) error {
934
935 conn, err := NewConnection()
936 if err != nil {
937 return err
938 }
939 defer conn.Close()
940
941 client := voltha.NewVolthaServiceClient(conn)
942
943 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
944 defer cancel()
945
946 id := voltha.ID{Id: string(options.Args.Id)}
947
948 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
949 if err != nil {
950 return err
951 }
952
953 if !pmConfigs.Grouped {
954 for _, metric := range pmConfigs.Metrics {
955 if metric.SampleFreq == 0 {
956 metric.SampleFreq = pmConfigs.DefaultFreq
957 }
958 }
Rohan Agrawalbca69122020-06-17 14:59:03 +0000959 outputFormat := CharReplacer.Replace(options.Format)
960 if outputFormat == "" {
961 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
962 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000963
Rohan Agrawalbca69122020-06-17 14:59:03 +0000964 orderBy := options.OrderBy
965 if orderBy == "" {
966 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
967 }
968
969 result := CommandResult{
970 Format: format.Format(outputFormat),
971 Filter: options.Filter,
972 OrderBy: orderBy,
973 OutputAs: toOutputType(options.OutputAs),
974 NameLimit: options.NameLimit,
975 Data: pmConfigs.Metrics,
976 }
977
978 GenerateOutput(&result)
979 return nil
980 } else {
981 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000982 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000983}
984
985func (options *DevicePmConfigMetricEnable) Execute(args []string) error {
986
987 conn, err := NewConnection()
988 if err != nil {
989 return err
990 }
991 defer conn.Close()
992
993 client := voltha.NewVolthaServiceClient(conn)
994
995 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
996 defer cancel()
997
998 id := voltha.ID{Id: string(options.Args.Id)}
999
1000 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1001 if err != nil {
1002 return err
1003 }
1004
1005 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001006 metrics := make(map[string]struct{})
1007 for _, metric := range pmConfigs.Metrics {
1008 metrics[metric.Name] = struct{}{}
1009 }
1010
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001011 for _, metric := range pmConfigs.Metrics {
1012 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001013 if _, exist := metrics[string(mName)]; !exist {
1014 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1015 }
1016
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001017 if string(mName) == metric.Name && !metric.Enabled {
1018 metric.Enabled = true
1019 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1020 if err != nil {
1021 return err
1022 }
1023 }
1024 }
1025 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001026 } else {
1027 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001028 }
1029 return nil
1030}
1031
1032func (options *DevicePmConfigMetricDisable) Execute(args []string) error {
1033
1034 conn, err := NewConnection()
1035 if err != nil {
1036 return err
1037 }
1038 defer conn.Close()
1039
1040 client := voltha.NewVolthaServiceClient(conn)
1041
1042 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1043 defer cancel()
1044
1045 id := voltha.ID{Id: string(options.Args.Id)}
1046
1047 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1048 if err != nil {
1049 return err
1050 }
1051
1052 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001053 metrics := make(map[string]struct{})
1054 for _, metric := range pmConfigs.Metrics {
1055 metrics[metric.Name] = struct{}{}
1056 }
1057
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001058 for _, metric := range pmConfigs.Metrics {
1059 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001060 if _, have := metrics[string(mName)]; !have {
1061 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1062 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001063 if string(mName) == metric.Name && metric.Enabled {
1064 metric.Enabled = false
1065 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1066 if err != nil {
1067 return err
1068 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001069 } else {
1070 return fmt.Errorf("Metric '%s' cannot be disabled", string(mName))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001071 }
1072 }
1073 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001074 } else {
1075 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001076 }
1077 return nil
1078}
1079
1080func (options *DevicePmConfigGroupEnable) Execute(args []string) error {
1081
1082 conn, err := NewConnection()
1083 if err != nil {
1084 return err
1085 }
1086 defer conn.Close()
1087
1088 client := voltha.NewVolthaServiceClient(conn)
1089
1090 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1091 defer cancel()
1092
1093 id := voltha.ID{Id: string(options.Args.Id)}
1094
1095 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1096 if err != nil {
1097 return err
1098 }
1099
1100 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001101 groups := make(map[string]struct{})
1102 for _, group := range pmConfigs.Groups {
1103 groups[group.GroupName] = struct{}{}
1104 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001105 for _, group := range pmConfigs.Groups {
1106 for _, gName := range options.Args.Groups {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001107 if _, have := groups[string(gName)]; !have {
1108 return fmt.Errorf("Group Name '%s' does not exist", gName)
1109 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001110 if string(gName) == group.GroupName && !group.Enabled {
1111 group.Enabled = true
1112 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1113 if err != nil {
1114 return err
1115 }
1116 }
1117 }
1118 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001119 } else {
1120 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001121 }
1122 return nil
1123}
1124
1125func (options *DevicePmConfigGroupDisable) Execute(args []string) error {
1126
1127 conn, err := NewConnection()
1128 if err != nil {
1129 return err
1130 }
1131 defer conn.Close()
1132
1133 client := voltha.NewVolthaServiceClient(conn)
1134
1135 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1136 defer cancel()
1137
1138 id := voltha.ID{Id: string(options.Args.Id)}
1139
1140 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1141 if err != nil {
1142 return err
1143 }
1144
1145 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001146 groups := make(map[string]struct{})
1147 for _, group := range pmConfigs.Groups {
1148 groups[group.GroupName] = struct{}{}
1149 }
1150
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001151 for _, group := range pmConfigs.Groups {
1152 for _, gName := range options.Args.Groups {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001153 if _, have := groups[string(gName)]; !have {
1154 return fmt.Errorf("Group Name '%s' does not exist", gName)
1155 }
1156
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001157 if string(gName) == group.GroupName && group.Enabled {
1158 group.Enabled = false
1159 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1160 if err != nil {
1161 return err
1162 }
1163 }
1164 }
1165 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001166 } else {
1167 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001168 }
1169 return nil
1170}
1171
1172func (options *DevicePmConfigGroupList) Execute(args []string) error {
1173
1174 conn, err := NewConnection()
1175 if err != nil {
1176 return err
1177 }
1178 defer conn.Close()
1179
1180 client := voltha.NewVolthaServiceClient(conn)
1181
1182 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1183 defer cancel()
1184
1185 id := voltha.ID{Id: string(options.Args.Id)}
1186
1187 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1188 if err != nil {
1189 return err
1190 }
1191
1192 if pmConfigs.Grouped {
1193 for _, group := range pmConfigs.Groups {
1194 if group.GroupFreq == 0 {
1195 group.GroupFreq = pmConfigs.DefaultFreq
1196 }
1197 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001198 outputFormat := CharReplacer.Replace(options.Format)
1199 if outputFormat == "" {
1200 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT)
1201 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001202
Rohan Agrawalbca69122020-06-17 14:59:03 +00001203 orderBy := options.OrderBy
1204 if orderBy == "" {
1205 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1206 }
1207
1208 result := CommandResult{
1209 Format: format.Format(outputFormat),
1210 Filter: options.Filter,
1211 OrderBy: orderBy,
1212 OutputAs: toOutputType(options.OutputAs),
1213 NameLimit: options.NameLimit,
1214 Data: pmConfigs.Groups,
1215 }
1216
1217 GenerateOutput(&result)
1218 } else {
1219 return fmt.Errorf("Device '%s' does not have Group Metrics", string(options.Args.Id))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001220 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001221 return nil
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001222}
1223
1224func (options *DevicePmConfigGroupMetricList) Execute(args []string) error {
1225
1226 var metrics []*voltha.PmConfig
1227 conn, err := NewConnection()
1228 if err != nil {
1229 return err
1230 }
1231 defer conn.Close()
1232
1233 client := voltha.NewVolthaServiceClient(conn)
1234
1235 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1236 defer cancel()
1237
1238 id := voltha.ID{Id: string(options.Args.Id)}
1239
1240 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1241 if err != nil {
1242 return err
1243 }
1244
1245 for _, groups := range pmConfigs.Groups {
1246
1247 if string(options.Args.Group) == groups.GroupName {
1248 for _, metric := range groups.Metrics {
1249 if metric.SampleFreq == 0 && groups.GroupFreq == 0 {
1250 metric.SampleFreq = pmConfigs.DefaultFreq
1251 } else {
1252 metric.SampleFreq = groups.GroupFreq
1253 }
1254 }
1255 metrics = groups.Metrics
1256 }
1257 }
1258
1259 outputFormat := CharReplacer.Replace(options.Format)
1260 if outputFormat == "" {
1261 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
1262 }
1263
1264 orderBy := options.OrderBy
1265 if orderBy == "" {
1266 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1267 }
1268
1269 result := CommandResult{
1270 Format: format.Format(outputFormat),
1271 Filter: options.Filter,
1272 OrderBy: orderBy,
1273 OutputAs: toOutputType(options.OutputAs),
1274 NameLimit: options.NameLimit,
1275 Data: metrics,
1276 }
1277
1278 GenerateOutput(&result)
1279 return nil
1280
1281}
1282
1283func (options *DevicePmConfigFrequencySet) Execute(args []string) error {
1284
1285 conn, err := NewConnection()
1286 if err != nil {
1287 return err
1288 }
1289 defer conn.Close()
1290
1291 client := voltha.NewVolthaServiceClient(conn)
1292
1293 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1294 defer cancel()
1295
1296 id := voltha.ID{Id: string(options.Args.Id)}
1297
1298 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1299 if err != nil {
1300 return err
1301 }
1302
1303 pmConfigs.DefaultFreq = options.Args.Frequency
1304
1305 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1306 if err != nil {
1307 return err
1308 }
1309
1310 outputFormat := CharReplacer.Replace(options.Format)
1311 if outputFormat == "" {
1312 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
1313 }
1314 if options.Quiet {
1315 outputFormat = "{{.Id}}"
1316 }
1317
1318 result := CommandResult{
1319 Format: format.Format(outputFormat),
1320 OutputAs: toOutputType(options.OutputAs),
1321 NameLimit: options.NameLimit,
1322 Data: pmConfigs,
1323 }
1324
1325 GenerateOutput(&result)
1326 return nil
1327
1328}
1329
Andrea Campanella791d88b2021-01-08 13:29:00 +01001330func (options *DeviceOnuListImages) Execute(args []string) error {
1331
1332 conn, err := NewConnection()
1333 if err != nil {
1334 return err
1335 }
1336 defer conn.Close()
1337
1338 client := voltha.NewVolthaServiceClient(conn)
1339
1340 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1341 defer cancel()
1342
1343 id := common.ID{Id: string(options.Args.Id)}
1344
1345 imageDownloads, err := client.ListImageDownloads(ctx, &id)
1346 if err != nil {
1347 return err
1348 }
1349
1350 outputFormat := CharReplacer.Replace(options.Format)
1351 if outputFormat == "" {
1352 outputFormat = GetCommandOptionWithDefault("device-image-list", "format", DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT)
1353 }
1354
1355 if options.Quiet {
1356 outputFormat = "{{.Id}}"
1357 }
1358
1359 //TODO orderby
1360
1361 // Make sure json output prints an empty list, not "null"
1362 if imageDownloads.Items == nil {
1363 imageDownloads.Items = make([]*voltha.ImageDownload, 0)
1364 }
1365
1366 result := CommandResult{
1367 Format: format.Format(outputFormat),
1368 OutputAs: toOutputType(options.OutputAs),
1369 NameLimit: options.NameLimit,
1370 Data: imageDownloads.Items,
1371 }
1372
1373 GenerateOutput(&result)
1374 return nil
1375
1376}
1377
1378func (options *DeviceOnuDownloadImage) Execute(args []string) error {
1379
1380 conn, err := NewConnection()
1381 if err != nil {
1382 return err
1383 }
1384 defer conn.Close()
1385
1386 client := voltha.NewVolthaServiceClient(conn)
1387
1388 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1389 defer cancel()
1390
1391 downloadImage := voltha.ImageDownload{
1392 Id: string(options.Args.Id),
1393 Name: options.Args.Name,
1394 Url: options.Args.Url,
1395 Crc: options.Args.Crc,
1396 LocalDir: options.Args.LocalDir,
1397 }
1398
1399 _, err = client.DownloadImage(ctx, &downloadImage)
1400 if err != nil {
1401 return err
1402 }
1403
1404 return nil
1405
1406}
1407
1408func (options *DeviceOnuActivateImageUpdate) Execute(args []string) error {
1409
1410 conn, err := NewConnection()
1411 if err != nil {
1412 return err
1413 }
1414 defer conn.Close()
1415
1416 client := voltha.NewVolthaServiceClient(conn)
1417
1418 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1419 defer cancel()
1420
1421 downloadImage := voltha.ImageDownload{
1422 Id: string(options.Args.Id),
1423 Name: options.Args.Name,
1424 ImageVersion: options.Args.ImageVersion,
1425 SaveConfig: options.Args.SaveConfig,
1426 LocalDir: options.Args.LocalDir,
1427 }
1428
1429 _, err = client.ActivateImageUpdate(ctx, &downloadImage)
1430 if err != nil {
1431 return err
1432 }
1433
1434 return nil
1435
1436}
1437
Scott Baker9173ed82020-05-19 08:30:12 -07001438type ReturnValueRow struct {
1439 Name string `json:"name"`
1440 Result interface{} `json:"result"`
1441}
1442
kesavand8ec4fc02021-01-27 09:10:22 -05001443func (options *DeviceGetPortStats) Execute(args []string) error {
1444 conn, err := NewConnection()
1445 if err != nil {
1446 return err
1447 }
1448 defer conn.Close()
1449 client := extension.NewExtensionClient(conn)
1450 var portType extension.GetOltPortCounters_PortType
1451
1452 if options.Args.PortType == "pon" {
1453 portType = extension.GetOltPortCounters_Port_PON_OLT
1454 } else if options.Args.PortType == "nni" {
1455
1456 portType = extension.GetOltPortCounters_Port_ETHERNET_NNI
1457 } else {
1458 return fmt.Errorf("expected interface type pon/nni, provided %s", options.Args.PortType)
1459 }
1460
1461 singleGetValReq := extension.SingleGetValueRequest{
1462 TargetId: string(options.Args.Id),
1463 Request: &extension.GetValueRequest{
1464 Request: &extension.GetValueRequest_OltPortInfo{
1465 OltPortInfo: &extension.GetOltPortCounters{
1466 PortNo: options.Args.PortNo,
1467 PortType: portType,
1468 },
1469 },
1470 },
1471 }
1472
1473 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1474 defer cancel()
1475 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1476 if err != nil {
1477 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1478 return err
1479 }
1480
1481 if rv.Response.Status != extension.GetValueResponse_OK {
1482 return fmt.Errorf("failed to get port stats %v", rv.Response.ErrReason.String())
1483 }
1484
1485 outputFormat := CharReplacer.Replace(options.Format)
1486 if outputFormat == "" {
1487 outputFormat = GetCommandOptionWithDefault("device-get-port-status", "format", DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT)
1488 }
1489
1490 result := CommandResult{
1491 Format: format.Format(outputFormat),
1492 OutputAs: toOutputType(options.OutputAs),
1493 NameLimit: options.NameLimit,
1494 Data: rv.GetResponse().GetPortCoutners(),
1495 }
1496 GenerateOutput(&result)
1497 return nil
1498}
1499
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001500/*Device get Onu Distance */
1501func (options *DeviceGetExtValue) Execute(args []string) error {
1502 conn, err := NewConnection()
1503 if err != nil {
1504 return err
1505 }
1506 defer conn.Close()
1507
Scott Baker9173ed82020-05-19 08:30:12 -07001508 client := voltha.NewVolthaServiceClient(conn)
1509
1510 valueflag, okay := common.ValueType_Type_value[string(options.Args.Valueflag)]
1511 if !okay {
1512 Error.Printf("Unknown valueflag %s\n", options.Args.Valueflag)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001513 }
1514
Scott Baker9173ed82020-05-19 08:30:12 -07001515 val := voltha.ValueSpecifier{Id: string(options.Args.Id), Value: common.ValueType_Type(valueflag)}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001516
1517 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1518 defer cancel()
1519
Scott Baker9173ed82020-05-19 08:30:12 -07001520 rv, err := client.GetExtValue(ctx, &val)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001521 if err != nil {
1522 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1523 return err
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001524 }
1525
Scott Baker9173ed82020-05-19 08:30:12 -07001526 var rows []ReturnValueRow
1527 for name, num := range common.ValueType_Type_value {
1528 if num == 0 {
1529 // EMPTY is not a real value
1530 continue
1531 }
1532 if (rv.Error & uint32(num)) != 0 {
1533 row := ReturnValueRow{Name: name, Result: "Error"}
1534 rows = append(rows, row)
1535 }
1536 if (rv.Unsupported & uint32(num)) != 0 {
1537 row := ReturnValueRow{Name: name, Result: "Unsupported"}
1538 rows = append(rows, row)
1539 }
1540 if (rv.Set & uint32(num)) != 0 {
1541 switch name {
1542 case "DISTANCE":
1543 row := ReturnValueRow{Name: name, Result: rv.Distance}
1544 rows = append(rows, row)
1545 default:
1546 row := ReturnValueRow{Name: name, Result: "Unimplemented-in-voltctl"}
1547 rows = append(rows, row)
1548 }
1549 }
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001550 }
1551
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001552 outputFormat := CharReplacer.Replace(options.Format)
1553 if outputFormat == "" {
1554 outputFormat = GetCommandOptionWithDefault("device-value-get", "format", DEFAULT_DEVICE_VALUE_GET_FORMAT)
1555 }
1556
1557 result := CommandResult{
1558 Format: format.Format(outputFormat),
1559 OutputAs: toOutputType(options.OutputAs),
1560 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -07001561 Data: rows,
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001562 }
1563 GenerateOutput(&result)
1564 return nil
1565}