| /* |
| * Portions Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors |
| * Original copyright 2019-present Ciena Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package commands |
| |
| import ( |
| "context" |
| "fmt" |
| "os" |
| "strconv" |
| "strings" |
| |
| "github.com/jessevdk/go-flags" |
| pb "github.com/opencord/bbsim/api/bbsim" |
| "github.com/opencord/bbsim/internal/bbsimctl/config" |
| "github.com/opencord/cordctl/pkg/format" |
| log "github.com/sirupsen/logrus" |
| ) |
| |
| const ( |
| DEFAULT_UNI_HEADER_FORMAT = "table{{ .OnuSn }}\t{{ .OnuID }}\t{{ .ID }}\t{{ .MeID }}\t{{ .PortNo }}\t{{ .OperState }}\t{{ .Type }}" |
| DEFAULT_UNI_HEADER_FORMAT_WITH_SERVICES = "table{{ .OnuSn }}\t{{ .OnuID }}\t{{ .ID }}\t{{ .MeID }}\t{{ .PortNo }}\t{{ .OperState }}\t{{ .Type }}\t{{ .Services }}" |
| ) |
| |
| type UniIdInt string |
| |
| type UNIList struct { |
| Verbose bool `short:"v" long:"verbose" description:"Print all the Unis from all the ONUs"` |
| } |
| |
| type UNIGet struct { |
| Verbose bool `short:"v" long:"verbose" description:"Print all the informations we have about UNIs"` |
| Args struct { |
| OnuSn OnuSnString |
| } `positional-args:"yes" required:"yes"` |
| } |
| |
| type UNIServices struct { |
| Verbose bool `short:"v" long:"verbose" description:"Print all the Services from the specified UNI"` |
| Args struct { |
| OnuSn OnuSnString |
| UniId UniIdInt |
| } `positional-args:"yes"` |
| } |
| |
| type UNIEapolRestart struct { |
| Args struct { |
| OnuSn OnuSnString |
| UniId UniIdInt |
| } `positional-args:"yes" required:"yes"` |
| } |
| |
| type UNIDhcpRestart struct { |
| Args struct { |
| OnuSn OnuSnString |
| UniId UniIdInt |
| } `positional-args:"yes" required:"yes"` |
| } |
| |
| type UNIOptions struct { |
| List UNIList `command:"list"` |
| Get UNIGet `command:"get"` |
| Services UNIServices `command:"services"` |
| RestartEapol UNIEapolRestart `command:"auth_restart"` |
| RestartDchp UNIDhcpRestart `command:"dhcp_restart"` |
| } |
| |
| func RegisterUNICommands(parser *flags.Parser) { |
| _, _ = parser.AddCommand("uni", "UNI Commands", "Commands to query and manipulate UNIs", &UNIOptions{}) |
| } |
| |
| func (options *UNIList) Execute(args []string) error { |
| client, conn := connect() |
| defer conn.Close() |
| |
| // Contact the server and print out its response. |
| ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout) |
| defer cancel() |
| |
| unis, err := client.GetUnis(ctx, &pb.Empty{}) |
| if err != nil { |
| log.Fatalf("could not get UNIs: %v", err) |
| return err |
| } |
| |
| var tableFormat format.Format |
| if options.Verbose { |
| tableFormat = format.Format(DEFAULT_UNI_HEADER_FORMAT_WITH_SERVICES) |
| } else { |
| tableFormat = format.Format(DEFAULT_UNI_HEADER_FORMAT) |
| } |
| if err := tableFormat.Execute(os.Stdout, true, unis.Items); err != nil { |
| log.Fatalf("Error while formatting Unis table: %s", err) |
| } |
| |
| return nil |
| } |
| |
| func (options *UNIGet) Execute(args []string) error { |
| |
| client, conn := connect() |
| defer conn.Close() |
| |
| ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout) |
| defer cancel() |
| req := pb.ONURequest{ |
| SerialNumber: string(options.Args.OnuSn), |
| } |
| res, err := client.GetOnuUnis(ctx, &req) |
| |
| if err != nil { |
| log.Fatalf("Cannot not get unis for ONU %s: %v", options.Args.OnuSn, err) |
| return err |
| } |
| |
| var tableFormat format.Format |
| if options.Verbose { |
| tableFormat = format.Format(DEFAULT_UNI_HEADER_FORMAT_WITH_SERVICES) |
| } else { |
| tableFormat = format.Format(DEFAULT_UNI_HEADER_FORMAT) |
| } |
| if err := tableFormat.Execute(os.Stdout, true, res.Items); err != nil { |
| log.Fatalf("Error while formatting Unis table: %s", err) |
| } |
| |
| return nil |
| } |
| |
| // Get Services for specified UNI |
| // First get UNIs from specified ONU SN |
| // Then get Services from appropriate UNI |
| func (options *UNIServices) Execute(args []string) error { |
| services, err := getServices(string(options.Args.OnuSn), string(options.Args.UniId)) |
| |
| if err != nil { |
| log.Fatalf("Cannot not get services for ONU %s and UNI %s: %v", options.Args.OnuSn, options.Args.UniId, err) |
| return err |
| } |
| |
| tableFormat := format.Format(DEFAULT_SERVICE_HEADER_FORMAT) |
| if err := tableFormat.Execute(os.Stdout, true, services.Items); err != nil { |
| log.Fatalf("Error while formatting ONUs table: %s", err) |
| } |
| |
| return nil |
| } |
| |
| func (options *UNIEapolRestart) Execute(args []string) error { |
| client, conn := connect() |
| defer conn.Close() |
| |
| ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout) |
| defer cancel() |
| |
| req := pb.UNIRequest{ |
| OnuSerialNumber: string(options.Args.OnuSn), |
| UniID: string(options.Args.UniId), |
| } |
| res, err := client.RestartEapol(ctx, &req) |
| |
| if err != nil { |
| log.Fatalf("Cannot restart EAPOL for ONU %s and UNI %s: %v", options.Args.OnuSn, options.Args.UniId, err) |
| return err |
| } |
| |
| fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message)) |
| |
| return nil |
| } |
| |
| func (options *UNIDhcpRestart) Execute(args []string) error { |
| client, conn := connect() |
| defer conn.Close() |
| |
| ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout) |
| defer cancel() |
| |
| req := pb.UNIRequest{ |
| OnuSerialNumber: string(options.Args.OnuSn), |
| UniID: string(options.Args.UniId), |
| } |
| res, err := client.RestartDhcp(ctx, &req) |
| |
| if err != nil { |
| log.Fatalf("Cannot restart DHCP for ONU %s and UNI %s: %v", options.Args.OnuSn, options.Args.UniId, err) |
| return err |
| } |
| |
| fmt.Println(fmt.Sprintf("[Status: %d] %s", res.StatusCode, res.Message)) |
| |
| return nil |
| } |
| |
| func (uniId *UniIdInt) Complete(match string) []flags.Completion { |
| client, conn := connect() |
| defer conn.Close() |
| |
| ctx, cancel := context.WithTimeout(context.Background(), config.GlobalConfig.Grpc.Timeout) |
| defer cancel() |
| |
| onus, err := client.GetONUs(ctx, &pb.Empty{}) |
| if err != nil { |
| log.Fatalf("could not get ONUs: %v", err) |
| return nil |
| } |
| |
| // go-flag doesn't allow us to read the previous parameters to the command so we can't get the ONU Serial Number, |
| // but since all the ONUs have the same number of UNIs thus we can re-use the UNIs belonging to the first ONU in the list |
| // pending issue here https://github.com/jessevdk/go-flags/issues/305 |
| unis := onus.Items[0].Unis |
| |
| list := make([]flags.Completion, 0) |
| for _, uni := range unis { |
| strID := strconv.Itoa(int(uni.ID)) |
| if strings.HasPrefix(strID, match) { |
| list = append(list, flags.Completion{Item: strID}) |
| } |
| } |
| |
| return list |
| } |