blob: 20837b59d280dd56e8ee6930035e97d8f108ec5b [file] [log] [blame]
Matteo Scandolo8df63df2019-09-12 10:34:32 -07001/*
2 * Portions copyright 2019-present Open Networking Foundation
3 * Original copyright 2019-present Ciena Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package commands
19
20import (
21 "context"
Matteo Scandolo10f965c2019-09-24 10:40:46 -070022 "fmt"
Anand S Katti09541352020-01-29 15:54:01 +053023 "os"
24 "strconv"
25 "strings"
26
Matteo Scandolo8df63df2019-09-12 10:34:32 -070027 "github.com/jessevdk/go-flags"
Anand S Katti09541352020-01-29 15:54:01 +053028 "github.com/olekukonko/tablewriter"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070029 pb "github.com/opencord/bbsim/api/bbsim"
30 "github.com/opencord/bbsim/internal/bbsimctl/config"
31 "github.com/opencord/cordctl/pkg/format"
32 log "github.com/sirupsen/logrus"
33 "google.golang.org/grpc"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070034)
35
36const (
Matteo Scandolo4a036262020-08-17 15:56:13 -070037 DEFAULT_ONU_DEVICE_HEADER_FORMAT = "table{{ .PonPortID }}\t{{ .ID }}\t{{ .PortNo }}\t{{ .SerialNumber }}\t{{ .OperState }}\t{{ .InternalState }}"
38 DEFAULT_ONU_DEVICE_HEADER_FORMAT_WITH_SERVICES = "table{{ .PonPortID }}\t{{ .ID }}\t{{ .PortNo }}\t{{ .SerialNumber }}\t{{ .OperState }}\t{{ .InternalState }}\t{{ .Services }}"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070039)
40
Matteo Scandolo10f965c2019-09-24 10:40:46 -070041type OnuSnString string
Arjun E K57a7fcb2020-01-30 06:44:45 +000042type IgmpSubAction string
43
44const IgmpJoinKey string = "join"
45const IgmpLeaveKey string = "leave"
Arjun E Kdd443f02020-02-07 15:24:01 +000046const IgmpJoinKeyV3 string = "joinv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +000047
Matteo Scandolo4a036262020-08-17 15:56:13 -070048type ONUList struct {
49 Verbose bool `short:"v" long:"verbose" description:"Print all the informations we have about ONUs"`
50}
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070051
52type ONUGet struct {
Matteo Scandolo4a036262020-08-17 15:56:13 -070053 Verbose bool `short:"v" long:"verbose" description:"Print all the informations we have about ONUs"`
54 Args struct {
55 OnuSn OnuSnString
56 } `positional-args:"yes" required:"yes"`
57}
58
59type ONUServices struct {
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070060 Args struct {
61 OnuSn OnuSnString
62 } `positional-args:"yes" required:"yes"`
63}
64
Matteo Scandolo10f965c2019-09-24 10:40:46 -070065type ONUShutDown struct {
66 Args struct {
67 OnuSn OnuSnString
68 } `positional-args:"yes" required:"yes"`
Matteo Scandolo8df63df2019-09-12 10:34:32 -070069}
70
Matteo Scandolo10f965c2019-09-24 10:40:46 -070071type ONUPowerOn struct {
72 Args struct {
73 OnuSn OnuSnString
74 } `positional-args:"yes" required:"yes"`
75}
76
Matteo Scandoloe383d5d2019-10-25 14:47:27 -070077type ONUEapolRestart struct {
78 Args struct {
79 OnuSn OnuSnString
80 } `positional-args:"yes" required:"yes"`
81}
82
83type ONUDhcpRestart struct {
84 Args struct {
85 OnuSn OnuSnString
86 } `positional-args:"yes" required:"yes"`
87}
88
Arjun E K57a7fcb2020-01-30 06:44:45 +000089type ONUIgmp struct {
90 Args struct {
91 OnuSn OnuSnString
92 SubAction IgmpSubAction
93 } `positional-args:"yes" required:"yes"`
94}
95
Pragya Arya8bdb4532020-03-02 17:08:09 +053096type ONUTrafficSchedulers struct {
97 Args struct {
98 OnuSn OnuSnString
99 } `positional-args:"yes" required:"yes"`
100}
101
102type ONUFlows struct {
103 Args struct {
104 OnuSn OnuSnString
105 } `positional-args:"yes" required:"yes"`
106}
107
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700108type ONUOptions struct {
Anand S Katti09541352020-01-29 15:54:01 +0530109 List ONUList `command:"list"`
110 Get ONUGet `command:"get"`
Matteo Scandolo4a036262020-08-17 15:56:13 -0700111 Services ONUServices `command:"services"`
Anand S Katti09541352020-01-29 15:54:01 +0530112 ShutDown ONUShutDown `command:"shutdown"`
113 PowerOn ONUPowerOn `command:"poweron"`
114 RestartEapol ONUEapolRestart `command:"auth_restart"`
115 RestartDchp ONUDhcpRestart `command:"dhcp_restart"`
116 Igmp ONUIgmp `command:"igmp"`
117 TrafficSchedulers ONUTrafficSchedulers `command:"traffic_schedulers"`
Anand S Katti86552f92020-03-03 21:56:32 +0530118 Alarms AlarmOptions `command:"alarms"`
Pragya Arya8bdb4532020-03-02 17:08:09 +0530119 Flows ONUFlows `command:"flows"`
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700120}
121
122func RegisterONUCommands(parser *flags.Parser) {
Shrey Baid688b4242020-07-10 20:40:10 +0530123 _, _ = parser.AddCommand("onu", "ONU Commands", "Commands to query and manipulate ONU devices", &ONUOptions{})
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700124}
125
126func connect() (pb.BBSimClient, *grpc.ClientConn) {
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700127 conn, err := grpc.Dial(config.GlobalConfig.Server, grpc.WithInsecure())
128
129 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700130 log.Fatalf("did not connect: %v", err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700131 return nil, conn
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700132 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700133 return pb.NewBBSimClient(conn), conn
134}
135
136func getONUs() *pb.ONUs {
137
138 client, conn := connect()
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700139 defer conn.Close()
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700140
141 // Contact the server and print out its response.
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700142 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
143 defer cancel()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700144
145 onus, err := client.GetONUs(ctx, &pb.Empty{})
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700146 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700147 log.Fatalf("could not get OLT: %v", err)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700148 return nil
149 }
150 return onus
151}
152
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700153func (options *ONUList) Execute(args []string) error {
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700154 onus := getONUs()
155
156 // print out
Matteo Scandolo4a036262020-08-17 15:56:13 -0700157 var tableFormat format.Format
158 if options.Verbose {
159 tableFormat = format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT_WITH_SERVICES)
160 } else {
161 tableFormat = format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT)
162 }
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700163 if err := tableFormat.Execute(os.Stdout, true, onus.Items); err != nil {
164 log.Fatalf("Error while formatting ONUs table: %s", err)
165 }
166
167 return nil
168}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700169
Matteo Scandolod2ca2c72019-10-04 16:50:22 -0700170func (options *ONUGet) Execute(args []string) error {
171 client, conn := connect()
172 defer conn.Close()
173
174 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
175 defer cancel()
176 req := pb.ONURequest{
177 SerialNumber: string(options.Args.OnuSn),
178 }
179 res, err := client.GetONU(ctx, &req)
180
181 if err != nil {
Matteo Scandolo4a036262020-08-17 15:56:13 -0700182 log.Fatalf("Cannot not get ONU %s: %v", options.Args.OnuSn, err)
Matteo Scandolod2ca2c72019-10-04 16:50:22 -0700183 return err
184 }
185
Matteo Scandolo4a036262020-08-17 15:56:13 -0700186 var tableFormat format.Format
187 if options.Verbose {
188 tableFormat = format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT_WITH_SERVICES)
189 } else {
190 tableFormat = format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT)
191 }
Matteo Scandolod2ca2c72019-10-04 16:50:22 -0700192 if err := tableFormat.Execute(os.Stdout, true, []*pb.ONU{res}); err != nil {
193 log.Fatalf("Error while formatting ONUs table: %s", err)
194 }
195
196 return nil
197}
198
Matteo Scandolo4a036262020-08-17 15:56:13 -0700199func (options *ONUServices) Execute(args []string) error {
200
201 client, conn := connect()
202 defer conn.Close()
203
204 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
205 defer cancel()
206 req := pb.ONURequest{
207 SerialNumber: string(options.Args.OnuSn),
208 }
209 res, err := client.GetOnuServices(ctx, &req)
210
211 if err != nil {
212 log.Fatalf("Cannot not get services for ONU %s: %v", options.Args.OnuSn, err)
213 return err
214 }
215
216 tableFormat := format.Format(DEFAULT_SERVICE_HEADER_FORMAT)
217 if err := tableFormat.Execute(os.Stdout, true, res.Items); err != nil {
218 log.Fatalf("Error while formatting Services table: %s", err)
219 }
220
221 return nil
222}
223
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700224func (options *ONUShutDown) Execute(args []string) error {
225
226 client, conn := connect()
227 defer conn.Close()
228
229 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
230 defer cancel()
231 req := pb.ONURequest{
232 SerialNumber: string(options.Args.OnuSn),
233 }
234 res, err := client.ShutdownONU(ctx, &req)
235
236 if err != nil {
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700237 log.Fatalf("Cannot shutdown ONU %s: %v", options.Args.OnuSn, err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700238 return err
239 }
240
241 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
242
243 return nil
244}
245
246func (options *ONUPowerOn) Execute(args []string) error {
247 client, conn := connect()
248 defer conn.Close()
249
250 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
251 defer cancel()
252 req := pb.ONURequest{
253 SerialNumber: string(options.Args.OnuSn),
254 }
255 res, err := client.PoweronONU(ctx, &req)
256
257 if err != nil {
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700258 log.Fatalf("Cannot power on ONU %s: %v", options.Args.OnuSn, err)
259 return err
260 }
261
262 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
263
264 return nil
265}
266
267func (options *ONUEapolRestart) Execute(args []string) error {
268 client, conn := connect()
269 defer conn.Close()
270
271 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
272 defer cancel()
273 req := pb.ONURequest{
274 SerialNumber: string(options.Args.OnuSn),
275 }
276 res, err := client.RestartEapol(ctx, &req)
277
278 if err != nil {
279 log.Fatalf("Cannot restart EAPOL for ONU %s: %v", options.Args.OnuSn, err)
280 return err
281 }
282
283 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
284
285 return nil
286}
287
288func (options *ONUDhcpRestart) Execute(args []string) error {
289 client, conn := connect()
290 defer conn.Close()
291
292 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
293 defer cancel()
294 req := pb.ONURequest{
295 SerialNumber: string(options.Args.OnuSn),
296 }
297 res, err := client.RestartDhcp(ctx, &req)
298
299 if err != nil {
300 log.Fatalf("Cannot restart DHCP for ONU %s: %v", options.Args.OnuSn, err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700301 return err
302 }
303
304 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
305
306 return nil
307}
308
Arjun E K57a7fcb2020-01-30 06:44:45 +0000309func (options *ONUIgmp) Execute(args []string) error {
310 client, conn := connect()
311 defer conn.Close()
312
313 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
314 defer cancel()
315
316 req := pb.ONURequest{
317 SerialNumber: string(options.Args.OnuSn),
318 }
319
320 var subActionVal pb.SubActionTypes
321 if string(options.Args.SubAction) == IgmpJoinKey {
322 subActionVal = pb.SubActionTypes_JOIN
323 } else if string(options.Args.SubAction) == IgmpLeaveKey {
324 subActionVal = pb.SubActionTypes_LEAVE
Anand S Katti09541352020-01-29 15:54:01 +0530325 } else if string(options.Args.SubAction) == IgmpJoinKeyV3 {
326 subActionVal = pb.SubActionTypes_JOINV3
327 }
Arjun E K57a7fcb2020-01-30 06:44:45 +0000328
329 igmpReq := pb.IgmpRequest{
330 OnuReq: &req,
331 SubActionVal: subActionVal,
332 }
333 res, err := client.GetONU(ctx, igmpReq.OnuReq)
334 if err != nil {
335 log.WithFields(log.Fields{
336 "SerialNumber": options.Args.OnuSn,
337 }).Errorf("Cannot not get details on ONU error: %v", err)
338 }
339 log.WithFields(log.Fields{
340 "SerialNumber": igmpReq.OnuReq.SerialNumber,
341 }).Debugf("ONU has indentified : %s", res)
342
343 igmpRes, igmpErr := client.ChangeIgmpState(ctx, &igmpReq)
344 if igmpErr != nil {
345 log.WithFields(log.Fields{
346 "SubAction": options.Args.SubAction,
347 }).Errorf("Could not process Action: error: %v", igmpErr)
348 } else {
349 log.WithFields(log.Fields{
350 "SubAction": options.Args.SubAction,
351 }).Debugf("igmp state has been changed with response: %s",
352 igmpRes.Message)
353 }
354
355 return nil
356}
357
Pragya Arya8bdb4532020-03-02 17:08:09 +0530358func (options *ONUFlows) Execute(args []string) error {
359 client, conn := connect()
360 defer conn.Close()
361
362 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
363 defer cancel()
364 req := pb.ONURequest{
365 SerialNumber: string(options.Args.OnuSn),
366 }
367 res, err := client.GetFlows(ctx, &req)
368 if err != nil {
369 log.Errorf("Cannot get flows for ONU %s: %v", options.Args.OnuSn, err)
370 return err
371 }
372
373 if res.Flows == nil {
374 fmt.Println(fmt.Sprintf("ONU %s has no flows", options.Args.OnuSn))
375 return nil
376 }
377
378 flowHeader := []string{
379 "access_intf_id",
380 "onu_id",
381 "uni_id",
382 "flow_id",
383 "flow_type",
384 "eth_type",
385 "alloc_id",
386 "network_intf_id",
387 "gemport_id",
388 "classifier",
389 "action",
390 "priority",
391 "cookie",
392 "port_no",
393 }
394
395 tableFlow := tablewriter.NewWriter(os.Stdout)
396 tableFlow.SetRowLine(true)
397 fmt.Fprintf(os.Stdout, "ONU Flows:\n")
398 tableFlow.SetHeader(flowHeader)
399
400 for _, flow := range res.Flows {
401 flowInfo := []string{}
402 flowInfo = append(flowInfo,
403 strconv.Itoa(int(flow.AccessIntfId)),
404 strconv.Itoa(int(flow.OnuId)),
405 strconv.Itoa(int(flow.UniId)),
406 strconv.Itoa(int(flow.FlowId)),
407 flow.FlowType,
408 fmt.Sprintf("%x", flow.Classifier.EthType),
409 strconv.Itoa(int(flow.AllocId)),
410 strconv.Itoa(int(flow.NetworkIntfId)),
411 strconv.Itoa(int(flow.GemportId)),
412 flow.Classifier.String(),
413 flow.Action.String(),
414 strconv.Itoa(int(flow.Priority)),
415 strconv.Itoa(int(flow.Cookie)),
416 strconv.Itoa(int(flow.PortNo)),
417 )
418 tableFlow.Append(flowInfo)
419 }
420 tableFlow.Render()
421 tableFlow.SetNewLine("")
422 return nil
423}
424
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700425func (onuSn *OnuSnString) Complete(match string) []flags.Completion {
426 client, conn := connect()
427 defer conn.Close()
428
429 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
430 defer cancel()
431
432 onus, err := client.GetONUs(ctx, &pb.Empty{})
433 if err != nil {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700434 log.Fatalf("could not get ONUs: %v", err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700435 return nil
436 }
437
438 list := make([]flags.Completion, 0)
439 for _, k := range onus.Items {
440 if strings.HasPrefix(k.SerialNumber, match) {
441 list = append(list, flags.Completion{Item: k.SerialNumber})
442 }
443 }
444
445 return list
446}
Anand S Katti09541352020-01-29 15:54:01 +0530447
448func (options *ONUTrafficSchedulers) Execute(args []string) error {
449 client, conn := connect()
450 defer conn.Close()
451
452 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
453 defer cancel()
454 req := pb.ONURequest{
455 SerialNumber: string(options.Args.OnuSn),
456 }
457 res, err := client.GetOnuTrafficSchedulers(ctx, &req)
458 if err != nil {
459 log.Fatalf("Cannot get traffic schedulers for ONU %s: %v", options.Args.OnuSn, err)
460 return err
461 }
462
463 if res.TraffSchedulers == nil {
464 log.Fatalf("Cannot get traffic schedulers for ONU: %s (unavailable)", options.Args.OnuSn)
465 return nil
466 }
467
468 SchedulerHeader := []string{"Direction",
469 "AllocId",
470 "Scheduler.Direction",
471 "Scheduler.AdditionalBw",
472 "Scheduler.Priority",
473 "Scheduler.Weight",
474 "Scheduler.SchedPolicy",
475 }
476
477 ShapingInfoHeader := []string{"InferredAdditionBwIndication",
478 "Cbs",
479 "Cir",
480 "Gir",
481 "Pbs",
482 "Pir",
483 }
484
485 SchedulerVals := []string{}
486 ShapingInfoVals := []string{}
487 for _, v := range res.TraffSchedulers.TrafficScheds {
488 SchedulerVals = append(SchedulerVals,
489 v.GetDirection().String(),
490 strconv.Itoa(int(v.GetAllocId())),
491 v.Scheduler.GetDirection().String(),
492 v.Scheduler.GetAdditionalBw().String(),
493 strconv.Itoa(int(v.Scheduler.GetPriority())),
494 strconv.Itoa(int(v.Scheduler.GetWeight())),
495 v.GetScheduler().GetSchedPolicy().String(),
496 )
497
498 ShapingInfoVals = append(ShapingInfoVals,
499 v.TrafficShapingInfo.GetAddBwInd().String(),
500 strconv.Itoa(int(v.TrafficShapingInfo.GetCbs())),
501 strconv.Itoa(int(v.TrafficShapingInfo.GetCir())),
502 strconv.Itoa(int(v.TrafficShapingInfo.GetGir())),
503 strconv.Itoa(int(v.TrafficShapingInfo.GetPbs())),
504 strconv.Itoa(int(v.TrafficShapingInfo.GetPir())),
505 )
506 }
507
508 fmt.Fprintf(os.Stdout, "OnuId: %d \n", int(res.TraffSchedulers.OnuId))
509 fmt.Fprintf(os.Stdout, "IntfId: %d \n", int(res.TraffSchedulers.IntfId))
510 fmt.Fprintf(os.Stdout, "UniId: %d \n", int(res.TraffSchedulers.UniId))
511 fmt.Fprintf(os.Stdout, "OnuPortNo: %d \n", int(res.TraffSchedulers.PortNo))
512
513 tableSched := tablewriter.NewWriter(os.Stdout)
514 tableSched.SetRowLine(true)
515 fmt.Fprintf(os.Stdout, "Traffic Schedulers Info:\n")
516 tableSched.SetHeader(SchedulerHeader)
517 tableSched.Append(SchedulerVals)
518 tableSched.Render()
519 tableSched.SetNewLine("")
520
521 tableShap := tablewriter.NewWriter(os.Stdout)
522 tableShap.SetRowLine(true)
523 fmt.Fprintf(os.Stdout, "Traffic Shaping Info:\n")
524 tableShap.SetHeader(ShapingInfoHeader)
525 tableShap.Append(ShapingInfoVals)
526 tableShap.Render()
527
528 return nil
529}