mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
console: HAS/HASNOT operator for filtering on ASPath
This commit is contained in:
@@ -163,7 +163,8 @@ guaranteed, so an URL may stop working after a few upgrades.
|
||||
The filter language looks like SQL with a few variations. Fields
|
||||
listed as dimensions can usually be used. Accepted operators are `=`,
|
||||
`!=`, `<`, `<=`, `>`, `>=`, `IN`, `NOTIN`, `LIKE`, `UNLIKE`, `ILIKE`,
|
||||
`IUNLIKE`, `<<`, `!<<` when they make sense. Here are a few examples:
|
||||
`IUNLIKE`, `<<`, `!<<`, `HAS`, `HASNOT` when they make sense. Here are
|
||||
a few examples:
|
||||
|
||||
- `InIfBoundary = external` only selects flows whose incoming
|
||||
interface was classified as external. The value should not be
|
||||
@@ -178,13 +179,19 @@ listed as dimensions can usually be used. Accepted operators are `=`,
|
||||
specified subnet.
|
||||
- `ExporterName LIKE th2-%` selects flows coming from routers
|
||||
starting with `th2-`.
|
||||
- `ASPath HAS AS1299` selects flows whose AS path contains 1299.
|
||||
|
||||
Field names are case-insensitive. Comments can also be added by using
|
||||
`--` for single-line comments or enclosing them in `/*` and `*/`.
|
||||
|
||||
The final SQL query sent to ClickHouse is logged inside the console
|
||||
after a successful request. It should be noted than using ports or
|
||||
addresses prevent the use of aggregated data and are therefore slower.
|
||||
after a successful request. It should be noted than using the
|
||||
following fields will prevent use of aggregated data and therefore
|
||||
will be slower:
|
||||
|
||||
- `SrcAddr` and `DstAddr`,
|
||||
- `SrcPort` and `DstPort`,
|
||||
- `DstASPath`
|
||||
|
||||
## Demo exporter service
|
||||
|
||||
|
||||
@@ -163,12 +163,15 @@ func (c *Component) filterCompleteHandlerFunc(gc *gin.Context) {
|
||||
filterCompletion{"PIM", "protocol", true},
|
||||
filterCompletion{"IPv4", "protocol", true},
|
||||
filterCompletion{"IPv6", "protocol", true})
|
||||
case "srcas", "dstas", "dst1stas", "dst2ndas", "dst3rdas":
|
||||
case "srcas", "dstas", "dst1stas", "dst2ndas", "dst3rdas", "dstaspath":
|
||||
results := []struct {
|
||||
Label string `ch:"label"`
|
||||
Detail string `ch:"detail"`
|
||||
}{}
|
||||
columnName := fixQueryColumnName(input.Column)
|
||||
if columnName == "DstASPath" {
|
||||
columnName = "DstAS"
|
||||
}
|
||||
sqlQuery := fmt.Sprintf(`
|
||||
SELECT label, detail FROM (
|
||||
SELECT concat('AS', toString(%s)) AS label, dictGet('asns', 'name', %s) AS detail, 1 AS rank
|
||||
|
||||
@@ -42,6 +42,7 @@ ConditionExpr "conditional" ←
|
||||
/ ConditionForwardingStatusExpr
|
||||
/ ConditionPortExpr
|
||||
/ ConditionASExpr
|
||||
/ ConditionASPathExpr
|
||||
/ ConditionETypeExpr
|
||||
/ ConditionProtoExpr
|
||||
/ ConditionPacketSizeExpr
|
||||
@@ -147,6 +148,12 @@ RConditionASExpr "condition on AS number" ←
|
||||
return fmt.Sprintf("%s (%s)", toString(operator), toString(value)), nil
|
||||
}
|
||||
|
||||
ConditionASPathExpr "condition on AS path" ←
|
||||
column:("DstASPath"i { return "DstASPath", nil }) _
|
||||
KW_HAS _ value:ASN { return fmt.Sprintf("has(%s, %s)", toString(column), toString(value)), nil }
|
||||
/ column:("DstASPath"i { return "DstASPath", nil }) _
|
||||
KW_HASNOT _ value:ASN { return fmt.Sprintf("NOT has(%s, %s)", toString(column), toString(value)), nil }
|
||||
|
||||
ConditionETypeExpr "condition on Ethernet type" ←
|
||||
column:("EType"i { return "EType", nil }) _
|
||||
operator:("=" / "!=") _ value:("IPv4"i / "IPv6"i) {
|
||||
@@ -260,6 +267,8 @@ KW_IN "IN operator" ← "IN"i !IdentStart { return "IN", nil }
|
||||
KW_UNLIKE "UNLIKE operator" ← "UNLIKE"i !IdentStart { return "NOT LIKE", nil }
|
||||
KW_IUNLIKE "IUNLIKE operator" ← "IUNLIKE"i !IdentStart { return "NOT ILIKE", nil }
|
||||
KW_NOTIN "NOTIN operator" ← "NOTIN"i !IdentStart { return "NOT IN", nil }
|
||||
KW_HAS "HAS operator" ← "HAS"i !IdentStart
|
||||
KW_HASNOT "HASNOT operator" ← "HASNOT"i !IdentStart
|
||||
|
||||
SingleLineComment "comment" ← "--" ( !EOL SourceChar )*
|
||||
MultiLineComment ← "/*" ( !"*/" SourceChar )* ("*/" / EOF {
|
||||
|
||||
@@ -196,6 +196,8 @@ AND SrcAS = AS12322 -- Proxad ASN`,
|
||||
output provider */ = 'telia'`,
|
||||
Output: `OutIfProvider = 'telia'`,
|
||||
},
|
||||
{Input: `DstASPath HAS 65000`, Output: `has(DstASPath, 65000)`},
|
||||
{Input: `DstASPath HASNOT 65000`, Output: `NOT has(DstASPath, 65000)`},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
got, err := Parse("", []byte(tc.Input), GlobalStore("meta", &tc.MetaIn))
|
||||
|
||||
@@ -89,7 +89,8 @@ UNION DISTINCT
|
||||
{"AS36987", "Google Kenya"},
|
||||
{"AS41264", "Google Switzerland"},
|
||||
}).
|
||||
Return(nil)
|
||||
Return(nil).
|
||||
MinTimes(2).MaxTimes(2)
|
||||
|
||||
helpers.TestHTTPEndpoints(t, h.LocalAddr(), helpers.HTTPEndpointCases{
|
||||
{
|
||||
@@ -120,6 +121,7 @@ UNION DISTINCT
|
||||
{"label": "Dst2ndAS", "detail": "column name", "quoted": false},
|
||||
{"label": "Dst3rdAS", "detail": "column name", "quoted": false},
|
||||
{"label": "DstAS", "detail": "column name", "quoted": false},
|
||||
{"label": "DstASPath", "detail": "column name", "quoted": false},
|
||||
{"label": "DstAddr", "detail": "column name", "quoted": false},
|
||||
{"label": "DstCountry", "detail": "column name", "quoted": false},
|
||||
{"label": "DstNetName", "detail": "column name", "quoted": false},
|
||||
@@ -198,6 +200,23 @@ UNION DISTINCT
|
||||
{"label": "AS36987", "detail": "Google Kenya", "quoted": false},
|
||||
{"label": "AS41264", "detail": "Google Switzerland", "quoted": false},
|
||||
}},
|
||||
}, {
|
||||
URL: "/api/v0/console/filter/complete",
|
||||
StatusCode: 200,
|
||||
JSONInput: gin.H{"what": "value", "column": "dstASpath", "prefix": "goog"},
|
||||
JSONOutput: gin.H{"completions": []gin.H{
|
||||
{"label": "AS15169", "detail": "Google", "quoted": false},
|
||||
{"label": "AS16550", "detail": "Google Private Cloud", "quoted": false},
|
||||
{"label": "AS16591", "detail": "Google Fiber", "quoted": false},
|
||||
{"label": "AS19527", "detail": "Google", "quoted": false},
|
||||
{"label": "AS26910", "detail": "GOOGLE-CLOUD-2", "quoted": false},
|
||||
{"label": "AS36040", "detail": "Google", "quoted": false},
|
||||
{"label": "AS36384", "detail": "Google", "quoted": false},
|
||||
{"label": "AS36385", "detail": "Google IT", "quoted": false},
|
||||
{"label": "AS36492", "detail": "Google", "quoted": false},
|
||||
{"label": "AS36987", "detail": "Google Kenya", "quoted": false},
|
||||
{"label": "AS41264", "detail": "Google Switzerland", "quoted": false},
|
||||
}},
|
||||
}, {
|
||||
URL: "/api/v0/console/filter/complete",
|
||||
StatusCode: 200,
|
||||
|
||||
Reference in New Issue
Block a user