blob: 9e4199012353837c21cfedb1067e2f09e567af00 [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 Scandolo40e067f2019-10-16 16:59:41 -070037 DEFAULT_ONU_DEVICE_HEADER_FORMAT = "table{{ .PonPortID }}\t{{ .ID }}\t{{ .PortNo }}\t{{ .SerialNumber }}\t{{ .HwAddress }}\t{{ .STag }}\t{{ .CTag }}\t{{ .OperState }}\t{{ .InternalState }}"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070038)
39
Matteo Scandolo10f965c2019-09-24 10:40:46 -070040type OnuSnString string
Arjun E K57a7fcb2020-01-30 06:44:45 +000041type IgmpSubAction string
42
43const IgmpJoinKey string = "join"
44const IgmpLeaveKey string = "leave"
Arjun E Kdd443f02020-02-07 15:24:01 +000045const IgmpJoinKeyV3 string = "joinv3"
Arjun E K57a7fcb2020-01-30 06:44:45 +000046
Matteo Scandolo10f965c2019-09-24 10:40:46 -070047type ONUList struct{}
Matteo Scandolod2ca2c72019-10-04 16:50:22 -070048
49type ONUGet struct {
50 Args struct {
51 OnuSn OnuSnString
52 } `positional-args:"yes" required:"yes"`
53}
54
Matteo Scandolo10f965c2019-09-24 10:40:46 -070055type ONUShutDown struct {
56 Args struct {
57 OnuSn OnuSnString
58 } `positional-args:"yes" required:"yes"`
Matteo Scandolo8df63df2019-09-12 10:34:32 -070059}
60
Matteo Scandolo10f965c2019-09-24 10:40:46 -070061type ONUPowerOn struct {
62 Args struct {
63 OnuSn OnuSnString
64 } `positional-args:"yes" required:"yes"`
65}
66
Matteo Scandoloe383d5d2019-10-25 14:47:27 -070067type ONUEapolRestart struct {
68 Args struct {
69 OnuSn OnuSnString
70 } `positional-args:"yes" required:"yes"`
71}
72
73type ONUDhcpRestart struct {
74 Args struct {
75 OnuSn OnuSnString
76 } `positional-args:"yes" required:"yes"`
77}
78
Arjun E K57a7fcb2020-01-30 06:44:45 +000079type ONUIgmp struct {
80 Args struct {
81 OnuSn OnuSnString
82 SubAction IgmpSubAction
83 } `positional-args:"yes" required:"yes"`
84}
85
Matteo Scandolo10f965c2019-09-24 10:40:46 -070086type ONUOptions struct {
Anand S Katti09541352020-01-29 15:54:01 +053087 List ONUList `command:"list"`
88 Get ONUGet `command:"get"`
89 ShutDown ONUShutDown `command:"shutdown"`
90 PowerOn ONUPowerOn `command:"poweron"`
91 RestartEapol ONUEapolRestart `command:"auth_restart"`
92 RestartDchp ONUDhcpRestart `command:"dhcp_restart"`
93 Igmp ONUIgmp `command:"igmp"`
94 TrafficSchedulers ONUTrafficSchedulers `command:"traffic_schedulers"`
95}
96
97type ONUTrafficSchedulers struct {
98 Args struct {
99 OnuSn OnuSnString
100 } `positional-args:"yes" required:"yes"`
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700101}
102
103func RegisterONUCommands(parser *flags.Parser) {
104 parser.AddCommand("onu", "ONU Commands", "Commands to query and manipulate ONU devices", &ONUOptions{})
105}
106
107func connect() (pb.BBSimClient, *grpc.ClientConn) {
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700108 conn, err := grpc.Dial(config.GlobalConfig.Server, grpc.WithInsecure())
109
110 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700111 log.Fatalf("did not connect: %v", err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700112 return nil, conn
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700113 }
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700114 return pb.NewBBSimClient(conn), conn
115}
116
117func getONUs() *pb.ONUs {
118
119 client, conn := connect()
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700120 defer conn.Close()
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700121
122 // Contact the server and print out its response.
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700123 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
124 defer cancel()
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700125
126 onus, err := client.GetONUs(ctx, &pb.Empty{})
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700127 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700128 log.Fatalf("could not get OLT: %v", err)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700129 return nil
130 }
131 return onus
132}
133
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700134func (options *ONUList) Execute(args []string) error {
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700135 onus := getONUs()
136
137 // print out
138 tableFormat := format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT)
139 if err := tableFormat.Execute(os.Stdout, true, onus.Items); err != nil {
140 log.Fatalf("Error while formatting ONUs table: %s", err)
141 }
142
143 return nil
144}
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700145
Matteo Scandolod2ca2c72019-10-04 16:50:22 -0700146func (options *ONUGet) Execute(args []string) error {
147 client, conn := connect()
148 defer conn.Close()
149
150 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
151 defer cancel()
152 req := pb.ONURequest{
153 SerialNumber: string(options.Args.OnuSn),
154 }
155 res, err := client.GetONU(ctx, &req)
156
157 if err != nil {
158 log.Fatalf("Cannot not shutdown ONU %s: %v", options.Args.OnuSn, err)
159 return err
160 }
161
162 tableFormat := format.Format(DEFAULT_ONU_DEVICE_HEADER_FORMAT)
163 if err := tableFormat.Execute(os.Stdout, true, []*pb.ONU{res}); err != nil {
164 log.Fatalf("Error while formatting ONUs table: %s", err)
165 }
166
167 return nil
168}
169
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700170func (options *ONUShutDown) Execute(args []string) error {
171
172 client, conn := connect()
173 defer conn.Close()
174
175 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
176 defer cancel()
177 req := pb.ONURequest{
178 SerialNumber: string(options.Args.OnuSn),
179 }
180 res, err := client.ShutdownONU(ctx, &req)
181
182 if err != nil {
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700183 log.Fatalf("Cannot shutdown ONU %s: %v", options.Args.OnuSn, err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700184 return err
185 }
186
187 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
188
189 return nil
190}
191
192func (options *ONUPowerOn) Execute(args []string) error {
193 client, conn := connect()
194 defer conn.Close()
195
196 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
197 defer cancel()
198 req := pb.ONURequest{
199 SerialNumber: string(options.Args.OnuSn),
200 }
201 res, err := client.PoweronONU(ctx, &req)
202
203 if err != nil {
Matteo Scandoloe383d5d2019-10-25 14:47:27 -0700204 log.Fatalf("Cannot power on ONU %s: %v", options.Args.OnuSn, err)
205 return err
206 }
207
208 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
209
210 return nil
211}
212
213func (options *ONUEapolRestart) Execute(args []string) error {
214 client, conn := connect()
215 defer conn.Close()
216
217 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
218 defer cancel()
219 req := pb.ONURequest{
220 SerialNumber: string(options.Args.OnuSn),
221 }
222 res, err := client.RestartEapol(ctx, &req)
223
224 if err != nil {
225 log.Fatalf("Cannot restart EAPOL for ONU %s: %v", options.Args.OnuSn, err)
226 return err
227 }
228
229 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
230
231 return nil
232}
233
234func (options *ONUDhcpRestart) Execute(args []string) error {
235 client, conn := connect()
236 defer conn.Close()
237
238 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
239 defer cancel()
240 req := pb.ONURequest{
241 SerialNumber: string(options.Args.OnuSn),
242 }
243 res, err := client.RestartDhcp(ctx, &req)
244
245 if err != nil {
246 log.Fatalf("Cannot restart DHCP for ONU %s: %v", options.Args.OnuSn, err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700247 return err
248 }
249
250 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
251
252 return nil
253}
254
Arjun E K57a7fcb2020-01-30 06:44:45 +0000255func (options *ONUIgmp) Execute(args []string) error {
256 client, conn := connect()
257 defer conn.Close()
258
259 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
260 defer cancel()
261
262 req := pb.ONURequest{
263 SerialNumber: string(options.Args.OnuSn),
264 }
265
266 var subActionVal pb.SubActionTypes
267 if string(options.Args.SubAction) == IgmpJoinKey {
268 subActionVal = pb.SubActionTypes_JOIN
269 } else if string(options.Args.SubAction) == IgmpLeaveKey {
270 subActionVal = pb.SubActionTypes_LEAVE
Anand S Katti09541352020-01-29 15:54:01 +0530271 } else if string(options.Args.SubAction) == IgmpJoinKeyV3 {
272 subActionVal = pb.SubActionTypes_JOINV3
273 }
Arjun E K57a7fcb2020-01-30 06:44:45 +0000274
275 igmpReq := pb.IgmpRequest{
276 OnuReq: &req,
277 SubActionVal: subActionVal,
278 }
279 res, err := client.GetONU(ctx, igmpReq.OnuReq)
280 if err != nil {
281 log.WithFields(log.Fields{
282 "SerialNumber": options.Args.OnuSn,
283 }).Errorf("Cannot not get details on ONU error: %v", err)
284 }
285 log.WithFields(log.Fields{
286 "SerialNumber": igmpReq.OnuReq.SerialNumber,
287 }).Debugf("ONU has indentified : %s", res)
288
289 igmpRes, igmpErr := client.ChangeIgmpState(ctx, &igmpReq)
290 if igmpErr != nil {
291 log.WithFields(log.Fields{
292 "SubAction": options.Args.SubAction,
293 }).Errorf("Could not process Action: error: %v", igmpErr)
294 } else {
295 log.WithFields(log.Fields{
296 "SubAction": options.Args.SubAction,
297 }).Debugf("igmp state has been changed with response: %s",
298 igmpRes.Message)
299 }
300
301 return nil
302}
303
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700304func (onuSn *OnuSnString) Complete(match string) []flags.Completion {
305 client, conn := connect()
306 defer conn.Close()
307
308 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
309 defer cancel()
310
311 onus, err := client.GetONUs(ctx, &pb.Empty{})
312 if err != nil {
Matteo Scandolo86e8ce62019-10-11 12:03:10 -0700313 log.Fatalf("could not get ONUs: %v", err)
Matteo Scandolo10f965c2019-09-24 10:40:46 -0700314 return nil
315 }
316
317 list := make([]flags.Completion, 0)
318 for _, k := range onus.Items {
319 if strings.HasPrefix(k.SerialNumber, match) {
320 list = append(list, flags.Completion{Item: k.SerialNumber})
321 }
322 }
323
324 return list
325}
Anand S Katti09541352020-01-29 15:54:01 +0530326
327func (options *ONUTrafficSchedulers) Execute(args []string) error {
328 client, conn := connect()
329 defer conn.Close()
330
331 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
332 defer cancel()
333 req := pb.ONURequest{
334 SerialNumber: string(options.Args.OnuSn),
335 }
336 res, err := client.GetOnuTrafficSchedulers(ctx, &req)
337 if err != nil {
338 log.Fatalf("Cannot get traffic schedulers for ONU %s: %v", options.Args.OnuSn, err)
339 return err
340 }
341
342 if res.TraffSchedulers == nil {
343 log.Fatalf("Cannot get traffic schedulers for ONU: %s (unavailable)", options.Args.OnuSn)
344 return nil
345 }
346
347 SchedulerHeader := []string{"Direction",
348 "AllocId",
349 "Scheduler.Direction",
350 "Scheduler.AdditionalBw",
351 "Scheduler.Priority",
352 "Scheduler.Weight",
353 "Scheduler.SchedPolicy",
354 }
355
356 ShapingInfoHeader := []string{"InferredAdditionBwIndication",
357 "Cbs",
358 "Cir",
359 "Gir",
360 "Pbs",
361 "Pir",
362 }
363
364 SchedulerVals := []string{}
365 ShapingInfoVals := []string{}
366 for _, v := range res.TraffSchedulers.TrafficScheds {
367 SchedulerVals = append(SchedulerVals,
368 v.GetDirection().String(),
369 strconv.Itoa(int(v.GetAllocId())),
370 v.Scheduler.GetDirection().String(),
371 v.Scheduler.GetAdditionalBw().String(),
372 strconv.Itoa(int(v.Scheduler.GetPriority())),
373 strconv.Itoa(int(v.Scheduler.GetWeight())),
374 v.GetScheduler().GetSchedPolicy().String(),
375 )
376
377 ShapingInfoVals = append(ShapingInfoVals,
378 v.TrafficShapingInfo.GetAddBwInd().String(),
379 strconv.Itoa(int(v.TrafficShapingInfo.GetCbs())),
380 strconv.Itoa(int(v.TrafficShapingInfo.GetCir())),
381 strconv.Itoa(int(v.TrafficShapingInfo.GetGir())),
382 strconv.Itoa(int(v.TrafficShapingInfo.GetPbs())),
383 strconv.Itoa(int(v.TrafficShapingInfo.GetPir())),
384 )
385 }
386
387 fmt.Fprintf(os.Stdout, "OnuId: %d \n", int(res.TraffSchedulers.OnuId))
388 fmt.Fprintf(os.Stdout, "IntfId: %d \n", int(res.TraffSchedulers.IntfId))
389 fmt.Fprintf(os.Stdout, "UniId: %d \n", int(res.TraffSchedulers.UniId))
390 fmt.Fprintf(os.Stdout, "OnuPortNo: %d \n", int(res.TraffSchedulers.PortNo))
391
392 tableSched := tablewriter.NewWriter(os.Stdout)
393 tableSched.SetRowLine(true)
394 fmt.Fprintf(os.Stdout, "Traffic Schedulers Info:\n")
395 tableSched.SetHeader(SchedulerHeader)
396 tableSched.Append(SchedulerVals)
397 tableSched.Render()
398 tableSched.SetNewLine("")
399
400 tableShap := tablewriter.NewWriter(os.Stdout)
401 tableShap.SetRowLine(true)
402 fmt.Fprintf(os.Stdout, "Traffic Shaping Info:\n")
403 tableShap.SetHeader(ShapingInfoHeader)
404 tableShap.Append(ShapingInfoVals)
405 tableShap.Render()
406
407 return nil
408}