blob: 6bf85c0b66ee2a0433bf66f68a41620629d48d73 [file] [log] [blame]
/*
* Copyright 2022-present Open Networking Foundation
* 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 format
import (
"encoding/json"
"io"
"log"
"github.com/guumaster/tablewriter"
app "voltha-go-controller/internal/pkg/application"
"voltha-go-controller/voltha-go-controller/cli/database"
"voltha-go-controller/voltha-go-controller/cli/models"
"voltha-go-controller/voltha-go-controller/nbi"
)
type verticalTable struct {
title models.TableTitle
writer *tablewriter.Table
}
func newVerticalTable(title models.TableTitle, outputBuffer io.Writer) Table {
vt := verticalTable{}
vt.title = title
vt.writer = tablewriter.NewWriter(outputBuffer)
vt.writer.SetAlignment(tablewriter.ALIGN_LEFT)
return &vt
}
func (vt *verticalTable) SingleEntry(config *database.Data) {
configs := make(map[string]*database.Data, 1)
configs["singleEntry"] = config
vt.MultipleEntries(configs)
}
func (vt *verticalTable) SingleDataEntry(config map[string]map[string]bool) {
vt.MultipleDataEntries(config)
}
func (vt *verticalTable) SingleIcmpDataEntry(config map[string]map[string]int) {
vt.MultipleIcmpDataEntries(config)
}
func (vt *verticalTable) SinglePortDataEntry(config map[string][]*app.VoltPort) {
vt.MultiplePortDataEntries(config)
}
func (vt *verticalTable) SinglePonPortDataEntry(config map[string][]*app.PonPortCfg) {
vt.MultiplePonPortDataEntries(config)
}
func (vt *verticalTable) SingleDeviceTaskList(config map[string]map[int]*app.TaskInfo) {
vt.MultipleDeviceTaskList(config)
}
func (vt *verticalTable) SingleDeviceInfo(config map[string]map[string]*nbi.DeviceInfo) {
vt.MultipleDeviceInfo(config)
}
func (vt *verticalTable) SingleDhcpSessionInfo(config []*nbi.DhcpSessionInfo) {
vt.MultipleDhcpSessionInfo(config)
}
func (vt *verticalTable) MultipleEntries(configs map[string]*database.Data) {
var rows [][]string
isMultiline := len(configs) > 1
for key, value := range configs {
var data map[string]interface{}
err := json.Unmarshal(value.Value, &data)
if err != nil {
log.Fatalf("Data saved in database seems to be corrupted: %s", err)
}
sortedData := sortData(data)
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
for i := range sortedData {
parseAndAppendRowNew(vt.writer, sortedData[i].Key, sortedData[i].Value, "", &rows)
}
if isMultiline {
vt.writer.AddSeparator()
}
}
vt.writer.Render()
}
// Formatting for Cache API commands
func (vt *verticalTable) MultipleDataEntries(configs map[string]map[string]bool) {
var rows [][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendHeaderRowForAPICmd(vt.writer, "DeviceID", "vlan", "status", "", &rows)
vt.writer.AddSeparator()
for key, value := range configs {
data := value
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
for k, v := range data {
parseAndAppendRowNewForAPICmd(vt.writer, key, k, v, "", &rows)
}
if isMultiline {
vt.writer.AddSeparator()
}
}
vt.writer.Render()
}
// Formatting for Cache API commands
func (vt *verticalTable) MultipleIcmpDataEntries(configs map[string]map[string]int) {
var rows [][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendHeaderRowForAPICmd(vt.writer, "DeviceID", "vlan", "status", "", &rows)
vt.writer.AddSeparator()
for key, value := range configs {
data := value
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
for k, v := range data {
parseAndAppendRowNewForIcmpAPICmd(vt.writer, key, k, v, "", &rows)
}
if isMultiline {
vt.writer.AddSeparator()
}
}
vt.writer.Render()
}
// Formatting for API based task list commands
func (vt *verticalTable) MultipleDeviceTaskList(configs map[string]map[int]*app.TaskInfo) {
var rows [][][][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendHeaderRowForTaskList(vt.writer, "DeviceID", "Position", "Task-ID", "Task-Name", "Timestamp", "", &rows)
vt.writer.AddSeparator()
for key, value := range configs {
data := value
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
for k, v := range data {
parseAndAppendRowNewForTaskList(vt.writer, key, k, v.ID, v.Name, v.Timestamp, "", &rows)
}
if isMultiline {
vt.writer.AddSeparator()
}
}
vt.writer.Render()
}
// Formatting for Port Cache API command
func (vt *verticalTable) MultiplePortDataEntries(configs map[string][]*app.VoltPort) {
// update in case voltPort is updated.
var rows [][][][][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendHeaderRowForPortAPI(vt.writer, "DeviceID", "ID", "Name", "Device", "Type", "State", "ActiveChannelCount", "", &rows)
vt.writer.AddSeparator()
for key, value := range configs {
data := value
for i := range data {
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
var portType string
var portState string
// Checking for port type
if data[i].Type == 0 {
portType = "Access Port"
} else {
portType = "NNI port"
}
// Checking for port state
if data[i].State == 0 {
portState = "DOWN"
} else {
portState = "UP"
}
parseAndAppendRowNewForPortAPI(vt.writer, key, data[i].ID, data[i].Name, data[i].Device, portType, portState, data[i].ActiveChannels, "", &rows)
if isMultiline {
vt.writer.AddSeparator()
}
}
}
vt.writer.Render()
}
// Formatting for PON Port API command
func (vt *verticalTable) MultiplePonPortDataEntries(configs map[string][]*app.PonPortCfg) {
// update in case voltPort is updated.
var rows [][][][][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendHeaderRowForPonPortAPI(vt.writer, "DeviceID", "PONID", "McastKPIsFlag", "MaxActiveChannels", "CurrActiveChannels", "", &rows)
vt.writer.AddSeparator()
for key, value := range configs {
data := value
for i := range data {
if isMultiline {
vt.writer.Append([]string{"ID", key})
vt.writer.AddSeparator()
}
parseAndAppendNewRowForPonPortAPI(vt.writer, key, data[i].PortID, data[i].EnableMulticastKPI, data[i].MaxActiveChannels, data[i].ActiveIGMPChannels, "", &rows)
if isMultiline {
vt.writer.AddSeparator()
}
}
}
vt.writer.Render()
}
// Formatting for API based device info commands
func (vt *verticalTable) MultipleDeviceInfo(configs map[string]map[string]*nbi.DeviceInfo) {
var rows [][][][][]string
isMultiline := len(configs) > 1
// adding table header
parseAndAppendRowNewForDeviceInfo(vt.writer, "DeviceID", "Serial Number", "State", "", &rows)
vt.writer.AddSeparator()
for deviceID, data := range configs {
if isMultiline {
vt.writer.Append([]string{"ID", deviceID})
vt.writer.AddSeparator()
}
for serialNum, deviceInfo := range data {
if isMultiline {
vt.writer.AddSeparator()
}
parseAndAppendRowNewForDeviceInfo(vt.writer, deviceID, serialNum, deviceInfo.State, "", &rows)
if isMultiline {
vt.writer.AddSeparator()
}
}
}
vt.writer.Render()
}
// Formatting for Api based DHCP session command
func (vt *verticalTable) MultipleDhcpSessionInfo(value []*nbi.DhcpSessionInfo) {
var rows [][][][][][][][][][][][]string
isMultiline := len(value) > 1
// adding table header
parseAndAppendRowNewForDhcpCmd(vt.writer, "DeviceID", "UniPort", "SVlan", "CVlan", "UniVlan", "MacAddress", "IpAddress", "IPv6Address", "State-DHCPv4", "State-DHCP-v6", "LeaseTime IPv4", "LeaseTime IPv6", "", &rows)
vt.writer.AddSeparator()
for i := range value {
if isMultiline {
vt.writer.AddSeparator()
}
var rState string
var rStatev6 string
// Checking for state-DHCPv4
if value[i].State == "0" {
rState = "None"
} else if value[i].State == "1" {
rState = "Discover"
} else if value[i].State == "2" {
rState = "Offer"
} else if value[i].State == "3" {
rState = "Request"
} else if value[i].State == "4" {
rState = "Ack"
} else if value[i].State == "5" {
rState = "NAK"
} else if value[i].State == "6" {
rState = "Release"
}
// Checking for state-DHCPv6
if value[i].Statev6 == "0" {
rStatev6 = "None"
} else if value[i].Statev6 == "1" {
rStatev6 = "Solicit"
} else if value[i].Statev6 == "2" {
rStatev6 = "Reply"
} else if value[i].Statev6 == "3" {
rStatev6 = "Release"
}
parseAndAppendRowNewForDhcpCmd(vt.writer, value[i].DeviceID, value[i].Uniport, value[i].Svlan, value[i].Cvlan, value[i].UniVlan, value[i].MacAddress, value[i].IPAddress, value[i].Ipv6Address, rState, rStatev6, value[i].LeaseTime, value[i].LeaseTimev6, "", &rows)
}
vt.writer.Render()
}