blob: f1553db2e6e4445e7a77a7360a07d0ffea6ed3da [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"
22 "fmt"
Pragya Arya8bdb4532020-03-02 17:08:09 +053023 "os"
24 "strconv"
25
Matteo Scandolo8df63df2019-09-12 10:34:32 -070026 "github.com/jessevdk/go-flags"
Pragya Arya8bdb4532020-03-02 17:08:09 +053027 "github.com/olekukonko/tablewriter"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070028 pb "github.com/opencord/bbsim/api/bbsim"
29 "github.com/opencord/bbsim/internal/bbsimctl/config"
30 "github.com/opencord/cordctl/pkg/format"
31 log "github.com/sirupsen/logrus"
32 "google.golang.org/grpc"
Matteo Scandolo8df63df2019-09-12 10:34:32 -070033)
34
35const (
36 DEFAULT_OLT_DEVICE_HEADER_FORMAT = "table{{ .ID }}\t{{ .SerialNumber }}\t{{ .OperState }}\t{{ .InternalState }}"
37 DEFAULT_PORT_HEADER_FORMAT = "table{{ .ID }}\t{{ .OperState }}"
38)
39
40type OltGet struct{}
41
42type OltNNIs struct{}
43
44type OltPONs struct{}
45
Zdravko Bozakov681364d2019-11-10 14:28:46 +010046type OltShutdown struct{}
47
48type OltPoweron struct{}
49
50type OltReboot struct{}
51
Pragya Arya8bdb4532020-03-02 17:08:09 +053052type OltFlows struct{}
53
Matteo Scandolo8df63df2019-09-12 10:34:32 -070054type oltOptions struct {
Anand S Katti86552f92020-03-03 21:56:32 +053055 Get OltGet `command:"get"`
56 NNI OltNNIs `command:"nnis"`
57 PON OltPONs `command:"pons"`
58 Shutdown OltShutdown `command:"shutdown"`
59 Poweron OltPoweron `command:"poweron"`
60 Reboot OltReboot `command:"reboot"`
61 Alarms OltAlarmOptions `command:"alarms"`
Pragya Arya8bdb4532020-03-02 17:08:09 +053062 Flows OltFlows `command:"flows"`
Matteo Scandolo8df63df2019-09-12 10:34:32 -070063}
64
65func RegisterOltCommands(parser *flags.Parser) {
66 parser.AddCommand("olt", "OLT Commands", "Commands to query and manipulate the OLT device", &oltOptions{})
67}
68
69func getOLT() *pb.Olt {
70 conn, err := grpc.Dial(config.GlobalConfig.Server, grpc.WithInsecure())
71 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070072 log.Fatalf("did not connect: %v", err)
Matteo Scandolo8df63df2019-09-12 10:34:32 -070073 return nil
74 }
75 defer conn.Close()
76 c := pb.NewBBSimClient(conn)
77
78 // Contact the server and print out its response.
79
80 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
81 defer cancel()
82 olt, err := c.GetOlt(ctx, &pb.Empty{})
83 if err != nil {
Matteo Scandolo2bf742a2019-10-01 11:33:34 -070084 log.Fatalf("could not get OLT: %v", err)
Matteo Scandolo8df63df2019-09-12 10:34:32 -070085 return nil
86 }
87 return olt
88}
89
90func printOltHeader(prefix string, o *pb.Olt) {
91 fmt.Println(fmt.Sprintf("%s : %s", prefix, o.SerialNumber))
92 fmt.Println()
93}
94
Matteo Scandolo8df63df2019-09-12 10:34:32 -070095func (o *OltGet) Execute(args []string) error {
96 olt := getOLT()
97
98 // print out
99 tableFormat := format.Format(DEFAULT_OLT_DEVICE_HEADER_FORMAT)
100 tableFormat.Execute(os.Stdout, true, olt)
101
102 return nil
103}
104
105func (o *OltNNIs) Execute(args []string) error {
106 olt := getOLT()
107
108 printOltHeader("NNI Ports for", olt)
109
110 tableFormat := format.Format(DEFAULT_PORT_HEADER_FORMAT)
111 tableFormat.Execute(os.Stdout, true, olt.NNIPorts)
112
113 return nil
114}
115
116func (o *OltPONs) Execute(args []string) error {
117 olt := getOLT()
118
119 printOltHeader("PON Ports for", olt)
120
121 tableFormat := format.Format(DEFAULT_PORT_HEADER_FORMAT)
122 tableFormat.Execute(os.Stdout, true, olt.PONPorts)
123
124 return nil
125}
Zdravko Bozakov681364d2019-11-10 14:28:46 +0100126
127func (o *OltShutdown) Execute(args []string) error {
128 client, conn := connect()
129 defer conn.Close()
130
131 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
132 defer cancel()
133
134 res, err := client.ShutdownOlt(ctx, &pb.Empty{})
135
136 if err != nil {
137 log.Fatalf("Cannot shut down OLT: %v", err)
138 return err
139 }
140
141 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
142 return nil
143}
144
145func (o *OltPoweron) Execute(args []string) error {
146 client, conn := connect()
147 defer conn.Close()
148
149 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
150 defer cancel()
151
152 res, err := client.PoweronOlt(ctx, &pb.Empty{})
153
154 if err != nil {
155 log.Fatalf("Cannot power on OLT: %v", err)
156 return err
157 }
158
159 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
160 return nil
161}
162
163func (o *OltReboot) Execute(args []string) error {
164 client, conn := connect()
165 defer conn.Close()
166
167 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
168 defer cancel()
169
170 res, err := client.RebootOlt(ctx, &pb.Empty{})
171
172 if err != nil {
173 log.Fatalf("Cannot reboot OLT: %v", err)
174 return err
175 }
176
177 fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message))
178 return nil
179}
Pragya Arya8bdb4532020-03-02 17:08:09 +0530180
181func (o *OltFlows) Execute(args []string) error {
182 client, conn := connect()
183 defer conn.Close()
184
185 ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout)
186 defer cancel()
187
188 req := pb.ONURequest{}
189 res, err := client.GetFlows(ctx, &req)
190 if err != nil {
191 log.Errorf("Cannot get flows for OLT: %v", err)
192 return err
193 }
194
195 if res.Flows == nil {
196 fmt.Println("OLT has no flows")
197 return nil
198 }
199
200 flowHeader := []string{
201 "access_intf_id",
202 "onu_id",
203 "uni_id",
204 "flow_id",
205 "flow_type",
206 "eth_type",
207 "alloc_id",
208 "network_intf_id",
209 "gemport_id",
210 "classifier",
211 "action",
212 "priority",
213 "cookie",
214 "port_no",
215 }
216
217 tableFlow := tablewriter.NewWriter(os.Stdout)
218 tableFlow.SetRowLine(true)
219 fmt.Fprintf(os.Stdout, "OLT Flows:\n")
220 tableFlow.SetHeader(flowHeader)
221
222 for _, flow := range res.Flows {
223 flowInfo := []string{}
224 flowInfo = append(flowInfo,
225 strconv.Itoa(int(flow.AccessIntfId)),
226 strconv.Itoa(int(flow.OnuId)),
227 strconv.Itoa(int(flow.UniId)),
228 strconv.Itoa(int(flow.FlowId)),
229 flow.FlowType,
230 fmt.Sprintf("%x", flow.Classifier.EthType),
231 strconv.Itoa(int(flow.AllocId)),
232 strconv.Itoa(int(flow.NetworkIntfId)),
233 strconv.Itoa(int(flow.GemportId)),
234 flow.Classifier.String(),
235 flow.Action.String(),
236 strconv.Itoa(int(flow.Priority)),
237 strconv.Itoa(int(flow.Cookie)),
238 strconv.Itoa(int(flow.PortNo)),
239 )
240 tableFlow.Append(flowInfo)
241 }
242 tableFlow.Render()
243 tableFlow.SetNewLine("")
244 return nil
245}