[VOL-5291] - pon & nni stats changes, onu stats from OLT, onu stats from onu
Change-Id: I4f23cb1b1276d27ca6f2c183875b8b227f772edd
Signed-off-by: Akash Reddy Kankanala <akash.kankanala@radisys.com>
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
index 6e6d0d3..28fadce 100644
--- a/internal/pkg/commands/command.go
+++ b/internal/pkg/commands/command.go
@@ -21,7 +21,6 @@
"encoding/json"
"errors"
"fmt"
- "io/ioutil"
"log"
"os"
"os/user"
@@ -32,8 +31,8 @@
"strings"
"time"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/jsonpb" //nolint:staticcheck
+ "github.com/golang/protobuf/proto" //nolint:staticcheck
configv1 "github.com/opencord/voltctl/internal/pkg/apis/config/v1"
configv2 "github.com/opencord/voltctl/internal/pkg/apis/config/v2"
configv3 "github.com/opencord/voltctl/internal/pkg/apis/config/v3"
@@ -234,7 +233,7 @@
}
if info, err := os.Stat(GlobalOptions.CommandOptions); err == nil && !info.IsDir() {
- optionsFile, err := ioutil.ReadFile(GlobalOptions.CommandOptions)
+ optionsFile, err := os.ReadFile(GlobalOptions.CommandOptions)
if err != nil {
Error.Fatalf("Unable to read command options configuration file '%s' : %s",
GlobalOptions.CommandOptions, err.Error())
@@ -350,7 +349,7 @@
}
if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
- configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+ configFile, err := os.ReadFile(GlobalOptions.Config)
if err != nil {
Error.Fatalf("Unable to read the configuration file '%s': %s",
GlobalOptions.Config, err.Error())
diff --git a/internal/pkg/commands/completion.go b/internal/pkg/commands/completion.go
index 0052a10..fa66982 100644
--- a/internal/pkg/commands/completion.go
+++ b/internal/pkg/commands/completion.go
@@ -17,6 +17,7 @@
import (
"fmt"
+
flags "github.com/jessevdk/go-flags"
"github.com/opencord/voltctl/internal/pkg/completion"
)
@@ -34,6 +35,6 @@
}
func (options *BashOptions) Execute(args []string) error {
- fmt.Println(completion.Bash)
+ fmt.Print(completion.Bash)
return nil
}
diff --git a/internal/pkg/commands/devices.go b/internal/pkg/commands/devices.go
index ba2b8c2..7d824f4 100644
--- a/internal/pkg/commands/devices.go
+++ b/internal/pkg/commands/devices.go
@@ -110,6 +110,49 @@
DFrames_512To_1023Octets: {{.DFrames_512To_1023Octets}}
DFrames_1024To_1518Octets: {{.DFrames_1024To_1518Octets}}
PmFormat: {{.PmFormat}}`
+ DEFAULT_PON_PORT_STATS_FORMAT = `Pon Port: {{.PonPort}}
+Bip Units: {{.BipUnits}}
+Bip Errors: {{.BipErrors}}
+RxPackets: {{.RxPackets}}
+RxGem: {{.RxGem}}
+RxGemDropped: {{.RxGemDropped}}
+RxGemIdle: {{.RxGemIdle}}
+RxGemCorrected: {{.RxGemCorrected}}
+RxGemIllegal: {{.RxGemIllegal}}
+RxCrcError: {{.RxCrcErrors}}
+RxFragmentError: {{.RxFragmentError}}
+RxPacketsDropped: {{.RxPacketsDropped}}
+RxCpuOmciPacketsDropped: {{.RxCpuOmciPacketsDropped}}
+RxCpu: {{.RxCpu}}
+RxOmci: {{.RxOmci}}
+RxOmciPacketsCrcError: {{.RxOmciPacketsCrcError}}
+TxPackets: {{.TxPackets}}
+TxGem: {{.TxGem}}
+TxCpu: {{.TxCpu}}
+TxOmci: {{.TxOmci}}
+TxDroppedIllegalLength: {{.TxDroppedIllegalLength}}
+TxDroppedTpidMiss: {{.TxDroppedTpidMiss}}
+TxDroppedVidMiss: {{.TxDroppedVidMiss}}
+TxDroppedTotal: {{.TxDroppedTotal}}`
+ DEFAULT_NNI_PORT_STATS_FORMAT = `Nni Port: {{.NniPort}}
+RxBytes: {{.RxBytes}}
+RxPackets: {{.RxPackets}}
+RxUcastPackets: {{.RxUcastPackets}}
+RxMcastPackets: {{.RxMcastPackets}}
+RxBcastPackets: {{.RxBcastPackets}}
+RxErrorPackets: {{.RxErrorPackets}}
+RxFcsErrorPackets: {{.RxFcsErrorPackets}}
+RxUndersizePackets: {{.RxUndersizePackets}}
+RxOversizePackets: {{.RxOversizePackets}}
+TxBytes: {{.TxBytes}}
+TxPackets: {{.TxPackets}}
+TxUcastPackets: {{.TxUcastPackets}}
+TxMcastPackets: {{.TxMcastPackets}}
+TxBcastPackets: {{.TxBcastPackets}}
+TxErrorPackets: {{.TxErrorPackets}}
+TxUndersizePackets: {{.TxUndersizePackets}}
+TxOversizePackets: {{.TxOversizePackets}}`
+
DEFAULT_ONU_OMCI_TX_RX_STATS_FORMAT = `BaseTxArFrames: {{.BaseTxArFrames}}
BaseRxAkFrames: {{.BaseRxAkFrames}}
BaseTxNoArFrames: {{.BaseTxNoArFrames}}
@@ -120,10 +163,28 @@
ExtRxNoAkFrames: {{.ExtRxNoAkFrames}}
TxOmciCounterRetries: {{.TxOmciCounterRetries}}
TxOmciCounterTimeouts: {{.TxOmciCounterTimeouts}}`
- DEFAULT_DEVICE_ALARMS_FORMAT = "table{{ .ClassId }}\t{{.InstanceId}}\t{{.Name}}\t{{.Description}}"
- DEFAULT_DEVICE_ALARMS_ORDER = "ClassId,InstanceId"
- DEFAULT_PON_RX_POWER_STATUS_FORMAT = "table{{.OnuSn}}\t{{.Status}}\t{{.FailReason}}\t{{.RxPower}}\t"
- DEFAULT_ONU_DISTANCE_FORMAT = `Distance`
+ DEFAULT_ONU_STATS_FROM_OLT_FORMAT = `AllocId: {{.AllocId}}
+AllocRxBytes: {{.AllocRxBytes}}
+{{range .GemPortStats}}
+-GemId: {{.GemId}}
+ RxPackets: {{.RxPackets}}
+ RxBytes: {{.RxBytes}}
+ TxPackets: {{.TxPackets}}
+ TxBytes: {{.TxBytes}}{{end}}`
+
+ DEFAULT_ONU_DISTANCE_FORMAT = `Distance`
+ DEFAULT_DEVICE_ALARMS_FORMAT = "table{{ .ClassId }}\t{{.InstanceId}}\t{{.Name}}\t{{.Description}}"
+ DEFAULT_DEVICE_ALARMS_ORDER = "ClassId,InstanceId"
+ DEFAULT_PON_RX_POWER_STATUS_FORMAT = "table{{.OnuSn}}\t{{.Status}}\t{{.FailReason}}\t{{.RxPower}}\t"
+ DEFAULT_DEVICE_VALUE_GEM_PORT_FORMAT = `AllocId: {{.AllocId}}
+ AllocRxBytes: {{.AllocRxBytes}}
+ {{range .GemHistoryStats}}
+-GemId: {{.GemId}}
+ TransmittedGEMFrames: {{.TransmittedGEMFrames}}
+ ReceivedGEMFrames: {{.ReceivedGEMFrames}}
+ ReceivedPayloadBytes: {{.ReceivedPayloadBytes}}
+ TransmittedPayloadBytes:{{.TransmittedPayloadBytes}}
+ EncryptionKeyErrors: {{.EncryptionKeyErrors}}{{end}}`
)
type DeviceList struct {
@@ -454,6 +515,30 @@
} `positional-args:"yes"`
}
+type GetPonPortStats struct {
+ ListOutputOptions
+ Reset bool `long:"reset" description:"Reset the counters"`
+ Args struct {
+ Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+ PortLabel string `positional-arg-name:"PORT_LABEL" required:"yes"`
+ } `positional-args:"yes"`
+}
+
+type GetNniPortStats struct {
+ ListOutputOptions
+ Reset bool `long:"reset" description:"Reset the counters"`
+ Args struct {
+ Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+ PortLabel string `positional-arg-name:"PORT_LABEL" required:"yes"`
+ } `positional-args:"yes"`
+}
+
+type GetOnuAllocGemStatsFromOlt struct {
+ ListOutputOptions
+ Args struct {
+ Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+ } `positional-args:"yes"`
+}
type RxPower struct {
ListOutputOptions
Args struct {
@@ -486,6 +571,13 @@
} `positional-args:"yes"`
}
+type GetOnuGEMStats struct {
+ ListOutputOptions
+ Args struct {
+ Id DeviceId `positional-arg-name:"DEVICE_ID" required:"yes"`
+ } `positional-args:"yes"`
+}
+
type GetOnuDistance struct {
ListOutputOptions
Args struct {
@@ -560,6 +652,10 @@
PonRxPower PonRxPower `command:"pon_rx_power"`
OnuDistance GetOnuDistance `command:"onu_distance"`
OffloadAppStats GetOffloadApp `command:"offload_app_stats"`
+ PonStats GetPonPortStats `command:"itu_pon_stats"`
+ NniStats GetNniPortStats `command:"nni_statistics"`
+ OnuGEMStats GetOnuGEMStats `command:"onu_gem_stats"`
+ OnuAllocGemStats GetOnuAllocGemStatsFromOlt `command:"onu_alloc_gem_from_olt"`
} `command:"getextval"`
SetExtVal struct {
OffloadAppStatsSet SetOffloadApp `command:"set_offload_app"`
@@ -567,6 +663,38 @@
} `command:"setextval"`
}
+type AllocGemStatsFromOlt struct {
+ AllocId uint32
+ AllocRxBytes uint64
+ GemPortStats []GemPortStatsFromOlt
+}
+type GemPortStatsFromOlt struct {
+ GemId uint32
+ RxPackets uint64
+ RxBytes uint64
+ TxPackets uint64
+ TxBytes uint64
+}
+type onugemstats struct {
+ AllocId uint32
+ AllocRxBytes uint32
+ GemHistoryStats []gemHistoryStats
+}
+type gemHistoryStats struct {
+ GemId uint32
+ TransmittedGEMFrames uint32
+ ReceivedGEMFrames uint32
+ ReceivedPayloadBytes uint32
+ TransmittedPayloadBytes uint32
+ EncryptionKeyErrors uint32
+}
+
+type PortStats struct {
+ PonPort uint32 // use this for PON
+ NniPort uint32 // use this for NNI
+ *common.PortStatistics
+}
+
var deviceOpts = DeviceOpts{}
func RegisterDeviceCommands(parser *flags.Parser) {
@@ -2349,6 +2477,104 @@
}
}
+func (options *GetPonPortStats) Execute(args []string) error {
+ conn, err := NewConnection()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+ client := extension.NewExtensionClient(conn)
+
+ singleGetValReq := extension.SingleGetValueRequest{
+ TargetId: string(options.Args.Id),
+ Request: &extension.GetValueRequest{
+ Request: &extension.GetValueRequest_OltPonStats{
+ OltPonStats: &extension.GetPonStatsRequest{
+ PortInfo: &extension.GetPonStatsRequest_PortLabel{
+ PortLabel: options.Args.PortLabel,
+ },
+ },
+ },
+ },
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+ defer cancel()
+ rv, err := client.GetExtValue(ctx, &singleGetValReq)
+ if err != nil {
+ Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+ return err
+ }
+
+ if rv.Response.Status != extension.GetValueResponse_OK {
+ return fmt.Errorf("failed to get pon port stats %v", rv.Response.ErrReason.String())
+ }
+ outputFormat := CharReplacer.Replace(options.Format)
+ if outputFormat == "" {
+ outputFormat = GetCommandOptionWithDefault("device-get-pon-stats", "format", DEFAULT_PON_PORT_STATS_FORMAT)
+ }
+ data := PortStats{
+ PonPort: rv.GetResponse().GetOltPonStatsResponse().GetPonPort(),
+ PortStatistics: rv.GetResponse().GetOltPonStatsResponse().GetPortStatistics(),
+ }
+ result := CommandResult{
+ Format: format.Format(outputFormat),
+ OutputAs: toOutputType(options.OutputAs),
+ NameLimit: options.NameLimit,
+ Data: data,
+ }
+ GenerateOutput(&result)
+ return nil
+}
+
+func (options *GetNniPortStats) Execute(args []string) error {
+ conn, err := NewConnection()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+ client := extension.NewExtensionClient(conn)
+
+ singleGetValReq := extension.SingleGetValueRequest{
+ TargetId: string(options.Args.Id),
+ Request: &extension.GetValueRequest{
+ Request: &extension.GetValueRequest_OltNniStats{
+ OltNniStats: &extension.GetNNIStatsRequest{
+ PortInfo: &extension.GetNNIStatsRequest_PortLabel{
+ PortLabel: options.Args.PortLabel,
+ },
+ },
+ },
+ },
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+ defer cancel()
+ rv, err := client.GetExtValue(ctx, &singleGetValReq)
+ if err != nil {
+ Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+ return err
+ }
+
+ if rv.Response.Status != extension.GetValueResponse_OK {
+ return fmt.Errorf("failed to get nni port stats %v", rv.Response.ErrReason.String())
+ }
+ outputFormat := CharReplacer.Replace(options.Format)
+ if outputFormat == "" {
+ outputFormat = GetCommandOptionWithDefault("device-get-nni-stats", "format", DEFAULT_NNI_PORT_STATS_FORMAT)
+ }
+ data := PortStats{
+ NniPort: rv.GetResponse().GetOltNniStatsResponse().GetNniPort(),
+ PortStatistics: rv.GetResponse().GetOltNniStatsResponse().GetPortStatistics(),
+ }
+ result := CommandResult{
+ Format: format.Format(outputFormat),
+ OutputAs: toOutputType(options.OutputAs),
+ NameLimit: options.NameLimit,
+ Data: data,
+ }
+ GenerateOutput(&result)
+ return nil
+}
+
func (options *GetOnuEthernetFrameExtendedPmCounters) Execute(args []string) error {
conn, err := NewConnection()
if err != nil {
@@ -2789,3 +3015,123 @@
GenerateOutput(&result)
return nil
}
+
+func (options *GetOnuGEMStats) Execute(args []string) error {
+
+ conn, err := NewConnection()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+ client := extension.NewExtensionClient(conn)
+ singleGetValReq := extension.SingleGetValueRequest{
+ TargetId: string(options.Args.Id),
+ Request: &extension.GetValueRequest{
+ Request: &extension.GetValueRequest_OnuAllocGemStats{
+ OnuAllocGemStats: &extension.GetOnuAllocGemHistoryRequest{},
+ },
+ },
+ }
+
+ ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+ defer cancel()
+
+ rv, err := client.GetExtValue(ctx, &singleGetValReq)
+
+ if err != nil {
+ Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+ return err
+ }
+
+ if rv.Response.Status != extension.GetValueResponse_OK {
+ return fmt.Errorf("failed to get gem port response %v", rv.Response.ErrReason.String())
+ }
+ outputFormat := CharReplacer.Replace(options.Format)
+ if outputFormat == "" {
+ outputFormat = GetCommandOptionWithDefault("device-get-gem-port", "format", DEFAULT_DEVICE_VALUE_GEM_PORT_FORMAT)
+ }
+ onugemhistoryresponse := rv.GetResponse().GetOnuAllocGemStatsResponse()
+ for _, OnuallocGemHistoryData := range onugemhistoryresponse.OnuAllocGemHistoryData {
+ data := onugemstats{}
+ data.AllocId = OnuallocGemHistoryData.OnuAllocIdInfo.AllocId
+ data.AllocRxBytes = OnuallocGemHistoryData.OnuAllocIdInfo.RxBytes
+ for _, gemStatsInfo := range OnuallocGemHistoryData.GemPortInfo {
+ data.GemHistoryStats = append(data.GemHistoryStats, gemHistoryStats{
+ GemId: gemStatsInfo.GemId,
+ TransmittedGEMFrames: gemStatsInfo.TransmittedGEMFrames,
+ ReceivedGEMFrames: gemStatsInfo.ReceivedGEMFrames,
+ ReceivedPayloadBytes: gemStatsInfo.ReceivedPayloadBytes,
+ TransmittedPayloadBytes: gemStatsInfo.TransmittedPayloadBytes,
+ EncryptionKeyErrors: gemStatsInfo.EncryptionKeyErrors,
+ })
+ }
+ result := CommandResult{
+ Format: format.Format(outputFormat),
+ OutputAs: toOutputType(options.OutputAs),
+ NameLimit: options.NameLimit,
+ Data: &data,
+ }
+ GenerateOutput(&result)
+ }
+ return nil
+
+}
+
+func (options *GetOnuAllocGemStatsFromOlt) Execute(args []string) error {
+ conn, err := NewConnection()
+ if err != nil {
+ return err
+ }
+ defer conn.Close()
+ client := extension.NewExtensionClient(conn)
+
+ singleGetValReq := extension.SingleGetValueRequest{
+ TargetId: string(options.Args.Id),
+ Request: &extension.GetValueRequest{
+ Request: &extension.GetValueRequest_OnuStatsFromOlt{
+ OnuStatsFromOlt: &extension.GetOnuStatsFromOltRequest{},
+ },
+ },
+ }
+ ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
+ defer cancel()
+ rv, err := client.GetExtValue(ctx, &singleGetValReq)
+ if err != nil {
+ Error.Printf("Error getting value on device Id %s,err=%s\n", options.Args.Id, ErrorToString(err))
+ return err
+ }
+
+ if rv.Response.Status != extension.GetValueResponse_OK {
+ return fmt.Errorf("failed to get onu alloc gem stats from olt %v", rv.Response.ErrReason.String())
+ }
+ outputFormat := CharReplacer.Replace(options.Format)
+ if outputFormat == "" {
+ outputFormat = GetCommandOptionWithDefault("device-get-onu-status", "format", DEFAULT_ONU_STATS_FROM_OLT_FORMAT)
+ }
+
+ onuAllocGemStatsResponse := rv.GetResponse().GetOnuStatsFromOltResponse()
+
+ for _, allocGemStatsInfo := range onuAllocGemStatsResponse.AllocGemStatsInfo {
+ data := AllocGemStatsFromOlt{}
+ data.AllocId = allocGemStatsInfo.AllocIdInfo.AllocId
+ data.AllocRxBytes = allocGemStatsInfo.AllocIdInfo.RxBytes
+ for _, gemStatsInfo := range allocGemStatsInfo.GemPortInfo {
+ data.GemPortStats = append(data.GemPortStats, GemPortStatsFromOlt{
+ GemId: gemStatsInfo.GemId,
+ RxBytes: gemStatsInfo.RxBytes,
+ RxPackets: gemStatsInfo.RxPackets,
+ TxBytes: gemStatsInfo.TxBytes,
+ TxPackets: gemStatsInfo.TxPackets,
+ })
+ }
+ result := CommandResult{
+ Format: format.Format(outputFormat),
+ OutputAs: toOutputType(options.OutputAs),
+ NameLimit: options.NameLimit,
+ Data: &data,
+ }
+ GenerateOutput(&result)
+ }
+
+ return nil
+}
diff --git a/internal/pkg/commands/events.go b/internal/pkg/commands/events.go
index cc149d6..22047f1 100644
--- a/internal/pkg/commands/events.go
+++ b/internal/pkg/commands/events.go
@@ -26,8 +26,8 @@
"time"
"github.com/Shopify/sarama"
- "github.com/golang/protobuf/jsonpb"
- "github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/jsonpb" //nolint:staticcheck
+ "github.com/golang/protobuf/proto" //nolint:staticcheck
"github.com/golang/protobuf/ptypes/timestamp"
flags "github.com/jessevdk/go-flags"
"github.com/opencord/voltctl/pkg/filter"
diff --git a/internal/pkg/commands/handler.go b/internal/pkg/commands/handler.go
index 0c6d32b..00a0aca 100644
--- a/internal/pkg/commands/handler.go
+++ b/internal/pkg/commands/handler.go
@@ -16,12 +16,13 @@
package commands
import (
- "github.com/golang/protobuf/proto"
+ "io"
+
+ "github.com/golang/protobuf/proto" //nolint:staticcheck
"github.com/jhump/protoreflect/desc"
"github.com/jhump/protoreflect/dynamic"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
- "io"
)
type RpcEventHandler struct {
@@ -54,7 +55,7 @@
return err
}
- if h.Fields == nil || len(h.Fields) == 0 {
+ if len(h.Fields) == 0 {
return io.EOF
}
diff --git a/internal/pkg/commands/log.go b/internal/pkg/commands/log.go
index 56c27cd..2390e02 100644
--- a/internal/pkg/commands/log.go
+++ b/internal/pkg/commands/log.go
@@ -97,7 +97,7 @@
} `positional-args:"yes" required:"yes"`
}
-// EnableLogTracingOpts represents the supported CLI arguments for the log tracing enable command
+// EnableLogTracingOpts represents the supported CLI arguments for the log tracing enable command
type EnableLogTracingOpts struct {
OutputOptions
Args struct {
@@ -105,7 +105,7 @@
} `positional-args:"yes" required:"yes"`
}
-// DisableLogTracingOpts represents the supported CLI arguments for the log tracing disable command
+// DisableLogTracingOpts represents the supported CLI arguments for the log tracing disable command
type DisableLogTracingOpts struct {
OutputOptions
Args struct {
@@ -113,7 +113,7 @@
} `positional-args:"yes" required:"yes"`
}
-// ListLogTracingOpts represents the supported CLI arguments for the log tracing list command
+// ListLogTracingOpts represents the supported CLI arguments for the log tracing list command
type ListLogTracingOpts struct {
ListOutputOptions
Args struct {
@@ -575,7 +575,7 @@
logLevelConfig, err = processComponentListArgs(toStringArray(options.Args.Component))
if err != nil {
- return fmt.Errorf(err.Error())
+ return err
}
ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().KvStoreConfig.Timeout)