mirror of
https://github.com/grafana/grafana.git
synced 2025-08-02 04:00:55 +08:00
Datasource: Fix storing timeout option as numeric (#35441)
#31871 introduced support for configuring timeout in seconds for HTTP data sources. That had a bug where backend expected a numeric timeout value where it was actually stored as a string. This should resolve this by requiring input to be numbers, storing input as numeric and falling back to string value if there's no numeric value. Ref #31871
This commit is contained in:

committed by
GitHub

parent
eff2410bae
commit
d15d87db8a
@ -167,13 +167,14 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
|
|||||||
<div className="gf-form">
|
<div className="gf-form">
|
||||||
<FormField
|
<FormField
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
|
type="number"
|
||||||
labelWidth={13}
|
labelWidth={13}
|
||||||
inputWidth={20}
|
inputWidth={20}
|
||||||
tooltip="HTTP request timeout in seconds"
|
tooltip="HTTP request timeout in seconds"
|
||||||
value={dataSourceConfig.jsonData.timeout}
|
value={dataSourceConfig.jsonData.timeout}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
onSettingsChange({
|
onSettingsChange({
|
||||||
jsonData: { ...dataSourceConfig.jsonData, timeout: event.currentTarget.value },
|
jsonData: { ...dataSourceConfig.jsonData, timeout: parseInt(event.currentTarget.value, 10) },
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -17,8 +18,15 @@ func (ds *DataSource) getTimeout() time.Duration {
|
|||||||
timeout := 0
|
timeout := 0
|
||||||
if ds.JsonData != nil {
|
if ds.JsonData != nil {
|
||||||
timeout = ds.JsonData.Get("timeout").MustInt()
|
timeout = ds.JsonData.Get("timeout").MustInt()
|
||||||
|
if timeout <= 0 {
|
||||||
|
if timeoutStr := ds.JsonData.Get("timeout").MustString(); timeoutStr != "" {
|
||||||
|
if t, err := strconv.Atoi(timeoutStr); err == nil {
|
||||||
|
timeout = t
|
||||||
}
|
}
|
||||||
if timeout == 0 {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if timeout <= 0 {
|
||||||
timeout = setting.DataProxyTimeout
|
timeout = setting.DataProxyTimeout
|
||||||
}
|
}
|
||||||
return time.Duration(timeout) * time.Second
|
return time.Duration(timeout) * time.Second
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/httpclient"
|
"github.com/grafana/grafana/pkg/infra/httpclient"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -310,6 +311,27 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDataSource_getTimeout(t *testing.T) {
|
||||||
|
setting.DataProxyTimeout = 30
|
||||||
|
testCases := []struct {
|
||||||
|
jsonData *simplejson.Json
|
||||||
|
expectedTimeout time.Duration
|
||||||
|
}{
|
||||||
|
{jsonData: simplejson.New(), expectedTimeout: 30 * time.Second},
|
||||||
|
{jsonData: simplejson.NewFromAny(map[string]interface{}{"timeout": nil}), expectedTimeout: 30 * time.Second},
|
||||||
|
{jsonData: simplejson.NewFromAny(map[string]interface{}{"timeout": 0}), expectedTimeout: 30 * time.Second},
|
||||||
|
{jsonData: simplejson.NewFromAny(map[string]interface{}{"timeout": 1}), expectedTimeout: time.Second},
|
||||||
|
{jsonData: simplejson.NewFromAny(map[string]interface{}{"timeout": "2"}), expectedTimeout: 2 * time.Second},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
ds := &DataSource{
|
||||||
|
JsonData: tc.jsonData,
|
||||||
|
}
|
||||||
|
assert.Equal(t, tc.expectedTimeout, ds.getTimeout())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDataSource_DecryptedValue(t *testing.T) {
|
func TestDataSource_DecryptedValue(t *testing.T) {
|
||||||
t.Run("When datasource hasn't been updated, encrypted JSON should be fetched from cache", func(t *testing.T) {
|
t.Run("When datasource hasn't been updated, encrypted JSON should be fetched from cache", func(t *testing.T) {
|
||||||
ClearDSDecryptionCache()
|
ClearDSDecryptionCache()
|
||||||
|
Reference in New Issue
Block a user