mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-12 06:24:10 +01:00
console: rely on validator to check input values
This commit is contained in:
@@ -15,10 +15,10 @@ import (
|
|||||||
// graphQuery describes the input for the /graph endpoint.
|
// graphQuery describes the input for the /graph endpoint.
|
||||||
type graphQuery struct {
|
type graphQuery struct {
|
||||||
Start time.Time `json:"start" binding:"required"`
|
Start time.Time `json:"start" binding:"required"`
|
||||||
End time.Time `json:"end" binding:"required"`
|
End time.Time `json:"end" binding:"required,gtfield=Start"`
|
||||||
Points int `json:"points" binding:"required"` // minimum number of points
|
Points int `json:"points" binding:"required,min=5,max=2000"` // minimum number of points
|
||||||
Dimensions []queryColumn `json:"dimensions"` // group by ...
|
Dimensions []queryColumn `json:"dimensions"` // group by ...
|
||||||
Limit int `json:"limit"` // limit product of dimensions
|
Limit int `json:"limit" binding:"isdefault|min=1,max=50"` // limit product of dimensions
|
||||||
Filter queryFilter `json:"filter"` // where ...
|
Filter queryFilter `json:"filter"` // where ...
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,21 +96,6 @@ func (c *Component) graphHandlerFunc(gc *gin.Context) {
|
|||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": helpers.Capitalize(err.Error())})
|
gc.JSON(http.StatusBadRequest, gin.H{"message": helpers.Capitalize(err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if query.Start.After(query.End) {
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": "Start should not be after end"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if query.Points < 5 || query.Points > 2000 {
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": "Points should be >= 5 and <= 2000"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if query.Limit == 0 {
|
|
||||||
query.Limit = 10
|
|
||||||
}
|
|
||||||
if query.Limit < 5 || query.Limit > 50 {
|
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": "Limit should be >= 5 and <= 50"})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlQuery, err := query.toSQL()
|
sqlQuery, err := query.toSQL()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"akvorado/common/helpers"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -169,19 +170,22 @@ LIMIT 5
|
|||||||
gc.JSON(http.StatusOK, gin.H{"top": results})
|
gc.JSON(http.StatusOK, gin.H{"top": results})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type widgetParameters struct {
|
||||||
|
Points uint64 `form:"points" binding:"isdefault|min=5,max=1000"`
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) {
|
func (c *Component) widgetGraphHandlerFunc(gc *gin.Context) {
|
||||||
ctx := c.t.Context(gc.Request.Context())
|
ctx := c.t.Context(gc.Request.Context())
|
||||||
|
|
||||||
points, err := strconv.ParseUint(gc.DefaultQuery("points", "200"), 10, 16)
|
var params widgetParameters
|
||||||
if err != nil {
|
if err := gc.ShouldBindQuery(¶ms); err != nil {
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": "Invalid value for points."})
|
gc.JSON(http.StatusBadRequest, gin.H{"message": helpers.Capitalize(err.Error())})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if points < 5 || points > 1000 {
|
if params.Points == 0 {
|
||||||
gc.JSON(http.StatusBadRequest, gin.H{"message": "Points should be > 5 and < 1000"})
|
params.Points = 200
|
||||||
return
|
|
||||||
}
|
}
|
||||||
interval := int64((24 * time.Hour).Seconds()) / int64(points)
|
interval := int64((24 * time.Hour).Seconds()) / int64(params.Points)
|
||||||
now := c.d.Clock.Now()
|
now := c.d.Clock.Now()
|
||||||
query := c.queryFlowsTable(fmt.Sprintf(`
|
query := c.queryFlowsTable(fmt.Sprintf(`
|
||||||
WITH
|
WITH
|
||||||
@@ -200,7 +204,7 @@ ORDER BY Time`, interval), now.Add(-24*time.Hour), now, time.Duration(interval)*
|
|||||||
Time time.Time `json:"t"`
|
Time time.Time `json:"t"`
|
||||||
Gbps float64 `json:"gbps"`
|
Gbps float64 `json:"gbps"`
|
||||||
}{}
|
}{}
|
||||||
err = c.d.ClickHouseDB.Conn.Select(ctx, &results, query)
|
err := c.d.ClickHouseDB.Conn.Select(ctx, &results, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.r.Err(err).Msg("unable to query database")
|
c.r.Err(err).Msg("unable to query database")
|
||||||
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to query database."})
|
gc.JSON(http.StatusInternalServerError, gin.H{"message": "Unable to query database."})
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"akvorado/common/helpers"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,9 +19,10 @@ type flowsParameters struct {
|
|||||||
// is intended for debug only.
|
// is intended for debug only.
|
||||||
func (c *Component) FlowsHTTPHandler(gc *gin.Context) {
|
func (c *Component) FlowsHTTPHandler(gc *gin.Context) {
|
||||||
var params flowsParameters
|
var params flowsParameters
|
||||||
var limit, count uint64
|
var count uint64
|
||||||
if gc.ShouldBindQuery(¶ms) == nil {
|
if err := gc.ShouldBindQuery(¶ms); err != nil {
|
||||||
limit = params.Limit
|
gc.JSON(http.StatusBadRequest, gin.H{"message": helpers.Capitalize(err.Error())})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic.AddUint32(&c.httpFlowClients, 1)
|
atomic.AddUint32(&c.httpFlowClients, 1)
|
||||||
@@ -36,14 +39,14 @@ func (c *Component) FlowsHTTPHandler(gc *gin.Context) {
|
|||||||
case <-gc.Request.Context().Done():
|
case <-gc.Request.Context().Done():
|
||||||
return
|
return
|
||||||
case msg := <-c.httpFlowChannel:
|
case msg := <-c.httpFlowChannel:
|
||||||
if limit == 1 {
|
if params.Limit == 1 {
|
||||||
gc.IndentedJSON(http.StatusOK, msg)
|
gc.IndentedJSON(http.StatusOK, msg)
|
||||||
} else {
|
} else {
|
||||||
gc.JSON(http.StatusOK, msg)
|
gc.JSON(http.StatusOK, msg)
|
||||||
gc.Writer.Write([]byte("\n"))
|
gc.Writer.Write([]byte("\n"))
|
||||||
}
|
}
|
||||||
count++
|
count++
|
||||||
if limit > 0 && count == limit {
|
if params.Limit > 0 && count == params.Limit {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
case <-tickerChan:
|
case <-tickerChan:
|
||||||
|
|||||||
Reference in New Issue
Block a user