blob: 073cd6688aacbeb059935260e3c845a4029680fe [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001/*
2 * Copyright 2019-present Ciena Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package commands
17
18import (
19 "context"
20 "fmt"
David Bainbridge7052fe82020-03-25 10:37:00 -070021 "os"
22 "strconv"
23 "strings"
Girish Gowdra610acb42021-01-27 13:33:57 -080024 "time"
David Bainbridge7052fe82020-03-25 10:37:00 -070025
Scott Baker9173ed82020-05-19 08:30:12 -070026 "github.com/golang/protobuf/ptypes/empty"
Zack Williamse940c7a2019-08-21 14:25:39 -070027 flags "github.com/jessevdk/go-flags"
Scott Baker2b0ad652019-08-21 14:57:07 -070028 "github.com/opencord/voltctl/pkg/format"
kesavand8ec4fc02021-01-27 09:10:22 -050029 "github.com/opencord/voltha-protos/v4/go/common"
30 "github.com/opencord/voltha-protos/v4/go/extension"
31 "github.com/opencord/voltha-protos/v4/go/voltha"
Zack Williamse940c7a2019-08-21 14:25:39 -070032)
33
34const (
David K. Bainbridge89003c42020-02-27 17:22:49 -080035 DEFAULT_DEVICE_FORMAT = "table{{ .Id }}\t{{.Type}}\t{{.Root}}\t{{.ParentId}}\t{{.SerialNumber}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.ConnectStatus}}\t{{.Reason}}"
Zack Williamse940c7a2019-08-21 14:25:39 -070036 DEFAULT_DEVICE_PORTS_FORMAT = "table{{.PortNo}}\t{{.Label}}\t{{.Type}}\t{{.AdminState}}\t{{.OperStatus}}\t{{.DeviceId}}\t{{.Peers}}"
37 DEFAULT_DEVICE_INSPECT_FORMAT = `ID: {{.Id}}
38 TYPE: {{.Type}}
39 ROOT: {{.Root}}
40 PARENTID: {{.ParentId}}
41 SERIALNUMBER: {{.SerialNumber}}
42 VLAN: {{.Vlan}}
43 ADMINSTATE: {{.AdminState}}
44 OPERSTATUS: {{.OperStatus}}
45 CONNECTSTATUS: {{.ConnectStatus}}`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000046 DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT = "table{{.DefaultFreq}}\t{{.Grouped}}\t{{.FreqOverride}}"
47 DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT = "table{{.Name}}\t{{.Type}}\t{{.Enabled}}\t{{.SampleFreq}}"
48 DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT = "table{{.GroupName}}\t{{.Enabled}}\t{{.GroupFreq}}"
49 DEFAULT_DEVICE_VALUE_GET_FORMAT = "table{{.Name}}\t{{.Result}}"
Andrea Campanella791d88b2021-01-08 13:29:00 +010050 DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT = "table{{.Name}}\t{{.Url}}\t{{.Crc}}\t{{.DownloadState}}\t{{.ImageVersion}}\t{{.LocalDir}}\t{{.ImageState}}\t{{.FileSize}}"
ssiddiqui7bc89e92021-05-20 20:58:02 +053051 ONU_IMAGE_LIST_FORMAT = "table{{.Version}}\t{{.IsCommited}}\t{{.IsActive}}\t{{.IsValid}}\t{{.ProductCode}}\t{{.Hash}}"
52 ONU_IMAGE_STATUS_FORMAT = "table{{.DeviceId}}\t{{.ImageState.Version}}\t{{.ImageState.DownloadState}}\t{{.ImageState.Reason}}\t{{.ImageState.ImageState}}\t"
kesavand8ec4fc02021-01-27 09:10:22 -050053 DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT = `
54 TXBYTES: {{.TxBytes}}
55 TXPACKETS: {{.TxPackets}}
56 TXERRPACKETS: {{.TxErrorPackets}}
57 TXBCASTPACKETS: {{.TxBcastPackets}}
58 TXUCASTPACKETS: {{.TxUcastPackets}}
59 TXMCASTPACKETS: {{.TxMcastPackets}}
60 RXBYTES: {{.RxBytes}}
61 RXPACKETS: {{.RxPackets}}
62 RXERRPACKETS: {{.RxErrorPackets}}
63 RXBCASTPACKETS: {{.RxBcastPackets}}
64 RXUCASTPACKETS: {{.RxUcastPackets}}
65 RXMCASTPACKETS: {{.RxMcastPackets}}`
kesavand6d1131f2021-02-05 22:38:15 +053066 DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT = `
67 ADMIN_STATE: {{.AdmState}}
68 OPERATIONAL_STATE: {{.OperState}}
69 CONFIG_IND: {{.ConfigInd}}`
Girish Gowdra4f5ce7c2021-04-29 18:53:21 -070070 DEFAULT_ONU_PON_OPTICAL_INFO_STATUS_FORMAT = `
71 POWER_FEED_VOLTAGE__VOLTS: {{.PowerFeedVoltage}}
72 RECEIVED_OPTICAL_POWER__dBm: {{.ReceivedOpticalPower}}
73 MEAN_OPTICAL_LAUNCH_POWER__dBm: {{.MeanOpticalLaunchPower}}
74 LASER_BIAS_CURRENT__mA: {{.LaserBiasCurrent}}
75 TEMPERATURE__Celsius: {{.Temperature}}`
Gamze Abakac857a462021-05-26 13:45:54 +000076 DEFAULT_RX_POWER_STATUS_FORMAT = `
77 INTF_ID: {{.IntfId}}
78 ONU_ID: {{.OnuId}}
79 STATUS: {{.Status}}
80 FAIL_REASON: {{.FailReason}}
81 RX_POWER : {{.RxPower}}`
Zack Williamse940c7a2019-08-21 14:25:39 -070082)
83
84type DeviceList struct {
85 ListOutputOptions
86}
87
88type DeviceCreate struct {
David Bainbridge1a514392020-06-23 11:12:51 -070089 DeviceType string `short:"t" required:"true" long:"devicetype" description:"Device type"`
David Bainbridge835dd0e2020-04-01 10:30:09 -070090 MACAddress string `short:"m" long:"macaddress" default:"" description:"MAC Address"`
Zack Williamse940c7a2019-08-21 14:25:39 -070091 IPAddress string `short:"i" long:"ipaddress" default:"" description:"IP Address"`
92 HostAndPort string `short:"H" long:"hostandport" default:"" description:"Host and port"`
93}
94
95type DeviceId string
96
Rohan Agrawal9228d2f2020-06-03 07:48:50 +000097type MetricName string
98type GroupName string
kesavand12cd8eb2020-01-20 22:25:22 -050099type PortNum uint32
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800100type ValueFlag string
kesavand12cd8eb2020-01-20 22:25:22 -0500101
Zack Williamse940c7a2019-08-21 14:25:39 -0700102type DeviceDelete struct {
Himani Chawla9933ddc2020-10-12 23:53:27 +0530103 Force bool `long:"force" description:"Delete device forcefully"`
104 Args struct {
Zack Williamse940c7a2019-08-21 14:25:39 -0700105 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
106 } `positional-args:"yes"`
107}
108
109type DeviceEnable struct {
110 Args struct {
111 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
112 } `positional-args:"yes"`
113}
114
115type DeviceDisable struct {
116 Args struct {
117 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
118 } `positional-args:"yes"`
119}
120
121type DeviceReboot struct {
122 Args struct {
123 Ids []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
124 } `positional-args:"yes"`
125}
126
127type DeviceFlowList struct {
128 ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530129 FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700130 Args struct {
131 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
132 } `positional-args:"yes"`
133}
134
Himani Chawla3c161c62021-05-13 16:36:51 +0530135type DeviceFlowGroupList struct {
136 ListOutputOptions
137 GroupListOptions
138 Args struct {
139 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
140 } `positional-args:"yes"`
141}
Zack Williamse940c7a2019-08-21 14:25:39 -0700142type DevicePortList struct {
143 ListOutputOptions
144 Args struct {
145 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
146 } `positional-args:"yes"`
147}
148
149type DeviceInspect struct {
150 OutputOptionsJson
151 Args struct {
152 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
153 } `positional-args:"yes"`
154}
155
kesavand12cd8eb2020-01-20 22:25:22 -0500156type DevicePortEnable struct {
157 Args struct {
158 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
159 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
160 } `positional-args:"yes"`
161}
162
163type DevicePortDisable struct {
164 Args struct {
165 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
166 PortId PortNum `positional-arg-name:"PORT_NUMBER" required:"yes"`
167 } `positional-args:"yes"`
168}
169
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000170type DevicePmConfigsGet struct {
171 ListOutputOptions
172 Args struct {
173 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
174 } `positional-args:"yes"`
175}
176
177type DevicePmConfigMetricList struct {
178 ListOutputOptions
179 Args struct {
180 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
181 } `positional-args:"yes"`
182}
183
184type DevicePmConfigGroupList struct {
185 ListOutputOptions
186 Args struct {
187 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
188 } `positional-args:"yes"`
189}
190
191type DevicePmConfigGroupMetricList struct {
192 ListOutputOptions
193 Args struct {
194 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
195 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
196 } `positional-args:"yes"`
197}
198
199type DevicePmConfigFrequencySet struct {
200 OutputOptions
201 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800202 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
203 Interval time.Duration `positional-arg-name:"INTERVAL" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000204 } `positional-args:"yes"`
205}
206
207type DevicePmConfigMetricEnable struct {
208 Args struct {
209 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
210 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
211 } `positional-args:"yes"`
212}
213
214type DevicePmConfigMetricDisable struct {
215 Args struct {
216 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
217 Metrics []MetricName `positional-arg-name:"METRIC_NAME" required:"yes"`
218 } `positional-args:"yes"`
219}
220
221type DevicePmConfigGroupEnable struct {
222 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800223 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
224 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000225 } `positional-args:"yes"`
226}
227
228type DevicePmConfigGroupDisable struct {
229 Args struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800230 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
231 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
232 } `positional-args:"yes"`
233}
234
235type DevicePmConfigGroupFrequencySet struct {
236 OutputOptions
237 Args struct {
238 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
239 Group GroupName `positional-arg-name:"GROUP_NAME" required:"yes"`
240 Interval time.Duration `positional-arg-name:"INTERVAL" required:"yes"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000241 } `positional-args:"yes"`
242}
243
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800244type DeviceGetExtValue struct {
245 ListOutputOptions
246 Args struct {
247 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
248 Valueflag ValueFlag `positional-arg-name:"VALUE_FLAG" required:"yes"`
249 } `positional-args:"yes"`
250}
Rohan Agrawald7df3772020-06-29 11:23:36 +0000251
252type DevicePmConfigSetMaxSkew struct {
253 Args struct {
254 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
255 MaxSkew uint32 `positional-arg-name:"MAX_SKEW" required:"yes"`
256 } `positional-args:"yes"`
257}
258
Andrea Campanella791d88b2021-01-08 13:29:00 +0100259type DeviceOnuListImages struct {
260 ListOutputOptions
261 Args struct {
262 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
263 } `positional-args:"yes"`
264}
265
266type DeviceOnuDownloadImage struct {
267 Args struct {
268 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
269 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
270 Url string `positional-arg-name:"IMAGE_URL" required:"yes"`
271 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
272 Crc uint32 `positional-arg-name:"IMAGE_CRC" required:"yes"`
273 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
274 } `positional-args:"yes"`
275}
276
277type DeviceOnuActivateImageUpdate struct {
278 Args struct {
279 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
280 Name string `positional-arg-name:"IMAGE_NAME" required:"yes"`
281 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
282 SaveConfig bool `positional-arg-name:"SAVE_EXISTING_CONFIG"`
283 LocalDir string `positional-arg-name:"IMAGE_LOCAL_DIRECTORY"`
Andrea Campanella7b2ecf42021-02-25 12:27:15 +0100284 } `positional-args:"yes"`
kesavand8ec4fc02021-01-27 09:10:22 -0500285}
kesavand3e2f9f62021-04-22 11:06:38 +0530286
287type OnuDownloadImage struct {
288 Args struct {
289 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
290 Url string `positional-arg-name:"IMAGE_URL" required:"yes"`
ssiddiqui7bc89e92021-05-20 20:58:02 +0530291 Vendor string `positional-arg-name:"IMAGE_VENDOR"`
kesavand3e2f9f62021-04-22 11:06:38 +0530292 ActivateOnSuccess bool `positional-arg-name:"IMAGE_ACTIVATE_ON_SUCCESS"`
293 CommitOnSuccess bool `positional-arg-name:"IMAGE_COMMIT_ON_SUCCESS"`
294 Crc uint32 `positional-arg-name:"IMAGE_CRC"`
295 IDs []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
296 } `positional-args:"yes"`
297}
298
299type OnuActivateImage struct {
300 Args struct {
301 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
302 CommitOnSuccess bool `positional-arg-name:"IMAGE_COMMIT_ON_SUCCESS"`
303 IDs []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
304 } `positional-args:"yes"`
305}
306
307type OnuAbortUpgradeImage struct {
308 Args struct {
309 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
310 IDs []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
311 } `positional-args:"yes"`
312}
313
314type OnuCommitImage struct {
315 Args struct {
316 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
317 IDs []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
318 } `positional-args:"yes"`
319}
320
321type OnuImageStatus struct {
322 ListOutputOptions
323 Args struct {
324 ImageVersion string `positional-arg-name:"IMAGE_VERSION" required:"yes"`
325 IDs []DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
326 } `positional-args:"yes"`
327}
328
329type OnuListImages struct {
330 ListOutputOptions
331 Args struct {
332 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
333 } `positional-args:"yes"`
334}
335
kesavand8ec4fc02021-01-27 09:10:22 -0500336type DeviceGetPortStats struct {
337 ListOutputOptions
338 Args struct {
339 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
340 PortNo uint32 `positional-arg-name:"PORT_NO" required:"yes"`
341 PortType string `positional-arg-name:"PORT_TYPE" required:"yes"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100342 } `positional-args:"yes"`
343}
kesavand6d1131f2021-02-05 22:38:15 +0530344type UniStatus struct {
345 ListOutputOptions
346 Args struct {
347 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
348 UniIndex uint32 `positional-arg-name:"UNI_INDEX" required:"yes"`
349 } `positional-args:"yes"`
350}
Girish Gowdra4f5ce7c2021-04-29 18:53:21 -0700351type OnuPonOpticalInfo struct {
352 ListOutputOptions
353 Args struct {
354 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
355 } `positional-args:"yes"`
356}
Himani Chawla40acc122021-05-26 18:52:29 +0530357
358type GetOnuStats struct {
359 ListOutputOptions
360 Args struct {
361 OltId DeviceId `positional-arg-name:"OLT_DEVICE_ID" required:"yes"`
362 IntfId uint32 `positional-arg-name:"PON_INTF_ID" required:"yes"`
363 OnuId uint32 `positional-arg-name:"ONU_ID" required:"yes"`
364 } `positional-args:"yes"`
365}
366
Gamze Abakac857a462021-05-26 13:45:54 +0000367type RxPower struct {
368 ListOutputOptions
369 Args struct {
370 Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
371 PortNo uint32 `positional-arg-name:"PORT_NO" required:"yes"`
372 OnuNo uint32 `positional-arg-name:"ONU_NO" required:"yes"`
373 } `positional-args:"yes"`
374}
375
Zack Williamse940c7a2019-08-21 14:25:39 -0700376type DeviceOpts struct {
Himani Chawla3c161c62021-05-13 16:36:51 +0530377 List DeviceList `command:"list"`
378 Create DeviceCreate `command:"create"`
379 Delete DeviceDelete `command:"delete"`
380 Enable DeviceEnable `command:"enable"`
381 Disable DeviceDisable `command:"disable"`
382 Flows DeviceFlowList `command:"flows"`
383 Groups DeviceFlowGroupList `command:"groups"`
kesavand12cd8eb2020-01-20 22:25:22 -0500384 Port struct {
385 List DevicePortList `command:"list"`
386 Enable DevicePortEnable `command:"enable"`
387 Disable DevicePortDisable `command:"disable"`
388 } `command:"port"`
389 Inspect DeviceInspect `command:"inspect"`
390 Reboot DeviceReboot `command:"reboot"`
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800391 Value struct {
392 Get DeviceGetExtValue `command:"get"`
393 } `command:"value"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000394 PmConfig struct {
Rohan Agrawald7df3772020-06-29 11:23:36 +0000395 Get DevicePmConfigsGet `command:"get"`
396 MaxSkew struct {
397 Set DevicePmConfigSetMaxSkew `command:"set"`
398 } `command:"maxskew"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000399 Frequency struct {
400 Set DevicePmConfigFrequencySet `command:"set"`
401 } `command:"frequency"`
402 Metric struct {
403 List DevicePmConfigMetricList `command:"list"`
404 Enable DevicePmConfigMetricEnable `command:"enable"`
405 Disable DevicePmConfigMetricDisable `command:"disable"`
406 } `command:"metric"`
407 Group struct {
Girish Gowdra610acb42021-01-27 13:33:57 -0800408 List DevicePmConfigGroupList `command:"list"`
409 Enable DevicePmConfigGroupEnable `command:"enable"`
410 Disable DevicePmConfigGroupDisable `command:"disable"`
411 Set DevicePmConfigGroupFrequencySet `command:"set"`
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000412 } `command:"group"`
413 GroupMetric struct {
414 List DevicePmConfigGroupMetricList `command:"list"`
415 } `command:"groupmetric"`
416 } `command:"pmconfig"`
Andrea Campanella791d88b2021-01-08 13:29:00 +0100417 Image struct {
418 Get DeviceOnuListImages `command:"list"`
419 Download DeviceOnuDownloadImage `command:"download"`
420 Activate DeviceOnuActivateImageUpdate `command:"activate"`
421 } `command:"image"`
kesavand3e2f9f62021-04-22 11:06:38 +0530422 DownloadImage struct {
423 Download OnuDownloadImage `command:"download"`
424 Activate OnuActivateImage `command:"activate"`
425 Commit OnuCommitImage `command:"commit"`
426 AbortUpgrade OnuAbortUpgradeImage `command:"abort"`
427 Status OnuImageStatus `command:"status"`
428 List OnuListImages `command:"list" `
429 } `command:"onuimage"`
kesavand8ec4fc02021-01-27 09:10:22 -0500430 GetExtVal struct {
Girish Gowdra4f5ce7c2021-04-29 18:53:21 -0700431 Stats DeviceGetPortStats `command:"portstats"`
432 UniStatus UniStatus `command:"unistatus"`
433 OpticalInfo OnuPonOpticalInfo `command:"onu_pon_optical_info"`
Himani Chawla40acc122021-05-26 18:52:29 +0530434 OnuStats GetOnuStats `command:"onu_stats"`
Gamze Abakac857a462021-05-26 13:45:54 +0000435 RxPower RxPower `command:"rxpower"`
kesavand8ec4fc02021-01-27 09:10:22 -0500436 } `command:"getextval"`
Zack Williamse940c7a2019-08-21 14:25:39 -0700437}
438
439var deviceOpts = DeviceOpts{}
440
441func RegisterDeviceCommands(parser *flags.Parser) {
David Bainbridge12f036f2019-10-15 22:09:04 +0000442 if _, err := parser.AddCommand("device", "device commands", "Commands to query and manipulate VOLTHA devices", &deviceOpts); err != nil {
David Bainbridgea6722342019-10-24 23:55:53 +0000443 Error.Fatalf("Unexpected error while attempting to register device commands : %s", err)
David Bainbridge12f036f2019-10-15 22:09:04 +0000444 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700445}
446
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000447func (i *MetricName) Complete(match string) []flags.Completion {
448 conn, err := NewConnection()
449 if err != nil {
450 return nil
451 }
452 defer conn.Close()
453
454 client := voltha.NewVolthaServiceClient(conn)
455
456 var deviceId string
457found:
458 for i := len(os.Args) - 1; i >= 0; i -= 1 {
459 switch os.Args[i] {
460 case "enable":
461 fallthrough
462 case "disable":
463 if len(os.Args) > i+1 {
464 deviceId = os.Args[i+1]
465 } else {
466 return nil
467 }
468 break found
469 default:
470 }
471 }
472
473 if len(deviceId) == 0 {
474 return nil
475 }
476
David K. Bainbridge9189c632021-03-26 21:52:21 +0000477 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000478 defer cancel()
479
480 id := voltha.ID{Id: string(deviceId)}
481
482 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
483
484 if err != nil {
485 return nil
486 }
487
488 list := make([]flags.Completion, 0)
489 for _, metrics := range pmconfigs.Metrics {
490 if strings.HasPrefix(metrics.Name, match) {
491 list = append(list, flags.Completion{Item: metrics.Name})
492 }
493 }
494
495 return list
496}
497
498func (i *GroupName) Complete(match string) []flags.Completion {
499 conn, err := NewConnection()
500 if err != nil {
501 return nil
502 }
503 defer conn.Close()
504
505 client := voltha.NewVolthaServiceClient(conn)
506
507 var deviceId string
508found:
509 for i := len(os.Args) - 1; i >= 0; i -= 1 {
510 switch os.Args[i] {
511 case "list":
512 fallthrough
513 case "enable":
514 fallthrough
515 case "disable":
516 if len(os.Args) > i+1 {
517 deviceId = os.Args[i+1]
518 } else {
519 return nil
520 }
521 break found
522 default:
523 }
524 }
525
526 if len(deviceId) == 0 {
527 return nil
528 }
529
David K. Bainbridge9189c632021-03-26 21:52:21 +0000530 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +0000531 defer cancel()
532
533 id := voltha.ID{Id: string(deviceId)}
534
535 pmconfigs, err := client.ListDevicePmConfigs(ctx, &id)
536
537 if err != nil {
538 return nil
539 }
540
541 list := make([]flags.Completion, 0)
542 for _, group := range pmconfigs.Groups {
543 if strings.HasPrefix(group.GroupName, match) {
544 list = append(list, flags.Completion{Item: group.GroupName})
545 }
546 }
547 return list
548}
549
kesavand12cd8eb2020-01-20 22:25:22 -0500550func (i *PortNum) Complete(match string) []flags.Completion {
551 conn, err := NewConnection()
552 if err != nil {
553 return nil
554 }
555 defer conn.Close()
556
Scott Baker9173ed82020-05-19 08:30:12 -0700557 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500558
559 /*
560 * The command line args when completing for PortNum will be a DeviceId
561 * followed by one or more PortNums. So walk the argument list from the
562 * end and find the first argument that is enable/disable as those are
563 * the subcommands that come before the positional arguments. It would
564 * be nice if this package gave us the list of optional arguments
565 * already parsed.
566 */
567 var deviceId string
568found:
569 for i := len(os.Args) - 1; i >= 0; i -= 1 {
570 switch os.Args[i] {
571 case "enable":
572 fallthrough
573 case "disable":
574 if len(os.Args) > i+1 {
575 deviceId = os.Args[i+1]
576 } else {
577 return nil
578 }
579 break found
580 default:
581 }
582 }
583
584 if len(deviceId) == 0 {
585 return nil
586 }
587
David K. Bainbridge9189c632021-03-26 21:52:21 +0000588 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
kesavand12cd8eb2020-01-20 22:25:22 -0500589 defer cancel()
kesavand12cd8eb2020-01-20 22:25:22 -0500590
Scott Baker9173ed82020-05-19 08:30:12 -0700591 id := voltha.ID{Id: string(deviceId)}
kesavand12cd8eb2020-01-20 22:25:22 -0500592
Scott Baker9173ed82020-05-19 08:30:12 -0700593 ports, err := client.ListDevicePorts(ctx, &id)
kesavand12cd8eb2020-01-20 22:25:22 -0500594 if err != nil {
595 return nil
596 }
597
598 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700599 for _, item := range ports.Items {
600 pn := strconv.FormatUint(uint64(item.PortNo), 10)
kesavand12cd8eb2020-01-20 22:25:22 -0500601 if strings.HasPrefix(pn, match) {
602 list = append(list, flags.Completion{Item: pn})
603 }
604 }
605
606 return list
607}
608
Zack Williamse940c7a2019-08-21 14:25:39 -0700609func (i *DeviceId) Complete(match string) []flags.Completion {
610 conn, err := NewConnection()
611 if err != nil {
612 return nil
613 }
614 defer conn.Close()
615
Scott Baker9173ed82020-05-19 08:30:12 -0700616 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700617
David K. Bainbridge9189c632021-03-26 21:52:21 +0000618 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700619 defer cancel()
620
Scott Baker9173ed82020-05-19 08:30:12 -0700621 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700622 if err != nil {
623 return nil
624 }
625
626 list := make([]flags.Completion, 0)
Scott Baker9173ed82020-05-19 08:30:12 -0700627 for _, item := range devices.Items {
628 if strings.HasPrefix(item.Id, match) {
629 list = append(list, flags.Completion{Item: item.Id})
Zack Williamse940c7a2019-08-21 14:25:39 -0700630 }
631 }
632
633 return list
634}
635
636func (options *DeviceList) Execute(args []string) error {
637
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 K. Bainbridge9189c632021-03-26 21:52:21 +0000646 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700647 defer cancel()
648
Scott Baker9173ed82020-05-19 08:30:12 -0700649 devices, err := client.ListDevices(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700650 if err != nil {
651 return err
652 }
653
654 outputFormat := CharReplacer.Replace(options.Format)
655 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000656 outputFormat = GetCommandOptionWithDefault("device-list", "format", DEFAULT_DEVICE_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700657 }
658 if options.Quiet {
659 outputFormat = "{{.Id}}"
660 }
661
David Bainbridgea6722342019-10-24 23:55:53 +0000662 orderBy := options.OrderBy
663 if orderBy == "" {
664 orderBy = GetCommandOptionWithDefault("device-list", "order", "")
665 }
666
Scott Baker9173ed82020-05-19 08:30:12 -0700667 // Make sure json output prints an empty list, not "null"
668 if devices.Items == nil {
669 devices.Items = make([]*voltha.Device, 0)
Zack Williamse940c7a2019-08-21 14:25:39 -0700670 }
671
672 result := CommandResult{
673 Format: format.Format(outputFormat),
674 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000675 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700676 OutputAs: toOutputType(options.OutputAs),
677 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700678 Data: devices.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700679 }
680
681 GenerateOutput(&result)
682 return nil
683}
684
685func (options *DeviceCreate) Execute(args []string) error {
686
Scott Baker9173ed82020-05-19 08:30:12 -0700687 device := voltha.Device{}
Zack Williamse940c7a2019-08-21 14:25:39 -0700688 if options.HostAndPort != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700689 device.Address = &voltha.Device_HostAndPort{HostAndPort: options.HostAndPort}
Zack Williamse940c7a2019-08-21 14:25:39 -0700690 } else if options.IPAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700691 device.Address = &voltha.Device_Ipv4Address{Ipv4Address: options.IPAddress}
Hardik Windlassce1de342020-02-04 21:58:07 +0000692 }
693 if options.MACAddress != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700694 device.MacAddress = strings.ToLower(options.MACAddress)
Zack Williamse940c7a2019-08-21 14:25:39 -0700695 }
696 if options.DeviceType != "" {
Scott Baker9173ed82020-05-19 08:30:12 -0700697 device.Type = options.DeviceType
Zack Williamse940c7a2019-08-21 14:25:39 -0700698 }
699
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 K. Bainbridge9189c632021-03-26 21:52:21 +0000708 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700709 defer cancel()
710
Scott Baker9173ed82020-05-19 08:30:12 -0700711 createdDevice, err := client.CreateDevice(ctx, &device)
Zack Williamse940c7a2019-08-21 14:25:39 -0700712 if err != nil {
713 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700714 }
715
Scott Baker9173ed82020-05-19 08:30:12 -0700716 fmt.Printf("%s\n", createdDevice.Id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700717
718 return nil
719}
720
721func (options *DeviceDelete) Execute(args []string) error {
722
723 conn, err := NewConnection()
724 if err != nil {
725 return err
726 }
727 defer conn.Close()
728
Scott Baker9173ed82020-05-19 08:30:12 -0700729 client := voltha.NewVolthaServiceClient(conn)
David Bainbridge7052fe82020-03-25 10:37:00 -0700730 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700731 for _, i := range options.Args.Ids {
David K. Bainbridge9189c632021-03-26 21:52:21 +0000732 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700733 defer cancel()
734
Scott Baker9173ed82020-05-19 08:30:12 -0700735 id := voltha.ID{Id: string(i)}
Himani Chawla9933ddc2020-10-12 23:53:27 +0530736 if options.Force {
737 _, err = client.ForceDeleteDevice(ctx, &id)
738 } else {
739 _, err = client.DeleteDevice(ctx, &id)
740 }
Scott Baker9173ed82020-05-19 08:30:12 -0700741
Zack Williamse940c7a2019-08-21 14:25:39 -0700742 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000743 Error.Printf("Error while deleting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700744 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700745 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700746 }
747 fmt.Printf("%s\n", i)
748 }
749
David Bainbridge7052fe82020-03-25 10:37:00 -0700750 if lastErr != nil {
751 return NoReportErr
752 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700753 return nil
754}
755
756func (options *DeviceEnable) Execute(args []string) error {
757 conn, err := NewConnection()
758 if err != nil {
759 return err
760 }
761 defer conn.Close()
762
Scott Baker9173ed82020-05-19 08:30:12 -0700763 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700764
David Bainbridge7052fe82020-03-25 10:37:00 -0700765 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700766 for _, i := range options.Args.Ids {
David K. Bainbridge9189c632021-03-26 21:52:21 +0000767 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700768 defer cancel()
769
Scott Baker9173ed82020-05-19 08:30:12 -0700770 id := voltha.ID{Id: string(i)}
771
772 _, err := client.EnableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700773 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000774 Error.Printf("Error while enabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700775 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700776 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700777 }
778 fmt.Printf("%s\n", i)
779 }
780
David Bainbridge7052fe82020-03-25 10:37:00 -0700781 if lastErr != nil {
782 return NoReportErr
783 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700784 return nil
785}
786
787func (options *DeviceDisable) Execute(args []string) error {
788 conn, err := NewConnection()
789 if err != nil {
790 return err
791 }
792 defer conn.Close()
793
Scott Baker9173ed82020-05-19 08:30:12 -0700794 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700795
David Bainbridge7052fe82020-03-25 10:37:00 -0700796 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700797 for _, i := range options.Args.Ids {
David K. Bainbridge9189c632021-03-26 21:52:21 +0000798 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700799 defer cancel()
800
Scott Baker9173ed82020-05-19 08:30:12 -0700801 id := voltha.ID{Id: string(i)}
802
803 _, err := client.DisableDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700804 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000805 Error.Printf("Error while disabling '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700806 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700807 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700808 }
809 fmt.Printf("%s\n", i)
810 }
811
David Bainbridge7052fe82020-03-25 10:37:00 -0700812 if lastErr != nil {
813 return NoReportErr
814 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700815 return nil
816}
817
818func (options *DeviceReboot) Execute(args []string) error {
819 conn, err := NewConnection()
820 if err != nil {
821 return err
822 }
823 defer conn.Close()
824
Scott Baker9173ed82020-05-19 08:30:12 -0700825 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700826
David Bainbridge7052fe82020-03-25 10:37:00 -0700827 var lastErr error
Zack Williamse940c7a2019-08-21 14:25:39 -0700828 for _, i := range options.Args.Ids {
David K. Bainbridge9189c632021-03-26 21:52:21 +0000829 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700830 defer cancel()
831
Scott Baker9173ed82020-05-19 08:30:12 -0700832 id := voltha.ID{Id: string(i)}
833
834 _, err := client.RebootDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700835 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +0000836 Error.Printf("Error while rebooting '%s': %s\n", i, err)
David Bainbridge7052fe82020-03-25 10:37:00 -0700837 lastErr = err
Zack Williamse940c7a2019-08-21 14:25:39 -0700838 continue
Zack Williamse940c7a2019-08-21 14:25:39 -0700839 }
840 fmt.Printf("%s\n", i)
841 }
842
David Bainbridge7052fe82020-03-25 10:37:00 -0700843 if lastErr != nil {
844 return NoReportErr
845 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700846 return nil
847}
848
849func (options *DevicePortList) Execute(args []string) error {
850
851 conn, err := NewConnection()
852 if err != nil {
853 return err
854 }
855 defer conn.Close()
856
Scott Baker9173ed82020-05-19 08:30:12 -0700857 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700858
David K. Bainbridge9189c632021-03-26 21:52:21 +0000859 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700860 defer cancel()
861
Scott Baker9173ed82020-05-19 08:30:12 -0700862 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700863
Scott Baker9173ed82020-05-19 08:30:12 -0700864 ports, err := client.ListDevicePorts(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700865 if err != nil {
866 return err
867 }
868
869 outputFormat := CharReplacer.Replace(options.Format)
870 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000871 outputFormat = GetCommandOptionWithDefault("device-ports", "format", DEFAULT_DEVICE_PORTS_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700872 }
Zack Williamse940c7a2019-08-21 14:25:39 -0700873
David Bainbridgea6722342019-10-24 23:55:53 +0000874 orderBy := options.OrderBy
875 if orderBy == "" {
876 orderBy = GetCommandOptionWithDefault("device-ports", "order", "")
877 }
878
Zack Williamse940c7a2019-08-21 14:25:39 -0700879 result := CommandResult{
880 Format: format.Format(outputFormat),
881 Filter: options.Filter,
David Bainbridgea6722342019-10-24 23:55:53 +0000882 OrderBy: orderBy,
Zack Williamse940c7a2019-08-21 14:25:39 -0700883 OutputAs: toOutputType(options.OutputAs),
884 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -0700885 Data: ports.Items,
Zack Williamse940c7a2019-08-21 14:25:39 -0700886 }
887
888 GenerateOutput(&result)
889 return nil
890}
891
892func (options *DeviceFlowList) Execute(args []string) error {
893 fl := &FlowList{}
894 fl.ListOutputOptions = options.ListOutputOptions
Maninder045921e2020-09-29 16:46:02 +0530895 fl.FlowIdOptions = options.FlowIdOptions
Zack Williamse940c7a2019-08-21 14:25:39 -0700896 fl.Args.Id = string(options.Args.Id)
David Bainbridgea6722342019-10-24 23:55:53 +0000897 fl.Method = "device-flows"
Zack Williamse940c7a2019-08-21 14:25:39 -0700898 return fl.Execute(args)
899}
900
Himani Chawla3c161c62021-05-13 16:36:51 +0530901func (options *DeviceFlowGroupList) Execute(args []string) error {
902 grp := &GroupList{}
903 grp.ListOutputOptions = options.ListOutputOptions
904 grp.GroupListOptions = options.GroupListOptions
905 grp.Args.Id = string(options.Args.Id)
906 grp.Method = "device-groups"
907 return grp.Execute(args)
908}
909
Zack Williamse940c7a2019-08-21 14:25:39 -0700910func (options *DeviceInspect) Execute(args []string) error {
911 if len(args) > 0 {
912 return fmt.Errorf("only a single argument 'DEVICE_ID' can be provided")
913 }
914
915 conn, err := NewConnection()
916 if err != nil {
917 return err
918 }
919 defer conn.Close()
920
Scott Baker9173ed82020-05-19 08:30:12 -0700921 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700922
David K. Bainbridge9189c632021-03-26 21:52:21 +0000923 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700924 defer cancel()
925
Scott Baker9173ed82020-05-19 08:30:12 -0700926 id := voltha.ID{Id: string(options.Args.Id)}
Zack Williamse940c7a2019-08-21 14:25:39 -0700927
Scott Baker9173ed82020-05-19 08:30:12 -0700928 device, err := client.GetDevice(ctx, &id)
Zack Williamse940c7a2019-08-21 14:25:39 -0700929 if err != nil {
930 return err
931 }
932
Zack Williamse940c7a2019-08-21 14:25:39 -0700933 outputFormat := CharReplacer.Replace(options.Format)
934 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000935 outputFormat = GetCommandOptionWithDefault("device-inspect", "format", DEFAULT_DEVICE_INSPECT_FORMAT)
Zack Williamse940c7a2019-08-21 14:25:39 -0700936 }
937 if options.Quiet {
938 outputFormat = "{{.Id}}"
939 }
940
941 result := CommandResult{
942 Format: format.Format(outputFormat),
943 OutputAs: toOutputType(options.OutputAs),
944 NameLimit: options.NameLimit,
945 Data: device,
946 }
947 GenerateOutput(&result)
948 return nil
949}
kesavand12cd8eb2020-01-20 22:25:22 -0500950
951/*Device Port Enable */
952func (options *DevicePortEnable) Execute(args []string) error {
953 conn, err := NewConnection()
954 if err != nil {
955 return err
956 }
957 defer conn.Close()
958
Scott Baker9173ed82020-05-19 08:30:12 -0700959 client := voltha.NewVolthaServiceClient(conn)
kesavand12cd8eb2020-01-20 22:25:22 -0500960
David K. Bainbridge9189c632021-03-26 21:52:21 +0000961 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
kesavand12cd8eb2020-01-20 22:25:22 -0500962 defer cancel()
963
Scott Baker9173ed82020-05-19 08:30:12 -0700964 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
965
966 _, err = client.EnablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500967 if err != nil {
968 Error.Printf("Error enabling port number %v on device Id %s,err=%s\n", options.Args.PortId, options.Args.Id, ErrorToString(err))
969 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500970 }
971
972 return nil
973}
974
Scott Baker9173ed82020-05-19 08:30:12 -0700975/*Device Port Disable */
kesavand12cd8eb2020-01-20 22:25:22 -0500976func (options *DevicePortDisable) Execute(args []string) error {
977 conn, err := NewConnection()
978 if err != nil {
979 return err
980 }
981 defer conn.Close()
982
Scott Baker9173ed82020-05-19 08:30:12 -0700983 client := voltha.NewVolthaServiceClient(conn)
984
David K. Bainbridge9189c632021-03-26 21:52:21 +0000985 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
kesavand12cd8eb2020-01-20 22:25:22 -0500986 defer cancel()
987
Scott Baker9173ed82020-05-19 08:30:12 -0700988 port := voltha.Port{DeviceId: string(options.Args.Id), PortNo: uint32(options.Args.PortId)}
989
990 _, err = client.DisablePort(ctx, &port)
kesavand12cd8eb2020-01-20 22:25:22 -0500991 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700992 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 -0500993 return err
kesavand12cd8eb2020-01-20 22:25:22 -0500994 }
Scott Baker9173ed82020-05-19 08:30:12 -0700995
kesavand12cd8eb2020-01-20 22:25:22 -0500996 return nil
997}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -0800998
Rohan Agrawald7df3772020-06-29 11:23:36 +0000999func (options *DevicePmConfigSetMaxSkew) Execute(args []string) error {
1000 conn, err := NewConnection()
1001 if err != nil {
1002 return err
1003 }
1004 defer conn.Close()
1005
1006 client := voltha.NewVolthaServiceClient(conn)
1007
David K. Bainbridge9189c632021-03-26 21:52:21 +00001008 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawald7df3772020-06-29 11:23:36 +00001009 defer cancel()
1010
1011 id := voltha.ID{Id: string(options.Args.Id)}
1012
1013 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1014 if err != nil {
1015 return err
1016 }
1017
1018 pmConfigs.MaxSkew = options.Args.MaxSkew
1019
1020 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1021 if err != nil {
1022 return err
1023 }
1024
1025 return nil
1026}
1027
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001028func (options *DevicePmConfigsGet) Execute(args []string) error {
1029
1030 conn, err := NewConnection()
1031 if err != nil {
1032 return err
1033 }
1034 defer conn.Close()
1035
1036 client := voltha.NewVolthaServiceClient(conn)
1037
David K. Bainbridge9189c632021-03-26 21:52:21 +00001038 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001039 defer cancel()
1040
1041 id := voltha.ID{Id: string(options.Args.Id)}
1042
1043 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1044 if err != nil {
1045 return err
1046 }
1047
1048 outputFormat := CharReplacer.Replace(options.Format)
1049 if outputFormat == "" {
1050 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
1051 }
1052
1053 orderBy := options.OrderBy
1054 if orderBy == "" {
1055 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1056 }
1057
1058 result := CommandResult{
1059 Format: format.Format(outputFormat),
1060 Filter: options.Filter,
1061 OrderBy: orderBy,
1062 OutputAs: toOutputType(options.OutputAs),
1063 NameLimit: options.NameLimit,
1064 Data: pmConfigs,
1065 }
1066
1067 GenerateOutput(&result)
1068 return nil
1069
1070}
1071
1072func (options *DevicePmConfigMetricList) Execute(args []string) error {
1073
1074 conn, err := NewConnection()
1075 if err != nil {
1076 return err
1077 }
1078 defer conn.Close()
1079
1080 client := voltha.NewVolthaServiceClient(conn)
1081
David K. Bainbridge9189c632021-03-26 21:52:21 +00001082 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001083 defer cancel()
1084
1085 id := voltha.ID{Id: string(options.Args.Id)}
1086
1087 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1088 if err != nil {
1089 return err
1090 }
1091
1092 if !pmConfigs.Grouped {
1093 for _, metric := range pmConfigs.Metrics {
1094 if metric.SampleFreq == 0 {
1095 metric.SampleFreq = pmConfigs.DefaultFreq
1096 }
1097 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001098 outputFormat := CharReplacer.Replace(options.Format)
1099 if outputFormat == "" {
1100 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
1101 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001102
Rohan Agrawalbca69122020-06-17 14:59:03 +00001103 orderBy := options.OrderBy
1104 if orderBy == "" {
1105 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1106 }
1107
1108 result := CommandResult{
1109 Format: format.Format(outputFormat),
1110 Filter: options.Filter,
1111 OrderBy: orderBy,
1112 OutputAs: toOutputType(options.OutputAs),
1113 NameLimit: options.NameLimit,
1114 Data: pmConfigs.Metrics,
1115 }
1116
1117 GenerateOutput(&result)
1118 return nil
1119 } else {
1120 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001121 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001122}
1123
1124func (options *DevicePmConfigMetricEnable) Execute(args []string) error {
1125
1126 conn, err := NewConnection()
1127 if err != nil {
1128 return err
1129 }
1130 defer conn.Close()
1131
1132 client := voltha.NewVolthaServiceClient(conn)
1133
David K. Bainbridge9189c632021-03-26 21:52:21 +00001134 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001135 defer cancel()
1136
1137 id := voltha.ID{Id: string(options.Args.Id)}
1138
1139 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1140 if err != nil {
1141 return err
1142 }
1143
1144 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001145 metrics := make(map[string]struct{})
1146 for _, metric := range pmConfigs.Metrics {
1147 metrics[metric.Name] = struct{}{}
1148 }
1149
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001150 for _, metric := range pmConfigs.Metrics {
1151 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001152 if _, exist := metrics[string(mName)]; !exist {
1153 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1154 }
1155
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001156 if string(mName) == metric.Name && !metric.Enabled {
1157 metric.Enabled = true
1158 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1159 if err != nil {
1160 return err
1161 }
1162 }
1163 }
1164 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001165 } else {
1166 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001167 }
1168 return nil
1169}
1170
1171func (options *DevicePmConfigMetricDisable) Execute(args []string) error {
1172
1173 conn, err := NewConnection()
1174 if err != nil {
1175 return err
1176 }
1177 defer conn.Close()
1178
1179 client := voltha.NewVolthaServiceClient(conn)
1180
David K. Bainbridge9189c632021-03-26 21:52:21 +00001181 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001182 defer cancel()
1183
1184 id := voltha.ID{Id: string(options.Args.Id)}
1185
1186 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1187 if err != nil {
1188 return err
1189 }
1190
1191 if !pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001192 metrics := make(map[string]struct{})
1193 for _, metric := range pmConfigs.Metrics {
1194 metrics[metric.Name] = struct{}{}
1195 }
1196
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001197 for _, metric := range pmConfigs.Metrics {
1198 for _, mName := range options.Args.Metrics {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001199 if _, have := metrics[string(mName)]; !have {
1200 return fmt.Errorf("Metric Name '%s' does not exist", mName)
1201 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001202 if string(mName) == metric.Name && metric.Enabled {
1203 metric.Enabled = false
1204 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1205 if err != nil {
1206 return err
1207 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001208 } else {
1209 return fmt.Errorf("Metric '%s' cannot be disabled", string(mName))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001210 }
1211 }
1212 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001213 } else {
1214 return fmt.Errorf("Device '%s' does not have Non Grouped Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001215 }
1216 return nil
1217}
1218
1219func (options *DevicePmConfigGroupEnable) Execute(args []string) error {
1220
1221 conn, err := NewConnection()
1222 if err != nil {
1223 return err
1224 }
1225 defer conn.Close()
1226
1227 client := voltha.NewVolthaServiceClient(conn)
1228
David K. Bainbridge9189c632021-03-26 21:52:21 +00001229 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001230 defer cancel()
1231
1232 id := voltha.ID{Id: string(options.Args.Id)}
1233
1234 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1235 if err != nil {
1236 return err
1237 }
1238
1239 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001240 groups := make(map[string]struct{})
1241 for _, group := range pmConfigs.Groups {
1242 groups[group.GroupName] = struct{}{}
1243 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001244 for _, group := range pmConfigs.Groups {
Girish Gowdra610acb42021-01-27 13:33:57 -08001245 if _, have := groups[string(options.Args.Group)]; !have {
1246 return fmt.Errorf("Group Name '%s' does not exist", options.Args.Group)
1247 }
1248 if string(options.Args.Group) == group.GroupName && !group.Enabled {
1249 group.Enabled = true
1250 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1251 if err != nil {
1252 return err
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001253 }
1254 }
1255 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001256 } else {
1257 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001258 }
1259 return nil
1260}
1261
1262func (options *DevicePmConfigGroupDisable) Execute(args []string) error {
1263
1264 conn, err := NewConnection()
1265 if err != nil {
1266 return err
1267 }
1268 defer conn.Close()
1269
1270 client := voltha.NewVolthaServiceClient(conn)
1271
David K. Bainbridge9189c632021-03-26 21:52:21 +00001272 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001273 defer cancel()
1274
1275 id := voltha.ID{Id: string(options.Args.Id)}
1276
1277 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1278 if err != nil {
1279 return err
1280 }
1281
1282 if pmConfigs.Grouped {
Rohan Agrawalbca69122020-06-17 14:59:03 +00001283 groups := make(map[string]struct{})
1284 for _, group := range pmConfigs.Groups {
1285 groups[group.GroupName] = struct{}{}
1286 }
1287
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001288 for _, group := range pmConfigs.Groups {
Girish Gowdra610acb42021-01-27 13:33:57 -08001289 if _, have := groups[string(options.Args.Group)]; !have {
1290 return fmt.Errorf("Group Name '%s' does not exist", options.Args.Group)
1291 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001292
Girish Gowdra610acb42021-01-27 13:33:57 -08001293 if string(options.Args.Group) == group.GroupName && group.Enabled {
1294 group.Enabled = false
1295 _, err := client.UpdateDevicePmConfigs(ctx, pmConfigs)
1296 if err != nil {
1297 return err
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001298 }
1299 }
1300 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001301 } else {
1302 return fmt.Errorf("Device '%s' does not have Group Metrics", options.Args.Id)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001303 }
1304 return nil
1305}
1306
Girish Gowdra610acb42021-01-27 13:33:57 -08001307func (options *DevicePmConfigGroupFrequencySet) Execute(args []string) error {
1308
1309 conn, err := NewConnection()
1310 if err != nil {
1311 return err
1312 }
1313 defer conn.Close()
1314
1315 client := voltha.NewVolthaServiceClient(conn)
1316
David K. Bainbridge9189c632021-03-26 21:52:21 +00001317 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Girish Gowdra610acb42021-01-27 13:33:57 -08001318 defer cancel()
1319
1320 id := voltha.ID{Id: string(options.Args.Id)}
1321
1322 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1323 if err != nil {
1324 return err
1325 }
1326
1327 if pmConfigs.Grouped {
1328 groups := make(map[string]struct{})
1329 for _, group := range pmConfigs.Groups {
1330 groups[group.GroupName] = struct{}{}
1331 }
1332
1333 for _, group := range pmConfigs.Groups {
1334 if _, have := groups[string(options.Args.Group)]; !have {
1335 return fmt.Errorf("group name '%s' does not exist", options.Args.Group)
1336 }
1337
1338 if string(options.Args.Group) == group.GroupName {
1339 if !group.Enabled {
1340 return fmt.Errorf("group '%s' is not enabled", options.Args.Group)
1341 }
1342 group.GroupFreq = uint32(options.Args.Interval.Seconds())
1343 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1344 if err != nil {
1345 return err
1346 }
1347 }
1348 }
1349 } else {
1350 return fmt.Errorf("device '%s' does not have group metrics", options.Args.Id)
1351 }
1352 return nil
1353}
1354
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001355func (options *DevicePmConfigGroupList) Execute(args []string) error {
1356
1357 conn, err := NewConnection()
1358 if err != nil {
1359 return err
1360 }
1361 defer conn.Close()
1362
1363 client := voltha.NewVolthaServiceClient(conn)
1364
David K. Bainbridge9189c632021-03-26 21:52:21 +00001365 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001366 defer cancel()
1367
1368 id := voltha.ID{Id: string(options.Args.Id)}
1369
1370 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1371 if err != nil {
1372 return err
1373 }
1374
1375 if pmConfigs.Grouped {
1376 for _, group := range pmConfigs.Groups {
1377 if group.GroupFreq == 0 {
1378 group.GroupFreq = pmConfigs.DefaultFreq
1379 }
1380 }
Rohan Agrawalbca69122020-06-17 14:59:03 +00001381 outputFormat := CharReplacer.Replace(options.Format)
1382 if outputFormat == "" {
1383 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GROUP_LIST_FORMAT)
1384 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001385
Rohan Agrawalbca69122020-06-17 14:59:03 +00001386 orderBy := options.OrderBy
1387 if orderBy == "" {
1388 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1389 }
1390
1391 result := CommandResult{
1392 Format: format.Format(outputFormat),
1393 Filter: options.Filter,
1394 OrderBy: orderBy,
1395 OutputAs: toOutputType(options.OutputAs),
1396 NameLimit: options.NameLimit,
1397 Data: pmConfigs.Groups,
1398 }
1399
1400 GenerateOutput(&result)
1401 } else {
1402 return fmt.Errorf("Device '%s' does not have Group Metrics", string(options.Args.Id))
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001403 }
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001404 return nil
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001405}
1406
1407func (options *DevicePmConfigGroupMetricList) Execute(args []string) error {
1408
1409 var metrics []*voltha.PmConfig
1410 conn, err := NewConnection()
1411 if err != nil {
1412 return err
1413 }
1414 defer conn.Close()
1415
1416 client := voltha.NewVolthaServiceClient(conn)
1417
David K. Bainbridge9189c632021-03-26 21:52:21 +00001418 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001419 defer cancel()
1420
1421 id := voltha.ID{Id: string(options.Args.Id)}
1422
1423 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1424 if err != nil {
1425 return err
1426 }
1427
1428 for _, groups := range pmConfigs.Groups {
1429
1430 if string(options.Args.Group) == groups.GroupName {
1431 for _, metric := range groups.Metrics {
1432 if metric.SampleFreq == 0 && groups.GroupFreq == 0 {
1433 metric.SampleFreq = pmConfigs.DefaultFreq
1434 } else {
1435 metric.SampleFreq = groups.GroupFreq
1436 }
1437 }
1438 metrics = groups.Metrics
1439 }
1440 }
1441
1442 outputFormat := CharReplacer.Replace(options.Format)
1443 if outputFormat == "" {
1444 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_METRIC_LIST_FORMAT)
1445 }
1446
1447 orderBy := options.OrderBy
1448 if orderBy == "" {
1449 orderBy = GetCommandOptionWithDefault("device-pm-configs", "order", "")
1450 }
1451
1452 result := CommandResult{
1453 Format: format.Format(outputFormat),
1454 Filter: options.Filter,
1455 OrderBy: orderBy,
1456 OutputAs: toOutputType(options.OutputAs),
1457 NameLimit: options.NameLimit,
1458 Data: metrics,
1459 }
1460
1461 GenerateOutput(&result)
1462 return nil
1463
1464}
1465
1466func (options *DevicePmConfigFrequencySet) Execute(args []string) error {
1467
1468 conn, err := NewConnection()
1469 if err != nil {
1470 return err
1471 }
1472 defer conn.Close()
1473
1474 client := voltha.NewVolthaServiceClient(conn)
1475
David K. Bainbridge9189c632021-03-26 21:52:21 +00001476 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001477 defer cancel()
1478
1479 id := voltha.ID{Id: string(options.Args.Id)}
1480
1481 pmConfigs, err := client.ListDevicePmConfigs(ctx, &id)
1482 if err != nil {
1483 return err
1484 }
1485
Girish Gowdra610acb42021-01-27 13:33:57 -08001486 pmConfigs.DefaultFreq = uint32(options.Args.Interval.Seconds())
Rohan Agrawal9228d2f2020-06-03 07:48:50 +00001487
1488 _, err = client.UpdateDevicePmConfigs(ctx, pmConfigs)
1489 if err != nil {
1490 return err
1491 }
1492
1493 outputFormat := CharReplacer.Replace(options.Format)
1494 if outputFormat == "" {
1495 outputFormat = GetCommandOptionWithDefault("device-pm-configs", "format", DEFAULT_DEVICE_PM_CONFIG_GET_FORMAT)
1496 }
1497 if options.Quiet {
1498 outputFormat = "{{.Id}}"
1499 }
1500
1501 result := CommandResult{
1502 Format: format.Format(outputFormat),
1503 OutputAs: toOutputType(options.OutputAs),
1504 NameLimit: options.NameLimit,
1505 Data: pmConfigs,
1506 }
1507
1508 GenerateOutput(&result)
1509 return nil
1510
1511}
1512
kesavand3e2f9f62021-04-22 11:06:38 +05301513func (options *OnuDownloadImage) Execute(args []string) error {
1514
1515 conn, err := NewConnection()
1516 if err != nil {
1517 return err
1518 }
1519 defer conn.Close()
1520
1521 client := voltha.NewVolthaServiceClient(conn)
1522
1523 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1524 defer cancel()
1525
1526 var devIDList []*common.ID
1527 for _, i := range options.Args.IDs {
1528
1529 devIDList = append(devIDList, &common.ID{Id: string(i)})
1530 }
1531
1532 downloadImage := voltha.DeviceImageDownloadRequest{
1533 DeviceId: devIDList,
1534 Image: &voltha.Image{
1535 Url: options.Args.Url,
1536 Crc32: options.Args.Crc,
ssiddiqui7bc89e92021-05-20 20:58:02 +05301537 Vendor: options.Args.Vendor,
kesavand3e2f9f62021-04-22 11:06:38 +05301538 Version: options.Args.ImageVersion,
1539 },
1540 ActivateOnSuccess: options.Args.ActivateOnSuccess,
1541 CommitOnSuccess: options.Args.CommitOnSuccess,
1542 }
1543
1544 _, err = client.DownloadImageToDevice(ctx, &downloadImage)
1545 if err != nil {
1546 return err
1547 }
1548
1549 return nil
1550
1551}
1552
1553func (options *OnuActivateImage) Execute(args []string) error {
1554
1555 conn, err := NewConnection()
1556 if err != nil {
1557 return err
1558 }
1559 defer conn.Close()
1560
1561 client := voltha.NewVolthaServiceClient(conn)
1562
1563 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1564 defer cancel()
1565
1566 var devIDList []*common.ID
1567 for _, i := range options.Args.IDs {
1568
1569 devIDList = append(devIDList, &common.ID{Id: string(i)})
1570 }
1571
1572 downloadImage := voltha.DeviceImageRequest{
1573 DeviceId: devIDList,
1574 Version: options.Args.ImageVersion,
1575 CommitOnSuccess: options.Args.CommitOnSuccess,
1576 }
1577
1578 _, err = client.ActivateImage(ctx, &downloadImage)
1579 if err != nil {
1580 return err
1581 }
1582
1583 return nil
1584
1585}
1586
1587func (options *OnuAbortUpgradeImage) Execute(args []string) error {
1588
1589 conn, err := NewConnection()
1590 if err != nil {
1591 return err
1592 }
1593 defer conn.Close()
1594
1595 client := voltha.NewVolthaServiceClient(conn)
1596
1597 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1598 defer cancel()
1599
1600 var devIDList []*common.ID
1601 for _, i := range options.Args.IDs {
1602
1603 devIDList = append(devIDList, &common.ID{Id: string(i)})
1604 }
1605
1606 downloadImage := voltha.DeviceImageRequest{
1607 DeviceId: devIDList,
1608 Version: options.Args.ImageVersion,
1609 }
1610
1611 _, err = client.AbortImageUpgradeToDevice(ctx, &downloadImage)
1612 if err != nil {
1613 return err
1614 }
1615
1616 return nil
1617
1618}
1619
1620func (options *OnuCommitImage) Execute(args []string) error {
1621
1622 conn, err := NewConnection()
1623 if err != nil {
1624 return err
1625 }
1626 defer conn.Close()
1627
1628 client := voltha.NewVolthaServiceClient(conn)
1629
1630 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1631 defer cancel()
1632
1633 var devIDList []*common.ID
1634 for _, i := range options.Args.IDs {
1635
1636 devIDList = append(devIDList, &common.ID{Id: string(i)})
1637 }
1638 downloadImage := voltha.DeviceImageRequest{
1639 DeviceId: devIDList,
1640 Version: options.Args.ImageVersion,
1641 }
1642
1643 _, err = client.CommitImage(ctx, &downloadImage)
1644 if err != nil {
1645 return err
1646 }
1647
1648 return nil
1649
1650}
1651
1652func (options *OnuListImages) Execute(args []string) error {
1653
1654 conn, err := NewConnection()
1655 if err != nil {
1656 return err
1657 }
1658 defer conn.Close()
1659
1660 client := voltha.NewVolthaServiceClient(conn)
1661
1662 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1663 defer cancel()
1664
1665 id := common.ID{Id: string(options.Args.Id)}
1666
1667 onuImages, err := client.GetOnuImages(ctx, &id)
1668 if err != nil {
1669 return err
1670 }
1671
1672 outputFormat := CharReplacer.Replace(options.Format)
1673 if outputFormat == "" {
1674 outputFormat = GetCommandOptionWithDefault("onu-image-list", "format", ONU_IMAGE_LIST_FORMAT)
1675 }
1676
1677 if options.Quiet {
1678 outputFormat = "{{.Id}}"
1679 }
1680
1681 //TODO orderby
1682
1683 // Make sure json output prints an empty list, not "null"
1684 if onuImages.Items == nil {
1685 onuImages.Items = make([]*voltha.OnuImage, 0)
1686 }
1687
1688 result := CommandResult{
1689 Format: format.Format(outputFormat),
1690 OutputAs: toOutputType(options.OutputAs),
1691 NameLimit: options.NameLimit,
1692 Data: onuImages.Items,
1693 }
1694
1695 GenerateOutput(&result)
1696 return nil
1697
1698}
1699
1700func (options *OnuImageStatus) Execute(args []string) error {
1701
1702 conn, err := NewConnection()
1703 if err != nil {
1704 return err
1705 }
1706 defer conn.Close()
1707
1708 client := voltha.NewVolthaServiceClient(conn)
1709
1710 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1711 defer cancel()
1712
1713 var devIDList []*common.ID
1714 for _, i := range options.Args.IDs {
1715
1716 devIDList = append(devIDList, &common.ID{Id: string(i)})
1717 }
1718
1719 imageStatusReq := voltha.DeviceImageRequest{
1720 DeviceId: devIDList,
1721 Version: options.Args.ImageVersion,
1722 }
1723 imageStatus, err := client.GetImageStatus(ctx, &imageStatusReq)
1724 if err != nil {
1725 return err
1726 }
1727
1728 outputFormat := CharReplacer.Replace(options.Format)
1729 if outputFormat == "" {
1730 outputFormat = GetCommandOptionWithDefault("device-image-list", "format", ONU_IMAGE_STATUS_FORMAT)
1731 }
1732
1733 if options.Quiet {
1734 outputFormat = "{{.Id}}"
1735 }
1736
1737 //TODO orderby
1738
1739 // Make sure json output prints an empty list, not "null"
1740 if imageStatus.DeviceImageStates == nil {
1741 imageStatus.DeviceImageStates = make([]*voltha.DeviceImageState, 0)
1742 }
1743
1744 result := CommandResult{
1745 Format: format.Format(outputFormat),
1746 OutputAs: toOutputType(options.OutputAs),
1747 NameLimit: options.NameLimit,
1748 Data: imageStatus.DeviceImageStates,
1749 }
1750
1751 GenerateOutput(&result)
1752 return nil
1753
1754}
1755
Andrea Campanella791d88b2021-01-08 13:29:00 +01001756func (options *DeviceOnuListImages) Execute(args []string) error {
1757
1758 conn, err := NewConnection()
1759 if err != nil {
1760 return err
1761 }
1762 defer conn.Close()
1763
1764 client := voltha.NewVolthaServiceClient(conn)
1765
David K. Bainbridge9189c632021-03-26 21:52:21 +00001766 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Andrea Campanella791d88b2021-01-08 13:29:00 +01001767 defer cancel()
1768
1769 id := common.ID{Id: string(options.Args.Id)}
1770
1771 imageDownloads, err := client.ListImageDownloads(ctx, &id)
1772 if err != nil {
1773 return err
1774 }
1775
1776 outputFormat := CharReplacer.Replace(options.Format)
1777 if outputFormat == "" {
1778 outputFormat = GetCommandOptionWithDefault("device-image-list", "format", DEFAULT_DEVICE_IMAGE_LIST_GET_FORMAT)
1779 }
1780
1781 if options.Quiet {
1782 outputFormat = "{{.Id}}"
1783 }
1784
1785 //TODO orderby
1786
1787 // Make sure json output prints an empty list, not "null"
1788 if imageDownloads.Items == nil {
1789 imageDownloads.Items = make([]*voltha.ImageDownload, 0)
1790 }
1791
1792 result := CommandResult{
1793 Format: format.Format(outputFormat),
1794 OutputAs: toOutputType(options.OutputAs),
1795 NameLimit: options.NameLimit,
1796 Data: imageDownloads.Items,
1797 }
1798
1799 GenerateOutput(&result)
1800 return nil
1801
1802}
1803
1804func (options *DeviceOnuDownloadImage) Execute(args []string) error {
1805
1806 conn, err := NewConnection()
1807 if err != nil {
1808 return err
1809 }
1810 defer conn.Close()
1811
1812 client := voltha.NewVolthaServiceClient(conn)
1813
David K. Bainbridge9189c632021-03-26 21:52:21 +00001814 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Andrea Campanella791d88b2021-01-08 13:29:00 +01001815 defer cancel()
1816
1817 downloadImage := voltha.ImageDownload{
1818 Id: string(options.Args.Id),
1819 Name: options.Args.Name,
1820 Url: options.Args.Url,
1821 Crc: options.Args.Crc,
1822 LocalDir: options.Args.LocalDir,
1823 }
1824
1825 _, err = client.DownloadImage(ctx, &downloadImage)
1826 if err != nil {
1827 return err
1828 }
1829
1830 return nil
1831
1832}
1833
1834func (options *DeviceOnuActivateImageUpdate) Execute(args []string) error {
1835
1836 conn, err := NewConnection()
1837 if err != nil {
1838 return err
1839 }
1840 defer conn.Close()
1841
1842 client := voltha.NewVolthaServiceClient(conn)
1843
David K. Bainbridge9189c632021-03-26 21:52:21 +00001844 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Andrea Campanella791d88b2021-01-08 13:29:00 +01001845 defer cancel()
1846
1847 downloadImage := voltha.ImageDownload{
1848 Id: string(options.Args.Id),
1849 Name: options.Args.Name,
1850 ImageVersion: options.Args.ImageVersion,
1851 SaveConfig: options.Args.SaveConfig,
1852 LocalDir: options.Args.LocalDir,
1853 }
1854
1855 _, err = client.ActivateImageUpdate(ctx, &downloadImage)
1856 if err != nil {
1857 return err
1858 }
1859
1860 return nil
1861
1862}
1863
Scott Baker9173ed82020-05-19 08:30:12 -07001864type ReturnValueRow struct {
1865 Name string `json:"name"`
1866 Result interface{} `json:"result"`
1867}
1868
kesavand8ec4fc02021-01-27 09:10:22 -05001869func (options *DeviceGetPortStats) Execute(args []string) error {
1870 conn, err := NewConnection()
1871 if err != nil {
1872 return err
1873 }
1874 defer conn.Close()
1875 client := extension.NewExtensionClient(conn)
1876 var portType extension.GetOltPortCounters_PortType
1877
1878 if options.Args.PortType == "pon" {
1879 portType = extension.GetOltPortCounters_Port_PON_OLT
1880 } else if options.Args.PortType == "nni" {
1881
1882 portType = extension.GetOltPortCounters_Port_ETHERNET_NNI
1883 } else {
1884 return fmt.Errorf("expected interface type pon/nni, provided %s", options.Args.PortType)
1885 }
1886
1887 singleGetValReq := extension.SingleGetValueRequest{
1888 TargetId: string(options.Args.Id),
1889 Request: &extension.GetValueRequest{
1890 Request: &extension.GetValueRequest_OltPortInfo{
1891 OltPortInfo: &extension.GetOltPortCounters{
1892 PortNo: options.Args.PortNo,
1893 PortType: portType,
1894 },
1895 },
1896 },
1897 }
1898
David K. Bainbridge9189c632021-03-26 21:52:21 +00001899 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
kesavand8ec4fc02021-01-27 09:10:22 -05001900 defer cancel()
1901 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1902 if err != nil {
1903 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1904 return err
1905 }
1906
1907 if rv.Response.Status != extension.GetValueResponse_OK {
1908 return fmt.Errorf("failed to get port stats %v", rv.Response.ErrReason.String())
1909 }
1910
1911 outputFormat := CharReplacer.Replace(options.Format)
1912 if outputFormat == "" {
1913 outputFormat = GetCommandOptionWithDefault("device-get-port-status", "format", DEFAULT_DEVICE_GET_PORT_STATUS_FORMAT)
1914 }
1915
1916 result := CommandResult{
1917 Format: format.Format(outputFormat),
1918 OutputAs: toOutputType(options.OutputAs),
1919 NameLimit: options.NameLimit,
1920 Data: rv.GetResponse().GetPortCoutners(),
1921 }
1922 GenerateOutput(&result)
1923 return nil
1924}
1925
Himani Chawla40acc122021-05-26 18:52:29 +05301926func (options *GetOnuStats) Execute(args []string) error {
1927 conn, err := NewConnection()
1928 if err != nil {
1929 return err
1930 }
1931 defer conn.Close()
1932 client := extension.NewExtensionClient(conn)
1933
1934 singleGetValReq := extension.SingleGetValueRequest{
1935 TargetId: string(options.Args.OltId),
1936 Request: &extension.GetValueRequest{
1937 Request: &extension.GetValueRequest_OnuPonInfo{
1938 OnuPonInfo: &extension.GetOnuCountersRequest{
1939 IntfId: options.Args.IntfId,
1940 OnuId: options.Args.OnuId,
1941 },
1942 },
1943 },
1944 }
1945 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
1946 defer cancel()
1947 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1948 if err != nil {
1949 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.OltId, ErrorToString(err))
1950 return err
1951 }
1952
1953 if rv.Response.Status != extension.GetValueResponse_OK {
1954 return fmt.Errorf("failed to get onu stats %v", rv.Response.ErrReason.String())
1955 }
1956 outputFormat := CharReplacer.Replace(options.Format)
1957 data, formatStr := buildOnuStatsOutputFormat(rv.GetResponse().GetOnuPonCounters())
1958 if outputFormat == "" {
1959 outputFormat = GetCommandOptionWithDefault("device-get-onu-status", "format", formatStr)
1960 }
1961
1962 result := CommandResult{
1963 Format: format.Format(outputFormat),
1964 OutputAs: toOutputType(options.OutputAs),
1965 NameLimit: options.NameLimit,
1966 Data: data,
1967 }
1968 GenerateOutput(&result)
1969 return nil
1970}
1971
kesavand6d1131f2021-02-05 22:38:15 +05301972func (options *UniStatus) Execute(args []string) error {
1973 conn, err := NewConnection()
1974 if err != nil {
1975 return err
1976 }
1977 defer conn.Close()
1978 client := extension.NewExtensionClient(conn)
1979
1980 singleGetValReq := extension.SingleGetValueRequest{
1981 TargetId: string(options.Args.Id),
1982 Request: &extension.GetValueRequest{
1983 Request: &extension.GetValueRequest_UniInfo{
1984 UniInfo: &extension.GetOnuUniInfoRequest{
1985 UniIndex: options.Args.UniIndex,
1986 },
1987 },
1988 },
1989 }
David K. Bainbridge9189c632021-03-26 21:52:21 +00001990 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
kesavand6d1131f2021-02-05 22:38:15 +05301991 defer cancel()
1992 rv, err := client.GetExtValue(ctx, &singleGetValReq)
1993 if err != nil {
1994 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
1995 return err
1996 }
1997 if rv.Response.Status != extension.GetValueResponse_OK {
1998 return fmt.Errorf("failed to get uni status %v", rv.Response.ErrReason.String())
1999 }
2000 outputFormat := CharReplacer.Replace(options.Format)
2001 if outputFormat == "" {
2002 outputFormat = GetCommandOptionWithDefault("device-get-uni-status", "format", DEFAULT_DEVICE_GET_UNI_STATUS_FORMAT)
2003 }
2004 result := CommandResult{
2005 Format: format.Format(outputFormat),
2006 OutputAs: toOutputType(options.OutputAs),
2007 NameLimit: options.NameLimit,
2008 Data: rv.GetResponse().GetUniInfo(),
2009 }
2010 GenerateOutput(&result)
2011 return nil
2012}
2013
Girish Gowdra4f5ce7c2021-04-29 18:53:21 -07002014func (options *OnuPonOpticalInfo) Execute(args []string) error {
2015 conn, err := NewConnection()
2016 if err != nil {
2017 return err
2018 }
2019 defer conn.Close()
2020 client := extension.NewExtensionClient(conn)
2021
2022 singleGetValReq := extension.SingleGetValueRequest{
2023 TargetId: string(options.Args.Id),
2024 Request: &extension.GetValueRequest{
2025 Request: &extension.GetValueRequest_OnuOpticalInfo{
2026 OnuOpticalInfo: &extension.GetOnuPonOpticalInfo{},
2027 },
2028 },
2029 }
2030 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
2031 defer cancel()
2032 rv, err := client.GetExtValue(ctx, &singleGetValReq)
2033 if err != nil {
2034 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
2035 return err
2036 }
2037 if rv.Response.Status != extension.GetValueResponse_OK {
2038 return fmt.Errorf("failed to get onu pon optical info %v", rv.Response.ErrReason.String())
2039 }
2040 outputFormat := CharReplacer.Replace(options.Format)
2041 if outputFormat == "" {
2042 outputFormat = GetCommandOptionWithDefault("device-get-onu-pon-optical-info", "format", DEFAULT_ONU_PON_OPTICAL_INFO_STATUS_FORMAT)
2043 }
2044 result := CommandResult{
2045 Format: format.Format(outputFormat),
2046 OutputAs: toOutputType(options.OutputAs),
2047 NameLimit: options.NameLimit,
2048 Data: rv.GetResponse().GetOnuOpticalInfo(),
2049 }
2050 GenerateOutput(&result)
2051 return nil
2052}
2053
Gamze Abakac857a462021-05-26 13:45:54 +00002054func (options *RxPower) Execute(args []string) error {
2055 conn, err := NewConnection()
2056 if err != nil {
2057 return err
2058 }
2059 defer conn.Close()
2060 client := extension.NewExtensionClient(conn)
2061
2062 singleGetValReq := extension.SingleGetValueRequest{
2063 TargetId: string(options.Args.Id),
2064 Request: &extension.GetValueRequest{
2065 Request: &extension.GetValueRequest_RxPower{
2066 RxPower: &extension.GetRxPowerRequest{
2067 IntfId: options.Args.PortNo,
2068 OnuId: options.Args.OnuNo,
2069 },
2070 },
2071 },
2072 }
2073
2074 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
2075 defer cancel()
2076 rv, err := client.GetExtValue(ctx, &singleGetValReq)
2077 if err != nil {
2078 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
2079 return err
2080 }
2081 if rv.Response.Status != extension.GetValueResponse_OK {
2082 return fmt.Errorf("failed to get rx power %v", rv.Response.ErrReason.String())
2083 }
2084 outputFormat := CharReplacer.Replace(options.Format)
2085 if outputFormat == "" {
2086 outputFormat = GetCommandOptionWithDefault("device-get-rx-power", "format", DEFAULT_RX_POWER_STATUS_FORMAT)
2087 }
2088 result := CommandResult{
2089 Format: format.Format(outputFormat),
2090 OutputAs: toOutputType(options.OutputAs),
2091 NameLimit: options.NameLimit,
2092 Data: rv.GetResponse().GetRxPower(),
2093 }
2094 GenerateOutput(&result)
2095 return nil
2096}
2097
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002098/*Device get Onu Distance */
2099func (options *DeviceGetExtValue) Execute(args []string) error {
2100 conn, err := NewConnection()
2101 if err != nil {
2102 return err
2103 }
2104 defer conn.Close()
2105
Scott Baker9173ed82020-05-19 08:30:12 -07002106 client := voltha.NewVolthaServiceClient(conn)
2107
2108 valueflag, okay := common.ValueType_Type_value[string(options.Args.Valueflag)]
2109 if !okay {
2110 Error.Printf("Unknown valueflag %s\n", options.Args.Valueflag)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002111 }
2112
Scott Baker9173ed82020-05-19 08:30:12 -07002113 val := voltha.ValueSpecifier{Id: string(options.Args.Id), Value: common.ValueType_Type(valueflag)}
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002114
David K. Bainbridge9189c632021-03-26 21:52:21 +00002115 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002116 defer cancel()
2117
Scott Baker9173ed82020-05-19 08:30:12 -07002118 rv, err := client.GetExtValue(ctx, &val)
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002119 if err != nil {
2120 Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
2121 return err
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002122 }
2123
Scott Baker9173ed82020-05-19 08:30:12 -07002124 var rows []ReturnValueRow
2125 for name, num := range common.ValueType_Type_value {
2126 if num == 0 {
2127 // EMPTY is not a real value
2128 continue
2129 }
2130 if (rv.Error & uint32(num)) != 0 {
2131 row := ReturnValueRow{Name: name, Result: "Error"}
2132 rows = append(rows, row)
2133 }
2134 if (rv.Unsupported & uint32(num)) != 0 {
2135 row := ReturnValueRow{Name: name, Result: "Unsupported"}
2136 rows = append(rows, row)
2137 }
2138 if (rv.Set & uint32(num)) != 0 {
2139 switch name {
2140 case "DISTANCE":
2141 row := ReturnValueRow{Name: name, Result: rv.Distance}
2142 rows = append(rows, row)
2143 default:
2144 row := ReturnValueRow{Name: name, Result: "Unimplemented-in-voltctl"}
2145 rows = append(rows, row)
2146 }
2147 }
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002148 }
2149
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002150 outputFormat := CharReplacer.Replace(options.Format)
2151 if outputFormat == "" {
2152 outputFormat = GetCommandOptionWithDefault("device-value-get", "format", DEFAULT_DEVICE_VALUE_GET_FORMAT)
2153 }
2154
2155 result := CommandResult{
2156 Format: format.Format(outputFormat),
2157 OutputAs: toOutputType(options.OutputAs),
2158 NameLimit: options.NameLimit,
Scott Baker9173ed82020-05-19 08:30:12 -07002159 Data: rows,
Dinesh Belwalkarc9aa6d82020-03-04 15:22:17 -08002160 }
2161 GenerateOutput(&result)
2162 return nil
2163}