mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
99 lines
2.7 KiB
Go
99 lines
2.7 KiB
Go
// SPDX-FileCopyrightText: 2022 Free Mobile
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
package console
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"akvorado/common/helpers"
|
|
"akvorado/console/filter"
|
|
)
|
|
|
|
type queryColumn int
|
|
|
|
func (gc queryColumn) MarshalText() ([]byte, error) {
|
|
got, ok := queryColumnMap.LoadValue(gc)
|
|
if ok {
|
|
return []byte(got), nil
|
|
}
|
|
return nil, errors.New("unknown field")
|
|
}
|
|
func (gc queryColumn) String() string {
|
|
got, _ := queryColumnMap.LoadValue(gc)
|
|
return got
|
|
}
|
|
func (gc *queryColumn) UnmarshalText(input []byte) error {
|
|
got, ok := queryColumnMap.LoadKey(string(input))
|
|
if ok {
|
|
*gc = got
|
|
return nil
|
|
}
|
|
return errors.New("unknown field")
|
|
}
|
|
|
|
type queryFilter struct {
|
|
filter string
|
|
reverseFilter string
|
|
mainTableRequired bool
|
|
}
|
|
|
|
func (gf queryFilter) String() string {
|
|
return gf.filter
|
|
}
|
|
func (gf queryFilter) MarshalText() ([]byte, error) {
|
|
return []byte(gf.filter), nil
|
|
}
|
|
func (gf *queryFilter) UnmarshalText(input []byte) error {
|
|
if strings.TrimSpace(string(input)) == "" {
|
|
*gf = queryFilter{}
|
|
return nil
|
|
}
|
|
meta := &filter.Meta{}
|
|
direct, err := filter.Parse("", input, filter.GlobalStore("meta", meta))
|
|
if err != nil {
|
|
return fmt.Errorf("cannot parse filter: %s", filter.HumanError(err))
|
|
}
|
|
meta = &filter.Meta{ReverseDirection: true}
|
|
reverse, err := filter.Parse("", input, filter.GlobalStore("meta", meta))
|
|
*gf = queryFilter{
|
|
filter: direct.(string),
|
|
reverseFilter: reverse.(string),
|
|
mainTableRequired: meta.MainTableRequired,
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// toSQLSelect transforms a column into an expression to use in SELECT
|
|
func (gc queryColumn) toSQLSelect() string {
|
|
var strValue string
|
|
switch gc {
|
|
case queryColumnExporterAddress, queryColumnSrcAddr, queryColumnDstAddr:
|
|
strValue = fmt.Sprintf("replaceRegexpOne(IPv6NumToString(%s), '^::ffff:', '')", gc)
|
|
case queryColumnSrcAS, queryColumnDstAS:
|
|
strValue = fmt.Sprintf(`concat(toString(%s), ': ', dictGetOrDefault('asns', 'name', %s, '???'))`,
|
|
gc, gc)
|
|
case queryColumnEType:
|
|
strValue = fmt.Sprintf(`if(EType = %d, 'IPv4', if(EType = %d, 'IPv6', '???'))`,
|
|
helpers.ETypeIPv4, helpers.ETypeIPv6)
|
|
case queryColumnProto:
|
|
strValue = `dictGetOrDefault('protocols', 'name', Proto, '???')`
|
|
case queryColumnInIfSpeed, queryColumnOutIfSpeed, queryColumnSrcPort, queryColumnDstPort, queryColumnForwardingStatus, queryColumnInIfBoundary, queryColumnOutIfBoundary:
|
|
strValue = fmt.Sprintf("toString(%s)", gc)
|
|
default:
|
|
strValue = gc.String()
|
|
}
|
|
return strValue
|
|
}
|
|
|
|
// reverseDirection reverse the direction of a column (src/dst, in/out)
|
|
func (gc queryColumn) reverseDirection() queryColumn {
|
|
value, ok := queryColumnMap.LoadKey(filter.ReverseColumnDirection(gc.String()))
|
|
if !ok {
|
|
panic("unknown reverse column")
|
|
}
|
|
return value
|
|
}
|