blob: b0807339d8fbfc4149f3456a265648dccf6d7a3b [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}}`
kesavand6d1131f2021-02-05 22:38:15 +053063 DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT = `
64 ADMIN_STATE: {{.AdmState}}
65 OPERATIONAL_STATE: {{.OperState}}
66 CONFIG_IND: {{.ConfigInd}}`
Zack Williamse940c7a2019-08-21 14:25:39 -070067)
68
69type DeviceList struct {
70 ListOutputOptions
71}
72
73type DeviceCreate struct {
David Bainbridge1a514392020-06-23 11:12:51 -070074 DeviceType string `short:"t" required:"true" long:"devicetype" description:"Device type"`
David Bainbridge835dd0e2020-04-01 10:30:09 -070075 MACAddress string `short:"m" long:"macaddress" default:"" description:"MAC Address"`
Zack Williamse940c7a2019-08-21 14:25:39 -070076 IPAddress string `short:"i" long:"ipaddress" default:"" description:"IP Address"`
77 HostAndPort string `short:"H" long:"hostandport" default:"" description:"Host and port"`
78}
79
80type DeviceId string
81
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000082type MetricName string
83type GroupName string
kesavand12cd8eb2020-01-20 22:25:22 -050084type PortNum uint32
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -080085type ValueFlag string
kesavand12cd8eb2020-01-20 22:25:22 -050086
Zack Williamse940c7a2019-08-21 14:25:39 -070087type DeviceDelete struct {
Himani Chawla9933ddc2020-10-12 23:53:27 +053088 Force bool `long:"force" description:"Delete device forcefully"`
89 Args struct {
Zack Williamse940c7a2019-08-21 14:25:39 -070090 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
91 } `positional-args:"yes"`
92}
93
94type DeviceEnable struct {
95 Args struct {
96 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
97 } `positional-args:"yes"`
98}
99
100type DeviceDisable struct {
101 Args struct {
102 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
103 } `positional-args:"yes"`
104}
105
106type DeviceReboot struct {
107 Args struct {
108 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
109 } `positional-args:"yes"`
110}
111
112type DeviceFlowList struct {
113 ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530114 FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700115 Args struct {
116 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
117 } `positional-args:"yes"`
118}
119
120type DevicePortList struct {
121 ListOutputOptions
122 Args struct {
123 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
124 } `positional-args:"yes"`
125}
126
127type DeviceInspect struct {
128 OutputOptionsJson
129 Args struct {
130 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
131 } `positional-args:"yes"`
132}
133
kesavand12cd8eb2020-01-20 22:25:22 -0500134type DevicePortEnable struct {
135 Args struct {
136 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
137 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
138 } `positional-args:"yes"`
139}
140
141type DevicePortDisable struct {
142 Args struct {
143 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
144 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
145 } `positional-args:"yes"`
146}
147
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000148type DevicePmConfigsGet struct {
149 ListOutputOptions
150 Args struct {
151 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
152 } `positional-args:"yes"`
153}
154
155type DevicePmConfigMetricList struct {
156 ListOutputOptions
157 Args struct {
158 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
159 } `positional-args:"yes"`
160}
161
162type DevicePmConfigGroupList struct {
163 ListOutputOptions
164 Args struct {
165 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
166 } `positional-args:"yes"`
167}
168
169type DevicePmConfigGroupMetricList struct {
170 ListOutputOptions
171 Args struct {
172 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
173 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
174 } `positional-args:"yes"`
175}
176
177type DevicePmConfigFrequencySet struct {
178 OutputOptions
179 Args struct {
180 Frequency uint32 `positional-arg-name:"FREQUENCY" required:"yes"`
181 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
182 } `positional-args:"yes"`
183}
184
185type DevicePmConfigMetricEnable struct {
186 Args struct {
187 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
188 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
189 } `positional-args:"yes"`
190}
191
192type DevicePmConfigMetricDisable struct {
193 Args struct {
194 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
195 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
196 } `positional-args:"yes"`
197}
198
199type DevicePmConfigGroupEnable struct {
200 Args struct {
201 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
202 Groups []GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
203 } `positional-args:"yes"`
204}
205
206type DevicePmConfigGroupDisable struct {
207 Args struct {
208 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
209 Groups []GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
210 } `positional-args:"yes"`
211}
212
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800213type DeviceGetExtValue struct {
214 ListOutputOptions
215 Args struct {
216 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
217 Valueflag ValueFlag `positional-arg-name:"VALUE_FLAG" required:"yes"`
218 } `positional-args:"yes"`
219}
Rohan Agrawald7df3772020-06-29 11:23:36 +0000220
221type DevicePmConfigSetMaxSkew struct {
222 Args struct {
223 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
224 MaxSkew uint32 `positional-arg-name:"MAX_SKEW" required:"yes"`
225 } `positional-args:"yes"`
226}
227
Andrea Campanella791d88b2021-01-08 13:29:00 +0100228type DeviceOnuListImages struct {
229 ListOutputOptions
230 Args struct {
231 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
232 } `positional-args:"yes"`
233}
234
235type DeviceOnuDownloadImage struct {
236 Args struct {
237 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
238 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
239 Url string `positional-arg-name:"IMAGE_URL" required:"yes"`
240 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
241 Crc uint32 `positional-arg-name:"IMAGE_CRC" required:"yes"`
242 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
243 } `positional-args:"yes"`
244}
245
246type DeviceOnuActivateImageUpdate struct {
247 Args struct {
248 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
249 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
250 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
251 SaveConfig bool `positional-arg-name:"SAVE_EXISTING_CONFIG"`
252 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
kesavand8ec4fc02021-01-27 09:10:22 -0500253 }
254}
255type DeviceGetPortStats struct {
256 ListOutputOptions
257 Args struct {
258 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
259 PortNo uint32 `positional-arg-name:"PORT_NO" required:"yes"`
260 PortType string `positional-arg-name:"PORT_TYPE" required:"yes"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100261 } `positional-args:"yes"`
262}
kesavand6d1131f2021-02-05 22:38:15 +0530263type UniStatus struct {
264 ListOutputOptions
265 Args struct {
266 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
267 UniIndex uint32 `positional-arg-name:"UNI_INDEX" required:"yes"`
268 } `positional-args:"yes"`
269}
Zack Williamse940c7a2019-08-21 14:25:39 -0700270type DeviceOpts struct {
271 List DeviceList `command:"list"`
272 Create DeviceCreate `command:"create"`
273 Delete DeviceDelete `command:"delete"`
274 Enable DeviceEnable `command:"enable"`
275 Disable DeviceDisable `command:"disable"`
276 Flows DeviceFlowList `command:"flows"`
kesavand12cd8eb2020-01-20 22:25:22 -0500277 Port struct {
278 List DevicePortList `command:"list"`
279 Enable DevicePortEnable `command:"enable"`
280 Disable DevicePortDisable `command:"disable"`
281 } `command:"port"`
282 Inspect DeviceInspect `command:"inspect"`
283 Reboot DeviceReboot `command:"reboot"`
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800284 Value struct {
285 Get DeviceGetExtValue `command:"get"`
286 } `command:"value"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000287 PmConfig struct {
Rohan Agrawald7df3772020-06-29 11:23:36 +0000288 Get DevicePmConfigsGet `command:"get"`
289 MaxSkew struct {
290 Set DevicePmConfigSetMaxSkew `command:"set"`
291 } `command:"maxskew"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000292 Frequency struct {
293 Set DevicePmConfigFrequencySet `command:"set"`
294 } `command:"frequency"`
295 Metric struct {
296 List DevicePmConfigMetricList `command:"list"`
297 Enable DevicePmConfigMetricEnable `command:"enable"`
298 Disable DevicePmConfigMetricDisable `command:"disable"`
299 } `command:"metric"`
300 Group struct {
301 List DevicePmConfigGroupList `command:"list"`
302 Enable DevicePmConfigGroupEnable `command:"enable"`
303 Disable DevicePmConfigGroupDisable `command:"disable"`
304 } `command:"group"`
305 GroupMetric struct {
306 List DevicePmConfigGroupMetricList `command:"list"`
307 } `command:"groupmetric"`
308 } `command:"pmconfig"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100309 Image struct {
310 Get DeviceOnuListImages `command:"list"`
311 Download DeviceOnuDownloadImage `command:"download"`
312 Activate DeviceOnuActivateImageUpdate `command:"activate"`
313 } `command:"image"`
kesavand8ec4fc02021-01-27 09:10:22 -0500314 GetExtVal struct {
kesavand6d1131f2021-02-05 22:38:15 +0530315 Stats DeviceGetPortStats `command:"portstats"`
316 UniStatus UniStatus `command:"unistatus"`
kesavand8ec4fc02021-01-27 09:10:22 -0500317 } `command:"getextval"`
Zack Williamse940c7a2019-08-21 14:25:39 -0700318}
319
320var deviceOpts = DeviceOpts{}
321
322func RegisterDeviceCommands(parser *flags.Parser) {
David Bainbridge12f036f2019-10-15 22:09:04 +0000323 if _, err := parser.AddCommand("device", "device commands", "Commands to query and manipulate VOLTHA devices", &deviceOpts); err != nil {
David Bainbridgea6722342019-10-24 23:55:53 +0000324 Error.Fatalf("Unexpected error while attempting to register device commands : %s", err)
David Bainbridge12f036f2019-10-15 22:09:04 +0000325 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700326}
327
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000328func (i *MetricName) Complete(match string) []flags.Completion {
329 conn, err := NewConnection()
330 if err != nil {
331 return nil
332 }
333 defer conn.Close()
334
335 client := voltha.NewVolthaServiceClient(conn)
336
337 var deviceId string
338found:
339 for i := len(os.Args) - 1; i >= 0; i -= 1 {
340 switch os.Args[i] {
341 case "enable":
342 fallthrough
343 case "disable":
344 if len(os.Args) > i+1 {
345 deviceId = os.Args[i+1]
346 } else {
347 return nil
348 }
349 break found
350 default:
351 }
352 }
353
354 if len(deviceId) == 0 {
355 return nil
356 }
357
358 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
359 defer cancel()
360
361 id := voltha.ID{Id: string(deviceId)}
362
363 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
364
365 if err != nil {
366 return nil
367 }
368
369 list := make([]flags.Completion, 0)
370 for _, metrics := range pmconfigs.Metrics {
371 if strings.HasPrefix(metrics.Name, match) {
372 list = append(list, flags.Completion{Item: metrics.Name})
373 }
374 }
375
376 return list
377}
378
379func (i *GroupName) Complete(match string) []flags.Completion {
380 conn, err := NewConnection()
381 if err != nil {
382 return nil
383 }
384 defer conn.Close()
385
386 client := voltha.NewVolthaServiceClient(conn)
387
388 var deviceId string
389found:
390 for i := len(os.Args) - 1; i >= 0; i -= 1 {
391 switch os.Args[i] {
392 case "list":
393 fallthrough
394 case "enable":
395 fallthrough
396 case "disable":
397 if len(os.Args) > i+1 {
398 deviceId = os.Args[i+1]
399 } else {
400 return nil
401 }
402 break found
403 default:
404 }
405 }
406
407 if len(deviceId) == 0 {
408 return nil
409 }
410
411 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
412 defer cancel()
413
414 id := voltha.ID{Id: string(deviceId)}
415
416 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
417
418 if err != nil {
419 return nil
420 }
421
422 list := make([]flags.Completion, 0)
423 for _, group := range pmconfigs.Groups {
424 if strings.HasPrefix(group.GroupName, match) {
425 list = append(list, flags.Completion{Item: group.GroupName})
426 }
427 }
428 return list
429}
430
kesavand12cd8eb2020-01-20 22:25:22 -0500431func (i *PortNum) Complete(match string) []flags.Completion {
432 conn, err := NewConnection()
433 if err != nil {
434 return nil
435 }
436 defer conn.Close()
437
Scott Baker9173ed82020-05-19 08:30:12 -0700438 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500439
440 /*
441 * The command line args when completing for PortNum will be a DeviceId
442 * followed by one or more PortNums. So walk the argument list from the
443 * end and find the first argument that is enable/disable as those are
444 * the subcommands that come before the positional arguments. It would
445 * be nice if this package gave us the list of optional arguments
446 * already parsed.
447 */
448 var deviceId string
449found:
450 for i := len(os.Args) - 1; i >= 0; i -= 1 {
451 switch os.Args[i] {
452 case "enable":
453 fallthrough
454 case "disable":
455 if len(os.Args) > i+1 {
456 deviceId = os.Args[i+1]
457 } else {
458 return nil
459 }
460 break found
461 default:
462 }
463 }
464
465 if len(deviceId) == 0 {
466 return nil
467 }
468
kesavand12cd8eb2020-01-20 22:25:22 -0500469 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
470 defer cancel()
kesavand12cd8eb2020-01-20 22:25:22 -0500471
Scott Baker9173ed82020-05-19 08:30:12 -0700472 id := voltha.ID{Id: string(deviceId)}
kesavand12cd8eb2020-01-20 22:25:22 -0500473
Scott Baker9173ed82020-05-19 08:30:12 -0700474 ports, err := client.ListDevicePorts(ctx, &id)
kesavand12cd8eb2020-01-20 22:25:22 -0500475 if err != nil {
476 return nil
477 }
478
479 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700480 for _, item := range ports.Items {
481 pn := strconv.FormatUint(uint64(item.PortNo), 10)
kesavand12cd8eb2020-01-20 22:25:22 -0500482 if strings.HasPrefix(pn, match) {
483 list = append(list, flags.Completion{Item: pn})
484 }
485 }
486
487 return list
488}
489
Zack Williamse940c7a2019-08-21 14:25:39 -0700490func (i *DeviceId) Complete(match string) []flags.Completion {
491 conn, err := NewConnection()
492 if err != nil {
493 return nil
494 }
495 defer conn.Close()
496
Scott Baker9173ed82020-05-19 08:30:12 -0700497 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700498
499 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
500 defer cancel()
501
Scott Baker9173ed82020-05-19 08:30:12 -0700502 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700503 if err != nil {
504 return nil
505 }
506
507 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700508 for _, item := range devices.Items {
509 if strings.HasPrefix(item.Id, match) {
510 list = append(list, flags.Completion{Item: item.Id})
Zack Williamse940c7a2019-08-21 14:25:39 -0700511 }
512 }
513
514 return list
515}
516
517func (options *DeviceList) Execute(args []string) error {
518
519 conn, err := NewConnection()
520 if err != nil {
521 return err
522 }
523 defer conn.Close()
524
Scott Baker9173ed82020-05-19 08:30:12 -0700525 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700526
527 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
528 defer cancel()
529
Scott Baker9173ed82020-05-19 08:30:12 -0700530 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700531 if err != nil {
532 return err
533 }
534
535 outputFormat := CharReplacer.Replace(options.Format)
536 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000537 outputFormat = GetCommandOptionWithDefault("device-list", "format", DEFAULT_DEVICE_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700538 }
539 if options.Quiet {
540 outputFormat = "{{.Id}}"
541 }
542
David Bainbridgea6722342019-10-24 23:55:53 +0000543 orderBy := options.OrderBy
544 if orderBy == "" {
545 orderBy = GetCommandOptionWithDefault("device-list", "order", "")
546 }
547
Scott Baker9173ed82020-05-19 08:30:12 -0700548 // Make sure json output prints an empty list, not "null"
549 if devices.Items == nil {
550 devices.Items = make([]*voltha.Device, 0)
Zack Williamse940c7a2019-08-21 14:25:39 -0700551 }
552
553 result := CommandResult{
554 Format: format.Format(outputFormat),
555 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000556 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700557 OutputAs: toOutputType(options.OutputAs),
558 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700559 Data: devices.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700560 }
561
562 GenerateOutput(&result)
563 return nil
564}
565
566func (options *DeviceCreate) Execute(args []string) error {
567
Scott Baker9173ed82020-05-19 08:30:12 -0700568 device := voltha.Device{}
Zack Williamse940c7a2019-08-21 14:25:39 -0700569 if options.HostAndPort != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700570 device.Address = &voltha.Device_HostAndPort{HostAndPort: options.HostAndPort}
Zack Williamse940c7a2019-08-21 14:25:39 -0700571 } else if options.IPAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700572 device.Address = &voltha.Device_Ipv4Address{Ipv4Address: options.IPAddress}
Hardik Windlassce1de342020-02-04 21:58:07 +0000573 }
574 if options.MACAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700575 device.MacAddress = strings.ToLower(options.MACAddress)
Zack Williamse940c7a2019-08-21 14:25:39 -0700576 }
577 if options.DeviceType != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700578 device.Type = options.DeviceType
Zack Williamse940c7a2019-08-21 14:25:39 -0700579 }
580
581 conn, err := NewConnection()
582 if err != nil {
583 return err
584 }
585 defer conn.Close()
586
Scott Baker9173ed82020-05-19 08:30:12 -0700587 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700588
589 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
590 defer cancel()
591
Scott Baker9173ed82020-05-19 08:30:12 -0700592 createdDevice, err := client.CreateDevice(ctx, &device)
Zack Williamse940c7a2019-08-21 14:25:39 -0700593 if err != nil {
594 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700595 }
596
Scott Baker9173ed82020-05-19 08:30:12 -0700597 fmt.Printf("%s\n", createdDevice.Id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700598
599 return nil
600}
601
602func (options *DeviceDelete) Execute(args []string) error {
603
604 conn, err := NewConnection()
605 if err != nil {
606 return err
607 }
608 defer conn.Close()
609
Scott Baker9173ed82020-05-19 08:30:12 -0700610 client := voltha.NewVolthaServiceClient(conn)
David Bainbridge7052fe82020-03-25 10:37:00 -0700611 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700612 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700613 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
614 defer cancel()
615
Scott Baker9173ed82020-05-19 08:30:12 -0700616 id := voltha.ID{Id: string(i)}
Himani Chawla9933ddc2020-10-12 23:53:27 +0530617 if options.Force {
618 _, err = client.ForceDeleteDevice(ctx, &id)
619 } else {
620 _, err = client.DeleteDevice(ctx, &id)
621 }
Scott Baker9173ed82020-05-19 08:30:12 -0700622
Zack Williamse940c7a2019-08-21 14:25:39 -0700623 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000624 Error.Printf("Error while deleting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700625 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700626 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700627 }
628 fmt.Printf("%s\n", i)
629 }
630
David Bainbridge7052fe82020-03-25 10:37:00 -0700631 if lastErr != nil {
632 return NoReportErr
633 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700634 return nil
635}
636
637func (options *DeviceEnable) Execute(args []string) error {
638 conn, err := NewConnection()
639 if err != nil {
640 return err
641 }
642 defer conn.Close()
643
Scott Baker9173ed82020-05-19 08:30:12 -0700644 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700645
David Bainbridge7052fe82020-03-25 10:37:00 -0700646 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700647 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700648 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
649 defer cancel()
650
Scott Baker9173ed82020-05-19 08:30:12 -0700651 id := voltha.ID{Id: string(i)}
652
653 _, err := client.EnableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700654 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000655 Error.Printf("Error while enabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700656 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700657 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700658 }
659 fmt.Printf("%s\n", i)
660 }
661
David Bainbridge7052fe82020-03-25 10:37:00 -0700662 if lastErr != nil {
663 return NoReportErr
664 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700665 return nil
666}
667
668func (options *DeviceDisable) Execute(args []string) error {
669 conn, err := NewConnection()
670 if err != nil {
671 return err
672 }
673 defer conn.Close()
674
Scott Baker9173ed82020-05-19 08:30:12 -0700675 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700676
David Bainbridge7052fe82020-03-25 10:37:00 -0700677 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700678 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700679 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
680 defer cancel()
681
Scott Baker9173ed82020-05-19 08:30:12 -0700682 id := voltha.ID{Id: string(i)}
683
684 _, err := client.DisableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700685 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000686 Error.Printf("Error while disabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700687 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700688 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700689 }
690 fmt.Printf("%s\n", i)
691 }
692
David Bainbridge7052fe82020-03-25 10:37:00 -0700693 if lastErr != nil {
694 return NoReportErr
695 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700696 return nil
697}
698
699func (options *DeviceReboot) Execute(args []string) error {
700 conn, err := NewConnection()
701 if err != nil {
702 return err
703 }
704 defer conn.Close()
705
Scott Baker9173ed82020-05-19 08:30:12 -0700706 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700707
David Bainbridge7052fe82020-03-25 10:37:00 -0700708 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700709 for _, i := range options.Args.Ids {
Zack Williamse940c7a2019-08-21 14:25:39 -0700710 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
711 defer cancel()
712
Scott Baker9173ed82020-05-19 08:30:12 -0700713 id := voltha.ID{Id: string(i)}
714
715 _, err := client.RebootDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700716 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000717 Error.Printf("Error while rebooting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700718 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700719 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700720 }
721 fmt.Printf("%s\n", i)
722 }
723
David Bainbridge7052fe82020-03-25 10:37:00 -0700724 if lastErr != nil {
725 return NoReportErr
726 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700727 return nil
728}
729
730func (options *DevicePortList) Execute(args []string) error {
731
732 conn, err := NewConnection()
733 if err != nil {
734 return err
735 }
736 defer conn.Close()
737
Scott Baker9173ed82020-05-19 08:30:12 -0700738 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700739
740 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
741 defer cancel()
742
Scott Baker9173ed82020-05-19 08:30:12 -0700743 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700744
Scott Baker9173ed82020-05-19 08:30:12 -0700745 ports, err := client.ListDevicePorts(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700746 if err != nil {
747 return err
748 }
749
750 outputFormat := CharReplacer.Replace(options.Format)
751 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000752 outputFormat = GetCommandOptionWithDefault("device-ports", "format", DEFAULT_DEVICE_PORTS_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700753 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700754
David Bainbridgea6722342019-10-24 23:55:53 +0000755 orderBy := options.OrderBy
756 if orderBy == "" {
757 orderBy = GetCommandOptionWithDefault("device-ports", "order", "")
758 }
759
Zack Williamse940c7a2019-08-21 14:25:39 -0700760 result := CommandResult{
761 Format: format.Format(outputFormat),
762 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000763 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700764 OutputAs: toOutputType(options.OutputAs),
765 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700766 Data: ports.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700767 }
768
769 GenerateOutput(&result)
770 return nil
771}
772
773func (options *DeviceFlowList) Execute(args []string) error {
774 fl := &FlowList{}
775 fl.ListOutputOptions = options.ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530776 fl.FlowIdOptions = options.FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700777 fl.Args.Id = string(options.Args.Id)
David Bainbridgea6722342019-10-24 23:55:53 +0000778 fl.Method = "device-flows"
Zack Williamse940c7a2019-08-21 14:25:39 -0700779 return fl.Execute(args)
780}
781
782func (options *DeviceInspect) Execute(args []string) error {
783 if len(args) > 0 {
784 return fmt.Errorf("only a single argument 'DEVICE_ID' can be provided")
785 }
786
787 conn, err := NewConnection()
788 if err != nil {
789 return err
790 }
791 defer conn.Close()
792
Scott Baker9173ed82020-05-19 08:30:12 -0700793 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700794
795 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
796 defer cancel()
797
Scott Baker9173ed82020-05-19 08:30:12 -0700798 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700799
Scott Baker9173ed82020-05-19 08:30:12 -0700800 device, err := client.GetDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700801 if err != nil {
802 return err
803 }
804
Zack Williamse940c7a2019-08-21 14:25:39 -0700805 outputFormat := CharReplacer.Replace(options.Format)
806 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000807 outputFormat = GetCommandOptionWithDefault("device-inspect", "format", DEFAULT_DEVICE_INSPECT_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700808 }
809 if options.Quiet {
810 outputFormat = "{{.Id}}"
811 }
812
813 result := CommandResult{
814 Format: format.Format(outputFormat),
815 OutputAs: toOutputType(options.OutputAs),
816 NameLimit: options.NameLimit,
817 Data: device,
818 }
819 GenerateOutput(&result)
820 return nil
821}
kesavand12cd8eb2020-01-20 22:25:22 -0500822
823/*Device Port Enable */
824func (options *DevicePortEnable) Execute(args []string) error {
825 conn, err := NewConnection()
826 if err != nil {
827 return err
828 }
829 defer conn.Close()
830
Scott Baker9173ed82020-05-19 08:30:12 -0700831 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500832
kesavand12cd8eb2020-01-20 22:25:22 -0500833 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
834 defer cancel()
835
Scott Baker9173ed82020-05-19 08:30:12 -0700836 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
837
838 _, err = client.EnablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500839 if err != nil {
840 Error.Printf("Error enabling port number %v on device Id %s,err=%s\n", options.Args.PortId, options.Args.Id, ErrorToString(err))
841 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500842 }
843
844 return nil
845}
846
Scott Baker9173ed82020-05-19 08:30:12 -0700847/*Device Port Disable */
kesavand12cd8eb2020-01-20 22:25:22 -0500848func (options *DevicePortDisable) Execute(args []string) error {
849 conn, err := NewConnection()
850 if err != nil {
851 return err
852 }
853 defer conn.Close()
854
Scott Baker9173ed82020-05-19 08:30:12 -0700855 client := voltha.NewVolthaServiceClient(conn)
856
kesavand12cd8eb2020-01-20 22:25:22 -0500857 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
858 defer cancel()
859
Scott Baker9173ed82020-05-19 08:30:12 -0700860 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
861
862 _, err = client.DisablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500863 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700864 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 -0500865 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500866 }
Scott Baker9173ed82020-05-19 08:30:12 -0700867
kesavand12cd8eb2020-01-20 22:25:22 -0500868 return nil
869}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800870
Rohan Agrawald7df3772020-06-29 11:23:36 +0000871func (options *DevicePmConfigSetMaxSkew) Execute(args []string) error {
872 conn, err := NewConnection()
873 if err != nil {
874 return err
875 }
876 defer conn.Close()
877
878 client := voltha.NewVolthaServiceClient(conn)
879
880 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
881 defer cancel()
882
883 id := voltha.ID{Id: string(options.Args.Id)}
884
885 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
886 if err != nil {
887 return err
888 }
889
890 pmConfigs.MaxSkew = options.Args.MaxSkew
891
892 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
893 if err != nil {
894 return err
895 }
896
897 return nil
898}
899
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000900func (options *DevicePmConfigsGet) Execute(args []string) error {
901
902 conn, err := NewConnection()
903 if err != nil {
904 return err
905 }
906 defer conn.Close()
907
908 client := voltha.NewVolthaServiceClient(conn)
909
910 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
911 defer cancel()
912
913 id := voltha.ID{Id: string(options.Args.Id)}
914
915 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
916 if err != nil {
917 return err
918 }
919
920 outputFormat := CharReplacer.Replace(options.Format)
921 if outputFormat == "" {
922 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
923 }
924
925 orderBy := options.OrderBy
926 if orderBy == "" {
927 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
928 }
929
930 result := CommandResult{
931 Format: format.Format(outputFormat),
932 Filter: options.Filter,
933 OrderBy: orderBy,
934 OutputAs: toOutputType(options.OutputAs),
935 NameLimit: options.NameLimit,
936 Data: pmConfigs,
937 }
938
939 GenerateOutput(&result)
940 return nil
941
942}
943
944func (options *DevicePmConfigMetricList) Execute(args []string) error {
945
946 conn, err := NewConnection()
947 if err != nil {
948 return err
949 }
950 defer conn.Close()
951
952 client := voltha.NewVolthaServiceClient(conn)
953
954 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
955 defer cancel()
956
957 id := voltha.ID{Id: string(options.Args.Id)}
958
959 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
960 if err != nil {
961 return err
962 }
963
964 if !pmConfigs.Grouped {
965 for _, metric := range pmConfigs.Metrics {
966 if metric.SampleFreq == 0 {
967 metric.SampleFreq = pmConfigs.DefaultFreq
968 }
969 }
Rohan Agrawalbca69122020-06-17 14:59:03 +0000970 outputFormat := CharReplacer.Replace(options.Format)
971 if outputFormat == "" {
972 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
973 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000974
Rohan Agrawalbca69122020-06-17 14:59:03 +0000975 orderBy := options.OrderBy
976 if orderBy == "" {
977 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
978 }
979
980 result := CommandResult{
981 Format: format.Format(outputFormat),
982 Filter: options.Filter,
983 OrderBy: orderBy,
984 OutputAs: toOutputType(options.OutputAs),
985 NameLimit: options.NameLimit,
986 Data: pmConfigs.Metrics,
987 }
988
989 GenerateOutput(&result)
990 return nil
991 } else {
992 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000993 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000994}
995
996func (options *DevicePmConfigMetricEnable) Execute(args []string) error {
997
998 conn, err := NewConnection()
999 if err != nil {
1000 return err
1001 }
1002 defer conn.Close()
1003
1004 client := voltha.NewVolthaServiceClient(conn)
1005
1006 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1007 defer cancel()
1008
1009 id := voltha.ID{Id: string(options.Args.Id)}
1010
1011 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1012 if err != nil {
1013 return err
1014 }
1015
1016 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001017 metrics := make(map[string]struct{})
1018 for _, metric := range pmConfigs.Metrics {
1019 metrics[metric.Name] = struct{}{}
1020 }
1021
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001022 for _, metric := range pmConfigs.Metrics {
1023 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001024 if _, exist := metrics[string(mName)]; !exist {
1025 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1026 }
1027
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001028 if string(mName) == metric.Name && !metric.Enabled {
1029 metric.Enabled = true
1030 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1031 if err != nil {
1032 return err
1033 }
1034 }
1035 }
1036 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001037 } else {
1038 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001039 }
1040 return nil
1041}
1042
1043func (options *DevicePmConfigMetricDisable) Execute(args []string) error {
1044
1045 conn, err := NewConnection()
1046 if err != nil {
1047 return err
1048 }
1049 defer conn.Close()
1050
1051 client := voltha.NewVolthaServiceClient(conn)
1052
1053 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1054 defer cancel()
1055
1056 id := voltha.ID{Id: string(options.Args.Id)}
1057
1058 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1059 if err != nil {
1060 return err
1061 }
1062
1063 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001064 metrics := make(map[string]struct{})
1065 for _, metric := range pmConfigs.Metrics {
1066 metrics[metric.Name] = struct{}{}
1067 }
1068
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001069 for _, metric := range pmConfigs.Metrics {
1070 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001071 if _, have := metrics[string(mName)]; !have {
1072 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1073 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001074 if string(mName) == metric.Name && metric.Enabled {
1075 metric.Enabled = false
1076 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1077 if err != nil {
1078 return err
1079 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001080 } else {
1081 return fmt.Errorf("Metric '%s' cannot be disabled", string(mName))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001082 }
1083 }
1084 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001085 } else {
1086 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001087 }
1088 return nil
1089}
1090
1091func (options *DevicePmConfigGroupEnable) Execute(args []string) error {
1092
1093 conn, err := NewConnection()
1094 if err != nil {
1095 return err
1096 }
1097 defer conn.Close()
1098
1099 client := voltha.NewVolthaServiceClient(conn)
1100
1101 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1102 defer cancel()
1103
1104 id := voltha.ID{Id: string(options.Args.Id)}
1105
1106 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1107 if err != nil {
1108 return err
1109 }
1110
1111 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001112 groups := make(map[string]struct{})
1113 for _, group := range pmConfigs.Groups {
1114 groups[group.GroupName] = struct{}{}
1115 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001116 for _, group := range pmConfigs.Groups {
1117 for _, gName := range options.Args.Groups {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001118 if _, have := groups[string(gName)]; !have {
1119 return fmt.Errorf("Group Name '%s' does not exist", gName)
1120 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001121 if string(gName) == group.GroupName && !group.Enabled {
1122 group.Enabled = true
1123 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1124 if err != nil {
1125 return err
1126 }
1127 }
1128 }
1129 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001130 } else {
1131 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001132 }
1133 return nil
1134}
1135
1136func (options *DevicePmConfigGroupDisable) Execute(args []string) error {
1137
1138 conn, err := NewConnection()
1139 if err != nil {
1140 return err
1141 }
1142 defer conn.Close()
1143
1144 client := voltha.NewVolthaServiceClient(conn)
1145
1146 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1147 defer cancel()
1148
1149 id := voltha.ID{Id: string(options.Args.Id)}
1150
1151 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1152 if err != nil {
1153 return err
1154 }
1155
1156 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001157 groups := make(map[string]struct{})
1158 for _, group := range pmConfigs.Groups {
1159 groups[group.GroupName] = struct{}{}
1160 }
1161
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001162 for _, group := range pmConfigs.Groups {
1163 for _, gName := range options.Args.Groups {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001164 if _, have := groups[string(gName)]; !have {
1165 return fmt.Errorf("Group Name '%s' does not exist", gName)
1166 }
1167
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001168 if string(gName) == group.GroupName && group.Enabled {
1169 group.Enabled = false
1170 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1171 if err != nil {
1172 return err
1173 }
1174 }
1175 }
1176 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001177 } else {
1178 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001179 }
1180 return nil
1181}
1182
1183func (options *DevicePmConfigGroupList) Execute(args []string) error {
1184
1185 conn, err := NewConnection()
1186 if err != nil {
1187 return err
1188 }
1189 defer conn.Close()
1190
1191 client := voltha.NewVolthaServiceClient(conn)
1192
1193 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1194 defer cancel()
1195
1196 id := voltha.ID{Id: string(options.Args.Id)}
1197
1198 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1199 if err != nil {
1200 return err
1201 }
1202
1203 if pmConfigs.Grouped {
1204 for _, group := range pmConfigs.Groups {
1205 if group.GroupFreq == 0 {
1206 group.GroupFreq = pmConfigs.DefaultFreq
1207 }
1208 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001209 outputFormat := CharReplacer.Replace(options.Format)
1210 if outputFormat == "" {
1211 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT)
1212 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001213
Rohan Agrawalbca69122020-06-17 14:59:03 +00001214 orderBy := options.OrderBy
1215 if orderBy == "" {
1216 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1217 }
1218
1219 result := CommandResult{
1220 Format: format.Format(outputFormat),
1221 Filter: options.Filter,
1222 OrderBy: orderBy,
1223 OutputAs: toOutputType(options.OutputAs),
1224 NameLimit: options.NameLimit,
1225 Data: pmConfigs.Groups,
1226 }
1227
1228 GenerateOutput(&result)
1229 } else {
1230 return fmt.Errorf("Device '%s' does not have Group Metrics", string(options.Args.Id))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001231 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001232 return nil
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001233}
1234
1235func (options *DevicePmConfigGroupMetricList) Execute(args []string) error {
1236
1237 var metrics []*voltha.PmConfig
1238 conn, err := NewConnection()
1239 if err != nil {
1240 return err
1241 }
1242 defer conn.Close()
1243
1244 client := voltha.NewVolthaServiceClient(conn)
1245
1246 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1247 defer cancel()
1248
1249 id := voltha.ID{Id: string(options.Args.Id)}
1250
1251 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1252 if err != nil {
1253 return err
1254 }
1255
1256 for _, groups := range pmConfigs.Groups {
1257
1258 if string(options.Args.Group) == groups.GroupName {
1259 for _, metric := range groups.Metrics {
1260 if metric.SampleFreq == 0 && groups.GroupFreq == 0 {
1261 metric.SampleFreq = pmConfigs.DefaultFreq
1262 } else {
1263 metric.SampleFreq = groups.GroupFreq
1264 }
1265 }
1266 metrics = groups.Metrics
1267 }
1268 }
1269
1270 outputFormat := CharReplacer.Replace(options.Format)
1271 if outputFormat == "" {
1272 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
1273 }
1274
1275 orderBy := options.OrderBy
1276 if orderBy == "" {
1277 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1278 }
1279
1280 result := CommandResult{
1281 Format: format.Format(outputFormat),
1282 Filter: options.Filter,
1283 OrderBy: orderBy,
1284 OutputAs: toOutputType(options.OutputAs),
1285 NameLimit: options.NameLimit,
1286 Data: metrics,
1287 }
1288
1289 GenerateOutput(&result)
1290 return nil
1291
1292}
1293
1294func (options *DevicePmConfigFrequencySet) Execute(args []string) error {
1295
1296 conn, err := NewConnection()
1297 if err != nil {
1298 return err
1299 }
1300 defer conn.Close()
1301
1302 client := voltha.NewVolthaServiceClient(conn)
1303
1304 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1305 defer cancel()
1306
1307 id := voltha.ID{Id: string(options.Args.Id)}
1308
1309 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1310 if err != nil {
1311 return err
1312 }
1313
1314 pmConfigs.DefaultFreq = options.Args.Frequency
1315
1316 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1317 if err != nil {
1318 return err
1319 }
1320
1321 outputFormat := CharReplacer.Replace(options.Format)
1322 if outputFormat == "" {
1323 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
1324 }
1325 if options.Quiet {
1326 outputFormat = "{{.Id}}"
1327 }
1328
1329 result := CommandResult{
1330 Format: format.Format(outputFormat),
1331 OutputAs: toOutputType(options.OutputAs),
1332 NameLimit: options.NameLimit,
1333 Data: pmConfigs,
1334 }
1335
1336 GenerateOutput(&result)
1337 return nil
1338
1339}
1340
Andrea Campanella791d88b2021-01-08 13:29:00 +01001341func (options *DeviceOnuListImages) Execute(args []string) error {
1342
1343 conn, err := NewConnection()
1344 if err != nil {
1345 return err
1346 }
1347 defer conn.Close()
1348
1349 client := voltha.NewVolthaServiceClient(conn)
1350
1351 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1352 defer cancel()
1353
1354 id := common.ID{Id: string(options.Args.Id)}
1355
1356 imageDownloads, err := client.ListImageDownloads(ctx, &id)
1357 if err != nil {
1358 return err
1359 }
1360
1361 outputFormat := CharReplacer.Replace(options.Format)
1362 if outputFormat == "" {
1363 outputFormat = GetCommandOptionWithDefault("device-image-list", "format", DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT)
1364 }
1365
1366 if options.Quiet {
1367 outputFormat = "{{.Id}}"
1368 }
1369
1370 //TODO orderby
1371
1372 // Make sure json output prints an empty list, not "null"
1373 if imageDownloads.Items == nil {
1374 imageDownloads.Items = make([]*voltha.ImageDownload, 0)
1375 }
1376
1377 result := CommandResult{
1378 Format: format.Format(outputFormat),
1379 OutputAs: toOutputType(options.OutputAs),
1380 NameLimit: options.NameLimit,
1381 Data: imageDownloads.Items,
1382 }
1383
1384 GenerateOutput(&result)
1385 return nil
1386
1387}
1388
1389func (options *DeviceOnuDownloadImage) Execute(args []string) error {
1390
1391 conn, err := NewConnection()
1392 if err != nil {
1393 return err
1394 }
1395 defer conn.Close()
1396
1397 client := voltha.NewVolthaServiceClient(conn)
1398
1399 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1400 defer cancel()
1401
1402 downloadImage := voltha.ImageDownload{
1403 Id: string(options.Args.Id),
1404 Name: options.Args.Name,
1405 Url: options.Args.Url,
1406 Crc: options.Args.Crc,
1407 LocalDir: options.Args.LocalDir,
1408 }
1409
1410 _, err = client.DownloadImage(ctx, &downloadImage)
1411 if err != nil {
1412 return err
1413 }
1414
1415 return nil
1416
1417}
1418
1419func (options *DeviceOnuActivateImageUpdate) Execute(args []string) error {
1420
1421 conn, err := NewConnection()
1422 if err != nil {
1423 return err
1424 }
1425 defer conn.Close()
1426
1427 client := voltha.NewVolthaServiceClient(conn)
1428
1429 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1430 defer cancel()
1431
1432 downloadImage := voltha.ImageDownload{
1433 Id: string(options.Args.Id),
1434 Name: options.Args.Name,
1435 ImageVersion: options.Args.ImageVersion,
1436 SaveConfig: options.Args.SaveConfig,
1437 LocalDir: options.Args.LocalDir,
1438 }
1439
1440 _, err = client.ActivateImageUpdate(ctx, &downloadImage)
1441 if err != nil {
1442 return err
1443 }
1444
1445 return nil
1446
1447}
1448
Scott Baker9173ed82020-05-19 08:30:12 -07001449type ReturnValueRow struct {
1450 Name string `json:"name"`
1451 Result interface{} `json:"result"`
1452}
1453
kesavand8ec4fc02021-01-27 09:10:22 -05001454func (options *DeviceGetPortStats) Execute(args []string) error {
1455 conn, err := NewConnection()
1456 if err != nil {
1457 return err
1458 }
1459 defer conn.Close()
1460 client := extension.NewExtensionClient(conn)
1461 var portType extension.GetOltPortCounters_PortType
1462
1463 if options.Args.PortType == "pon" {
1464 portType = extension.GetOltPortCounters_Port_PON_OLT
1465 } else if options.Args.PortType == "nni" {
1466
1467 portType = extension.GetOltPortCounters_Port_ETHERNET_NNI
1468 } else {
1469 return fmt.Errorf("expected interface type pon/nni, provided %s", options.Args.PortType)
1470 }
1471
1472 singleGetValReq := extension.SingleGetValueRequest{
1473 TargetId: string(options.Args.Id),
1474 Request: &extension.GetValueRequest{
1475 Request: &extension.GetValueRequest_OltPortInfo{
1476 OltPortInfo: &extension.GetOltPortCounters{
1477 PortNo: options.Args.PortNo,
1478 PortType: portType,
1479 },
1480 },
1481 },
1482 }
1483
1484 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1485 defer cancel()
1486 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1487 if err != nil {
1488 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1489 return err
1490 }
1491
1492 if rv.Response.Status != extension.GetValueResponse_OK {
1493 return fmt.Errorf("failed to get port stats %v", rv.Response.ErrReason.String())
1494 }
1495
1496 outputFormat := CharReplacer.Replace(options.Format)
1497 if outputFormat == "" {
1498 outputFormat = GetCommandOptionWithDefault("device-get-port-status", "format", DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT)
1499 }
1500
1501 result := CommandResult{
1502 Format: format.Format(outputFormat),
1503 OutputAs: toOutputType(options.OutputAs),
1504 NameLimit: options.NameLimit,
1505 Data: rv.GetResponse().GetPortCoutners(),
1506 }
1507 GenerateOutput(&result)
1508 return nil
1509}
1510
kesavand6d1131f2021-02-05 22:38:15 +05301511func (options *UniStatus) Execute(args []string) error {
1512 conn, err := NewConnection()
1513 if err != nil {
1514 return err
1515 }
1516 defer conn.Close()
1517 client := extension.NewExtensionClient(conn)
1518
1519 singleGetValReq := extension.SingleGetValueRequest{
1520 TargetId: string(options.Args.Id),
1521 Request: &extension.GetValueRequest{
1522 Request: &extension.GetValueRequest_UniInfo{
1523 UniInfo: &extension.GetOnuUniInfoRequest{
1524 UniIndex: options.Args.UniIndex,
1525 },
1526 },
1527 },
1528 }
1529 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1530 defer cancel()
1531 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1532 if err != nil {
1533 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1534 return err
1535 }
1536 if rv.Response.Status != extension.GetValueResponse_OK {
1537 return fmt.Errorf("failed to get uni status %v", rv.Response.ErrReason.String())
1538 }
1539 outputFormat := CharReplacer.Replace(options.Format)
1540 if outputFormat == "" {
1541 outputFormat = GetCommandOptionWithDefault("device-get-uni-status", "format", DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT)
1542 }
1543 result := CommandResult{
1544 Format: format.Format(outputFormat),
1545 OutputAs: toOutputType(options.OutputAs),
1546 NameLimit: options.NameLimit,
1547 Data: rv.GetResponse().GetUniInfo(),
1548 }
1549 GenerateOutput(&result)
1550 return nil
1551}
1552
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001553/*Device get Onu Distance */
1554func (options *DeviceGetExtValue) Execute(args []string) error {
1555 conn, err := NewConnection()
1556 if err != nil {
1557 return err
1558 }
1559 defer conn.Close()
1560
Scott Baker9173ed82020-05-19 08:30:12 -07001561 client := voltha.NewVolthaServiceClient(conn)
1562
1563 valueflag, okay := common.ValueType_Type_value[string(options.Args.Valueflag)]
1564 if !okay {
1565 Error.Printf("Unknown valueflag %s\n", options.Args.Valueflag)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001566 }
1567
Scott Baker9173ed82020-05-19 08:30:12 -07001568 val := voltha.ValueSpecifier{Id: string(options.Args.Id), Value: common.ValueType_Type(valueflag)}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001569
1570 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
1571 defer cancel()
1572
Scott Baker9173ed82020-05-19 08:30:12 -07001573 rv, err := client.GetExtValue(ctx, &val)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001574 if err != nil {
1575 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1576 return err
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001577 }
1578
Scott Baker9173ed82020-05-19 08:30:12 -07001579 var rows []ReturnValueRow
1580 for name, num := range common.ValueType_Type_value {
1581 if num == 0 {
1582 // EMPTY is not a real value
1583 continue
1584 }
1585 if (rv.Error & uint32(num)) != 0 {
1586 row := ReturnValueRow{Name: name, Result: "Error"}
1587 rows = append(rows, row)
1588 }
1589 if (rv.Unsupported & uint32(num)) != 0 {
1590 row := ReturnValueRow{Name: name, Result: "Unsupported"}
1591 rows = append(rows, row)
1592 }
1593 if (rv.Set & uint32(num)) != 0 {
1594 switch name {
1595 case "DISTANCE":
1596 row := ReturnValueRow{Name: name, Result: rv.Distance}
1597 rows = append(rows, row)
1598 default:
1599 row := ReturnValueRow{Name: name, Result: "Unimplemented-in-voltctl"}
1600 rows = append(rows, row)
1601 }
1602 }
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001603 }
1604
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001605 outputFormat := CharReplacer.Replace(options.Format)
1606 if outputFormat == "" {
1607 outputFormat = GetCommandOptionWithDefault("device-value-get", "format", DEFAULT_DEVICE_VALUE_GET_FORMAT)
1608 }
1609
1610 result := CommandResult{
1611 Format: format.Format(outputFormat),
1612 OutputAs: toOutputType(options.OutputAs),
1613 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -07001614 Data: rows,
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08001615 }
1616 GenerateOutput(&result)
1617 return nil
1618}