Skip to content

Commit

Permalink
plugins: added more config-params to the plugin config (#899)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabor authored Feb 19, 2024
1 parent 39d7af0 commit 6c53dc9
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 2 deletions.
78 changes: 76 additions & 2 deletions backend/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package backend

import (
"context"
"errors"
"fmt"
"strconv"
"strings"
Expand All @@ -12,8 +13,13 @@ import (
)

const (
AppURL = "GF_APP_URL"
ConcurrentQueryCount = "GF_CONCURRENT_QUERY_COUNT"
AppURL = "GF_APP_URL"
ConcurrentQueryCount = "GF_CONCURRENT_QUERY_COUNT"
UserFacingDefaultError = "GF_USER_FACING_DEFAULT_ERROR"
SQLRowLimit = "GF_SQL_ROW_LIMIT"
SQLMaxOpenConnsDefault = "GF_SQL_MAX_OPEN_CONNS_DEFAULT"
SQLMaxIdleConnsDefault = "GF_SQL_MAX_IDLE_CONNS_DEFAULT"
SQLMaxConnLifetimeSecondsDefault = "GF_SQL_MAX_CONN_LIFETIME_SECONDS_DEFAULT"
)

type configKey struct{}
Expand Down Expand Up @@ -151,6 +157,74 @@ func (c *GrafanaCfg) ConcurrentQueryCount() (int, error) {
return i, nil
}

type SQLConfig struct {
RowLimit int64
DefaultMaxOpenConns int
DefaultMaxIdleConns int
DefaultMaxConnLifetimeSeconds int
}

func (c *GrafanaCfg) SQL() (SQLConfig, error) {
// max open connections
maxOpenString, ok := c.config[SQLMaxOpenConnsDefault]
if !ok {
return SQLConfig{}, errors.New("SQLDatasourceMaxOpenConnsDefault not set in config")
}

maxOpen, err := strconv.Atoi(maxOpenString)
if err != nil {
return SQLConfig{}, errors.New("SQLDatasourceMaxOpenConnsDefault config value is not a valid integer")
}

// max idle connections
maxIdleString, ok := c.config[SQLMaxIdleConnsDefault]
if !ok {
return SQLConfig{}, errors.New("SQLDatasourceMaxIdleConnsDefault not set in config")
}

maxIdle, err := strconv.Atoi(maxIdleString)
if err != nil {
return SQLConfig{}, errors.New("SQLDatasourceMaxIdleConnsDefault config value is not a valid integer")
}

// max connection lifetime
maxLifeString, ok := c.config[SQLMaxConnLifetimeSecondsDefault]
if !ok {
return SQLConfig{}, errors.New("SQLDatasourceMaxConnLifetimeDefault not set in config")
}

maxLife, err := strconv.Atoi(maxLifeString)
if err != nil {
return SQLConfig{}, errors.New("SQLDatasourceMaxConnLifetimeDefault config value is not a valid integer")
}

rowLimitString, ok := c.config[SQLRowLimit]
if !ok {
return SQLConfig{}, errors.New("RowLimit not set in config")
}

rowLimit, err := strconv.ParseInt(rowLimitString, 10, 64)
if err != nil {
return SQLConfig{}, errors.New("RowLimit in config is not a valid integer")
}

return SQLConfig{
RowLimit: rowLimit,
DefaultMaxOpenConns: maxOpen,
DefaultMaxIdleConns: maxIdle,
DefaultMaxConnLifetimeSeconds: maxLife,
}, nil
}

func (c *GrafanaCfg) UserFacingDefaultError() (string, error) {
value, ok := c.config[UserFacingDefaultError]
if !ok {
return "", errors.New("UserFacingDefaultError not set in config")
}

return value, nil
}

type userAgentKey struct{}

// UserAgentFromContext returns user agent from context.
Expand Down
114 changes: 114 additions & 0 deletions backend/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,117 @@ func TestUserAgentFromContext_NoUserAgent(t *testing.T) {
require.Equal(t, "0.0.0", result.GrafanaVersion())
require.Equal(t, "Grafana/0.0.0 (unknown; unknown)", result.String())
}

func TestUserFacingDefaultError(t *testing.T) {
t.Run("it should return the configured default error message", func(t *testing.T) {
cfg := NewGrafanaCfg(map[string]string{
UserFacingDefaultError: "something failed",
})
v, err := cfg.UserFacingDefaultError()
require.NoError(t, err)
require.Equal(t, "something failed", v)
})

t.Run("it should return an error if the default error message is missing", func(t *testing.T) {
cfg := NewGrafanaCfg(map[string]string{})
_, err := cfg.UserFacingDefaultError()
require.Error(t, err)
})
}

func TestSql(t *testing.T) {
t.Run("it should return the configured sql default values", func(t *testing.T) {
cfg := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "22",
SQLMaxConnLifetimeSecondsDefault: "33",
})
v, err := cfg.SQL()
require.NoError(t, err)
require.Equal(t, int64(5), v.RowLimit)
require.Equal(t, 11, v.DefaultMaxOpenConns)
require.Equal(t, 22, v.DefaultMaxIdleConns)
require.Equal(t, 33, v.DefaultMaxConnLifetimeSeconds)
})

t.Run("it should return an error if any of the defaults is missing", func(t *testing.T) {
cfg1 := NewGrafanaCfg(map[string]string{
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "22",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg2 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxIdleConnsDefault: "22",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg3 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg4 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "22",
})

_, err := cfg1.SQL()
require.ErrorContains(t, err, "not set")

_, err = cfg2.SQL()
require.ErrorContains(t, err, "not set")

_, err = cfg3.SQL()
require.ErrorContains(t, err, "not set")

_, err = cfg4.SQL()
require.ErrorContains(t, err, "not set")
})

t.Run("it should return an error if any of the defaults is not an integer", func(t *testing.T) {
cfg1 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "not-an-integer",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "22",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg2 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "not-an-integer",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg3 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "not-an-integer",
SQLMaxConnLifetimeSecondsDefault: "33",
})

cfg4 := NewGrafanaCfg(map[string]string{
SQLRowLimit: "5",
SQLMaxOpenConnsDefault: "11",
SQLMaxIdleConnsDefault: "22",
SQLMaxConnLifetimeSecondsDefault: "not-an-integer",
})

_, err := cfg1.SQL()
require.ErrorContains(t, err, "not a valid integer")

_, err = cfg2.SQL()
require.ErrorContains(t, err, "not a valid integer")

_, err = cfg3.SQL()
require.ErrorContains(t, err, "not a valid integer")

_, err = cfg4.SQL()
require.ErrorContains(t, err, "not a valid integer")
})
}

0 comments on commit 6c53dc9

Please sign in to comment.