blob: cf8f3ce0188faade2e4b5d976809c1eae96589f5 [file] [log] [blame]
Matteo Scandolo8df63df2019-09-12 10:34:32 -07001/*
Joey Armstrong4d6878e2024-02-08 16:29:26 -05002 * Portions Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandolo8df63df2019-09-12 10:34:32 -07003 * 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"
22 "fmt"
Pragya Arya8bdb4532020-03-02 17:08:09 +053023 "os"
24 "strconv"
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080025 "strings"
Pragya Arya8bdb4532020-03-02 17:08:09 +053026
Matteo Scandolo8df63df2019-09-12 10:34:32 -070027 "github.com/jessevdk/go-flags"
Pragya Arya8bdb4532020-03-02 17:08:09 +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"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070033)
34
35const (
Andrea Campanella6f5f3552022-03-10 17:14:25 +010036 DEFAULT_OLT_DEVICE_HEADER_FORMAT = "table{{ .ID }}\t{{ .SerialNumber }}\t{{ .OperState }}\t{{ .InternalState }}\t{{ .IP }}\t{{ .NniDhcpTrapVid }}"
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080037 DEFAULT_OLT_RESOURCES_HEADER_FORMAT = "table{{ .Type }}\t{{ .PonPortId }}\t{{ .OnuId }}\t{{ .PortNo }}\t{{ .ResourceId }}\t{{ .FlowId }}"
38 DEFAULT_NNI_PORT_HEADER_FORMAT = "table{{ .ID }}\t{{ .OperState }}\t{{ .InternalState }}\t{{ .PacketCount }}"
Elia Battistonb7bea222022-02-18 16:25:00 +010039 DEFAULT_PON_PORT_HEADER_FORMAT = "table{{ .ID }}\t{{ .Technology }}\t{{ .OperState }}\t{{ .InternalState }}\t{{ .PacketCount }}\t{{ .AllocatedOnuIds }}\t{{ .AllocatedGemPorts }}\t{{ .AllocatedAllocIds }}"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070040)
41
42type OltGet struct{}
43
44type OltNNIs struct{}
45
46type OltPONs struct{}
47
Zdravko Bozakov681364d2019-11-10 14:28:46 +010048type OltShutdown struct{}
49
50type OltPoweron struct{}
51
52type OltReboot struct{}
53
Matteo Scandolo88c204a2020-11-03 10:34:24 -080054type StopGrpcServer struct{}
55
56type StartGrpcServer struct{}
57type RestartGrpcServer struct {
58 Args struct {
59 Delay uint32
60 } `positional-args:"yes" required:"yes"`
61}
62
Pragya Arya8bdb4532020-03-02 17:08:09 +053063type OltFlows struct{}
64
Pragya Aryabd731ec2020-02-11 16:38:17 +053065type OltPoweronAllOnus struct{}
66
67type OltShutdownAllOnus struct{}
68
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080069type oltResourcesType string
70type OltResources struct {
71 Args struct {
72 Type oltResourcesType
73 } `positional-args:"yes" required:"yes"`
74}
75
Matteo Scandolo8df63df2019-09-12 10:34:32 -070076type oltOptions struct {
Pragya Aryabd731ec2020-02-11 16:38:17 +053077 Get OltGet `command:"get"`
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080078 GetResources OltResources `command:"resources"`
Pragya Aryabd731ec2020-02-11 16:38:17 +053079 NNI OltNNIs `command:"nnis"`
80 PON OltPONs `command:"pons"`
81 Shutdown OltShutdown `command:"shutdown"`
82 Poweron OltPoweron `command:"poweron"`
83 Reboot OltReboot `command:"reboot"`
84 Alarms OltAlarmOptions `command:"alarms"`
85 Flows OltFlows `command:"flows"`
86 PoweronAllOnus OltPoweronAllOnus `command:"poweronAllONUs"`
87 ShutdownAllOnus OltShutdownAllOnus `command:"shutdownAllONUs"`
Matteo Scandolo88c204a2020-11-03 10:34:24 -080088 StopServer StopGrpcServer `command:"stopServer"`
89 StartServer StartGrpcServer `command:"startServer"`
90 RestartServer RestartGrpcServer `command:"restartServer"`
Matteo Scandolo8df63df2019-09-12 10:34:32 -070091}
92
93func RegisterOltCommands(parser *flags.Parser) {
Shrey Baid688b4242020-07-10 20:40:10 +053094 _, _ = parser.AddCommand("olt", "OLT Commands", "Commands to query and manipulate the OLT device", &oltOptions{})
Matteo Scandolo8df63df2019-09-12 10:34:32 -070095}
96
97func getOLT() *pb.Olt {
Matteo Scandolo4b077aa2021-02-16 17:33:37 -080098 client, conn := connect()
Matteo Scandolo8df63df2019-09-12 10:34:32 -070099 defer conn.Close()
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700100
101 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
102 defer cancel()
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800103 olt, err := client.GetOlt(ctx, &pb.Empty{})
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700104 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -0700105 log.Fatalf("could not get OLT: %v", err)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700106 return nil
107 }
108 return olt
109}
110
111func printOltHeader(prefix string, o *pb.Olt) {
112 fmt.Println(fmt.Sprintf("%s : %s", prefix, o.SerialNumber))
113 fmt.Println()
114}
115
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700116func (o *OltGet) Execute(args []string) error {
117 olt := getOLT()
118
119 // print out
120 tableFormat := format.Format(DEFAULT_OLT_DEVICE_HEADER_FORMAT)
Shrey Baid688b4242020-07-10 20:40:10 +0530121 _ = tableFormat.Execute(os.Stdout, true, olt)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700122
123 return nil
124}
125
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800126func (o *OltResources) Execute(args []string) error {
127 client, conn := connect()
128 defer conn.Close()
129
130 resourceType := pb.OltAllocatedResourceType_Type_value[string(o.Args.Type)]
131
132 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
133 defer cancel()
134 resources, err := client.GetOltAllocatedResources(ctx, &pb.OltAllocatedResourceType{Type: pb.OltAllocatedResourceType_Type(resourceType)})
135
136 if err != nil {
137 log.Fatalf("could not get OLT resources: %v", err)
138 return nil
139 }
140
141 tableFormat := format.Format(DEFAULT_OLT_RESOURCES_HEADER_FORMAT)
142 if err := tableFormat.Execute(os.Stdout, true, resources.Resources); err != nil {
143 return err
144 }
145 return nil
146}
147
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700148func (o *OltNNIs) Execute(args []string) error {
149 olt := getOLT()
150
151 printOltHeader("NNI Ports for", olt)
152
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800153 tableFormat := format.Format(DEFAULT_NNI_PORT_HEADER_FORMAT)
Shrey Baid688b4242020-07-10 20:40:10 +0530154 _ = tableFormat.Execute(os.Stdout, true, olt.NNIPorts)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700155
156 return nil
157}
158
159func (o *OltPONs) Execute(args []string) error {
160 olt := getOLT()
161
162 printOltHeader("PON Ports for", olt)
163
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800164 tableFormat := format.Format(DEFAULT_PON_PORT_HEADER_FORMAT)
Shrey Baid688b4242020-07-10 20:40:10 +0530165 _ = tableFormat.Execute(os.Stdout, true, olt.PONPorts)
Matteo Scandolo8df63df2019-09-12 10:34:32 -0700166
167 return nil
168}
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100169
170func (o *OltShutdown) 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
177 res, err := client.ShutdownOlt(ctx, &pb.Empty{})
178
179 if err != nil {
180 log.Fatalf("Cannot shut down OLT: %v", err)
181 return err
182 }
183
184 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
185 return nil
186}
187
188func (o *OltPoweron) Execute(args []string) error {
189 client, conn := connect()
190 defer conn.Close()
191
192 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
193 defer cancel()
194
195 res, err := client.PoweronOlt(ctx, &pb.Empty{})
196
197 if err != nil {
198 log.Fatalf("Cannot power on OLT: %v", err)
199 return err
200 }
201
202 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
203 return nil
204}
205
206func (o *OltReboot) Execute(args []string) error {
207 client, conn := connect()
208 defer conn.Close()
209
210 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
211 defer cancel()
212
213 res, err := client.RebootOlt(ctx, &pb.Empty{})
214
215 if err != nil {
216 log.Fatalf("Cannot reboot OLT: %v", err)
217 return err
218 }
219
220 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
221 return nil
222}
Pragya Arya8bdb4532020-03-02 17:08:09 +0530223
Matteo Scandolo88c204a2020-11-03 10:34:24 -0800224func (o *StopGrpcServer) Execute(args []string) error {
225 client, conn := connect()
226 defer conn.Close()
227
228 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
229 defer cancel()
230
231 res, err := client.StopgRPCServer(ctx, &pb.Empty{})
232
233 if err != nil {
234 log.Fatalf("Cannot stop Openolt server: %v", err)
235 return err
236 }
237
238 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
239 return nil
240}
241
242func (o *StartGrpcServer) Execute(args []string) error {
243 client, conn := connect()
244 defer conn.Close()
245
246 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
247 defer cancel()
248
249 res, err := client.StartgRPCServer(ctx, &pb.Empty{})
250
251 if err != nil {
252 log.Fatalf("Cannot start Openolt server: %v", err)
253 return err
254 }
255
256 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
257 return nil
258}
259
260func (o *RestartGrpcServer) Execute(args []string) error {
261 req := &pb.Timeout{
262 Delay: o.Args.Delay,
263 }
264 client, conn := connect()
265 defer conn.Close()
266
267 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
268 defer cancel()
269
270 res, err := client.RestartgRPCServer(ctx, req)
271
272 if err != nil {
273 log.Fatalf("Cannot restart Openolt server: %v", err)
274 return err
275 }
276
277 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
278 return nil
279}
280
Pragya Arya8bdb4532020-03-02 17:08:09 +0530281func (o *OltFlows) Execute(args []string) error {
282 client, conn := connect()
283 defer conn.Close()
284
285 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
286 defer cancel()
287
288 req := pb.ONURequest{}
289 res, err := client.GetFlows(ctx, &req)
290 if err != nil {
291 log.Errorf("Cannot get flows for OLT: %v", err)
292 return err
293 }
294
295 if res.Flows == nil {
296 fmt.Println("OLT has no flows")
297 return nil
298 }
299
300 flowHeader := []string{
301 "access_intf_id",
302 "onu_id",
303 "uni_id",
304 "flow_id",
305 "flow_type",
306 "eth_type",
307 "alloc_id",
308 "network_intf_id",
309 "gemport_id",
310 "classifier",
311 "action",
312 "priority",
313 "cookie",
314 "port_no",
315 }
316
317 tableFlow := tablewriter.NewWriter(os.Stdout)
318 tableFlow.SetRowLine(true)
319 fmt.Fprintf(os.Stdout, "OLT Flows:\n")
320 tableFlow.SetHeader(flowHeader)
321
322 for _, flow := range res.Flows {
323 flowInfo := []string{}
324 flowInfo = append(flowInfo,
325 strconv.Itoa(int(flow.AccessIntfId)),
326 strconv.Itoa(int(flow.OnuId)),
327 strconv.Itoa(int(flow.UniId)),
328 strconv.Itoa(int(flow.FlowId)),
329 flow.FlowType,
330 fmt.Sprintf("%x", flow.Classifier.EthType),
331 strconv.Itoa(int(flow.AllocId)),
332 strconv.Itoa(int(flow.NetworkIntfId)),
333 strconv.Itoa(int(flow.GemportId)),
334 flow.Classifier.String(),
335 flow.Action.String(),
336 strconv.Itoa(int(flow.Priority)),
337 strconv.Itoa(int(flow.Cookie)),
338 strconv.Itoa(int(flow.PortNo)),
339 )
340 tableFlow.Append(flowInfo)
341 }
342 tableFlow.Render()
343 tableFlow.SetNewLine("")
344 return nil
345}
Pragya Aryabd731ec2020-02-11 16:38:17 +0530346
347func (o *OltPoweronAllOnus) Execute(args []string) error {
348 client, conn := connect()
349 defer conn.Close()
350
351 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
352 defer cancel()
353
354 res, err := client.PoweronAllONUs(ctx, &pb.Empty{})
355
356 if err != nil {
357 log.Errorf("Cannot poweron all ONUs: %v", err)
358 return err
359 }
360
361 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
362 return nil
363}
364
365func (o *OltShutdownAllOnus) Execute(args []string) error {
366 client, conn := connect()
367 defer conn.Close()
368
369 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
370 defer cancel()
371
372 res, err := client.ShutdownAllONUs(ctx, &pb.Empty{})
373
374 if err != nil {
375 log.Errorf("Cannot shutdown all ONUs: %v", err)
376 return err
377 }
378
379 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
380 return nil
381}
Matteo Scandolo4b077aa2021-02-16 17:33:37 -0800382
383func (rt *oltResourcesType) Complete(match string) []flags.Completion {
384 list := make([]flags.Completion, 0)
385 for k := range pb.OltAllocatedResourceType_Type_value {
386 if strings.HasPrefix(k, strings.ToUpper(match)) && k != pb.OltAllocatedResourceType_UNKNOWN.String() {
387 list = append(list, flags.Completion{Item: k})
388 }
389 }
390 return list
391}