Skip to content

Commit

Permalink
V4.x (#621)
Browse files Browse the repository at this point in the history
Co-authored-by: Spencer Torres <[email protected]>
  • Loading branch information
bossinc and SpencerTorres authored Dec 7, 2023
1 parent 4684ddf commit 04b0fe4
Show file tree
Hide file tree
Showing 135 changed files with 10,547 additions and 6,576 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ artifacts/
work/
ci/
e2e-results/
test_summary.json

# Editor
.idea
Expand Down
70 changes: 36 additions & 34 deletions e2e/e2ek6.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,43 +134,45 @@ export async function configurePanel(page) {

let queryData = {
"queries": [
{
"datasource": {
"type": "grafana-clickhouse-datasource",
"uid": `${datasourceUID}`
},
"refId": "A",
"queryType": "builder",
"rawSql": "SELECT \"schema_name\" FROM \"INFORMATION_SCHEMA\".\"SCHEMATA\" LIMIT 100",
"meta": {
"builderOptions": {
"mode": "list",
"fields": [],
"limit": 100
},
"timezone": "America/Denver"
},
"format": 1,
"selectedFormat": 4,
"builderOptions": {
"mode": "list",
"fields": [
"schema_name"
],
"limit": 100,
"database": "INFORMATION_SCHEMA",
"table": "SCHEMATA",
"filters": [],
"orderBy": []
},
"datasourceId": 3568,
"intervalMs": 30000,
"maxDataPoints": 631
}
{
"datasource": {
"type": "grafana-clickhouse-datasource",
"uid": `${datasourceUID}`
},
"pluginVersion": "4.0.0",
"editorType": "builder",
"rawSql": "SELECT \"schema_name\" FROM \"information_schema\".\"schemata\" LIMIT 1000",
"builderOptions": {
"database": "information_schema",
"table": "schemata",
"queryType": "table",
"mode": "list",
"columns": [
{
"name": "schema_name",
"type": "String",
"custom": false
}
],
"meta": {},
"limit": 1000,
"aggregates": [],
"groupBy": [],
"filters": [],
"orderBy": []
},
"format": 1,
"meta": {
"timezone": "America/New_York"
},
"datasourceId": 1,
"intervalMs": 10000,
"maxDataPoints": 1920
}
],
"from": "1695121104422",
"to": "1695142704422"
}
};

// ensures user is an admin to the org
http.post(`http://admin:admin@${GRAFANA_HOST}:3000/api/user/using/1`, null);
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "clickhouse-datasource",
"version": "3.3.0",
"version": "4.0.0-beta",
"description": "Clickhouse Datasource",
"engines": {
"node": ">=16"
Expand Down Expand Up @@ -28,10 +28,10 @@
"@grafana/eslint-config": "^6.0.0",
"@grafana/tsconfig": "^1.2.0-rc1",
"@swc/core": "1.3.75",
"@swc/helpers": "^0.5.0",
"@swc/helpers": "^0.5.3",
"@swc/jest": "^0.2.26",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.4",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.5.1",
"@types/glob": "^8.0.0",
"@types/jest": "^29.5.0",
Expand All @@ -56,7 +56,7 @@
"swc-loader": "^0.2.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "4.8.4",
"typescript": "^4.8.4",
"webpack": "^5.86.0",
"webpack-cli": "^5.1.4",
"webpack-livereload-plugin": "^3.0.2"
Expand All @@ -72,10 +72,10 @@
"@grafana/ui": "10.1.0",
"js-sql-parser": "^1.5.0",
"pgsql-ast-parser": "^11.1.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^5.2.0",
"tslib": "2.5.3"
"tslib": "^2.5.3"
},
"packageManager": "[email protected]"
}
12 changes: 6 additions & 6 deletions pkg/plugin/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type Clickhouse struct{}
func getTLSConfig(settings Settings) (*tls.Config, error) {
tlsConfig := &tls.Config{
InsecureSkipVerify: settings.InsecureSkipVerify,
ServerName: settings.Server,
ServerName: settings.Host,
}
if settings.TlsClientAuth || settings.TlsAuthWithCACert {
if settings.TlsAuthWithCACert && len(settings.TlsCACert) > 0 {
Expand Down Expand Up @@ -118,9 +118,9 @@ func (h *Clickhouse) Connect(config backend.DataSourceInstanceSettings, message
InsecureSkipVerify: settings.InsecureSkipVerify,
}
}
t, err := strconv.Atoi(settings.Timeout)
t, err := strconv.Atoi(settings.DialTimeout)
if err != nil {
return nil, errors.New(fmt.Sprintf("invalid timeout: %s", settings.Timeout))
return nil, errors.New(fmt.Sprintf("invalid timeout: %s", settings.DialTimeout))
}
qt, err := strconv.Atoi(settings.QueryTimeout)
if err != nil {
Expand Down Expand Up @@ -150,7 +150,7 @@ func (h *Clickhouse) Connect(config backend.DataSourceInstanceSettings, message
Products: getClientInfoProducts(ctx),
},
TLS: tlsConfig,
Addr: []string{fmt.Sprintf("%s:%d", settings.Server, settings.Port)},
Addr: []string{fmt.Sprintf("%s:%d", settings.Host, settings.Port)},
HttpUrlPath: settings.Path,
Auth: clickhouse.Auth{
Username: settings.Username,
Expand Down Expand Up @@ -267,8 +267,8 @@ func (h *Clickhouse) MutateQuery(ctx context.Context, req backend.DataQuery) (co
// MutateResponse For any view other than traces we convert FieldTypeNullableJSON to string
func (h *Clickhouse) MutateResponse(ctx context.Context, res data.Frames) (data.Frames, error) {
for _, frame := range res {
if frame.Meta.PreferredVisualization != data.VisType(data.VisTypeTrace) &&
frame.Meta.PreferredVisualization != data.VisType(data.VisTypeTable) {
if frame.Meta.PreferredVisualization != data.VisTypeTrace &&
frame.Meta.PreferredVisualization != data.VisTypeTable {
var fields []*data.Field
for _, field := range frame.Fields {
values := make([]*string, field.Len())
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugin/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "github.com/pkg/errors"

var (
ErrorMessageInvalidJSON = errors.New("could not parse json")
ErrorMessageInvalidServerName = errors.New("invalid server name. Either empty or not set")
ErrorMessageInvalidHost = errors.New("invalid server host. Either empty or not set")
ErrorMessageInvalidPort = errors.New("invalid port")
ErrorMessageInvalidUserName = errors.New("username is either empty or not set")
ErrorMessageInvalidPassword = errors.New("password is either empty or not set")
Expand Down
98 changes: 57 additions & 41 deletions pkg/plugin/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,29 @@ import (

// Settings - data loaded from grafana settings database
type Settings struct {
Server string `json:"server,omitempty"`
Port int64 `json:"port,omitempty"`
Path string `json:"path,omitempty"`
Username string `json:"username,omitempty"`
DefaultDatabase string `json:"defaultDatabase,omitempty"`
InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"`
TlsClientAuth bool `json:"tlsAuth,omitempty"`
TlsAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
Password string `json:"-,omitempty"`
TlsCACert string
Host string `json:"host,omitempty"`
Port int64 `json:"port,omitempty"`
Protocol string `json:"protocol"`
Secure bool `json:"secure,omitempty"`
Path string `json:"path,omitempty"`

InsecureSkipVerify bool `json:"tlsSkipVerify,omitempty"`
TlsClientAuth bool `json:"tlsAuth,omitempty"`
TlsAuthWithCACert bool `json:"tlsAuthWithCACert,omitempty"`
TlsClientCert string
TlsCACert string
TlsClientKey string
Secure bool `json:"secure,omitempty"`
Timeout string `json:"timeout,omitempty"`
QueryTimeout string `json:"queryTimeout,omitempty"`
Protocol string `json:"protocol"`
CustomSettings []CustomSetting `json:"customSettings"`
ProxyOptions *proxy.Options

Username string `json:"username,omitempty"`
Password string `json:"-,omitempty"`

DefaultDatabase string `json:"defaultDatabase,omitempty"`

DialTimeout string `json:"dialTimeout,omitempty"`
QueryTimeout string `json:"queryTimeout,omitempty"`

CustomSettings []CustomSetting `json:"customSettings"`
ProxyOptions *proxy.Options
}

type CustomSetting struct {
Expand All @@ -39,8 +44,8 @@ type CustomSetting struct {
}

func (settings *Settings) isValid() (err error) {
if settings.Server == "" {
return ErrorMessageInvalidServerName
if settings.Host == "" {
return ErrorMessageInvalidHost
}
if settings.Port == 0 {
return ErrorMessageInvalidPort
Expand All @@ -55,9 +60,14 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,
return settings, fmt.Errorf("%s: %w", err.Error(), ErrorMessageInvalidJSON)
}

// Deprecated: Replaced with Host for v4. Deserializes "server" field for old v3 configs.
if jsonData["server"] != nil {
settings.Server = jsonData["server"].(string)
settings.Host = jsonData["server"].(string)
}
if jsonData["host"] != nil {
settings.Host = jsonData["host"].(string)
}

if jsonData["port"] != nil {
if port, ok := jsonData["port"].(string); ok {
settings.Port, err = strconv.ParseInt(port, 0, 64)
Expand All @@ -68,15 +78,22 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,
settings.Port = int64(jsonData["port"].(float64))
}
}
if jsonData["username"] != nil {
settings.Username = jsonData["username"].(string)
if jsonData["protocol"] != nil {
settings.Protocol = jsonData["protocol"].(string)
}
if jsonData["secure"] != nil {
if secure, ok := jsonData["secure"].(string); ok {
settings.Secure, err = strconv.ParseBool(secure)
if err != nil {
return settings, fmt.Errorf("could not parse secure value: %w", err)
}
} else {
settings.Secure = jsonData["secure"].(bool)
}
}
if jsonData["path"] != nil {
settings.Path = jsonData["path"].(string)
}
if jsonData["defaultDatabase"] != nil {
settings.DefaultDatabase = jsonData["defaultDatabase"].(string)
}

if jsonData["tlsSkipVerify"] != nil {
if tlsSkipVerify, ok := jsonData["tlsSkipVerify"].(string); ok {
Expand Down Expand Up @@ -108,20 +125,22 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,
settings.TlsAuthWithCACert = jsonData["tlsAuthWithCACert"].(bool)
}
}
if jsonData["secure"] != nil {
if secure, ok := jsonData["secure"].(string); ok {
settings.Secure, err = strconv.ParseBool(secure)
if err != nil {
return settings, fmt.Errorf("could not parse secure value: %w", err)
}
} else {
settings.Secure = jsonData["secure"].(bool)
}

if jsonData["username"] != nil {
settings.Username = jsonData["username"].(string)
}
if jsonData["defaultDatabase"] != nil {
settings.DefaultDatabase = jsonData["defaultDatabase"].(string)
}

// Deprecated: Replaced with DialTimeout for v4. Deserializes "timeout" field for old v3 configs.
if jsonData["timeout"] != nil {
settings.Timeout = jsonData["timeout"].(string)
settings.DialTimeout = jsonData["timeout"].(string)
}
if jsonData["dialTimeout"] != nil {
settings.DialTimeout = jsonData["dialTimeout"].(string)
}

if jsonData["queryTimeout"] != nil {
if val, ok := jsonData["queryTimeout"].(string); ok {
settings.QueryTimeout = val
Expand All @@ -130,9 +149,6 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,
settings.QueryTimeout = fmt.Sprintf("%d", int64(val))
}
}
if jsonData["protocol"] != nil {
settings.Protocol = jsonData["protocol"].(string)
}
if jsonData["customSettings"] != nil {
customSettingsRaw := jsonData["customSettings"].([]interface{})
customSettings := make([]CustomSetting, len(customSettingsRaw))
Expand All @@ -148,8 +164,8 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,
settings.CustomSettings = customSettings
}

if strings.TrimSpace(settings.Timeout) == "" {
settings.Timeout = "10"
if strings.TrimSpace(settings.DialTimeout) == "" {
settings.DialTimeout = "10"
}
if strings.TrimSpace(settings.QueryTimeout) == "" {
settings.QueryTimeout = "60"
Expand Down Expand Up @@ -177,9 +193,9 @@ func LoadSettings(config backend.DataSourceInstanceSettings) (settings Settings,

if err == nil && proxyOpts != nil {
// the sdk expects the timeout to not be a string
timeout, err := strconv.ParseFloat(settings.Timeout, 64)
timeout, err := strconv.ParseFloat(settings.DialTimeout, 64)
if err == nil {
proxyOpts.Timeouts.Timeout = (time.Duration(timeout) * time.Second)
proxyOpts.Timeouts.Timeout = time.Duration(timeout) * time.Second
}

settings.ProxyOptions = proxyOpts
Expand Down
Loading

0 comments on commit 04b0fe4

Please sign in to comment.