From 1161c7bc3e4a5baabbde9b7eaec8f444fbc80fac Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Sun, 15 Apr 2018 17:56:56 +0200 Subject: [PATCH 01/13] add postgresVersion to postgres settings --- public/app/plugins/datasource/postgres/module.ts | 8 +++++++- .../datasource/postgres/partials/config.html | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/postgres/module.ts b/public/app/plugins/datasource/postgres/module.ts index acd23318b6d..766e7b2ec37 100644 --- a/public/app/plugins/datasource/postgres/module.ts +++ b/public/app/plugins/datasource/postgres/module.ts @@ -8,8 +8,14 @@ class PostgresConfigCtrl { /** @ngInject **/ constructor($scope) { - this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'require'; + this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'verify-full'; } + + /* the values are chosen to be equivalent to `select current_setting('server_version_num');` */ + postgresVersions = [ + { name: '8.0+', value: 80000 }, + { name: '8.1+', value: 80100 }, + ]; } const defaultQuery = `SELECT diff --git a/public/app/plugins/datasource/postgres/partials/config.html b/public/app/plugins/datasource/postgres/partials/config.html index 77f0dcfa4a5..51fd66d7ed6 100644 --- a/public/app/plugins/datasource/postgres/partials/config.html +++ b/public/app/plugins/datasource/postgres/partials/config.html @@ -38,6 +38,22 @@ +

PostgreSQL details

+ +
+
+ + Version + + This option controls what functions are used when expanding grafana macros. + + + + + +
+
+
User Permission
From 9b61ffb48ad9544b52b35f5870bfca1db098ae47 Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Sun, 15 Apr 2018 18:38:20 +0200 Subject: [PATCH 02/13] make timefilter macro aware of pg version --- pkg/tsdb/postgres/macros.go | 12 +++++- pkg/tsdb/postgres/macros_test.go | 65 +++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index bd0ac0cc620..b9a7580b3ce 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -79,11 +79,19 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, } return fmt.Sprintf("extract(epoch from %s) as \"time\"", args[0]), nil case "__timeFilter": - // dont use to_timestamp in this macro for redshift compatibility #9566 if len(args) == 0 { return "", fmt.Errorf("missing time column argument for macro %v", name) } - return fmt.Sprintf("extract(epoch from %s) BETWEEN %d AND %d", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil + + pg_version := m.Query.DataSource.JsonData.Get("postgresVersion").MustInt(0) + if pg_version >= 80100 { + // postgres has to_timestamp(double) starting with 8.1 + return fmt.Sprintf("%s BETWEEN to_timestamp(%d) AND to_timestamp(%d)", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil + } + + // dont use to_timestamp in this macro for redshift compatibility #9566 + return fmt.Sprintf("%s BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil + case "__timeFrom": return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil case "__timeTo": diff --git a/pkg/tsdb/postgres/macros_test.go b/pkg/tsdb/postgres/macros_test.go index f441690a429..b4ee043a87d 100644 --- a/pkg/tsdb/postgres/macros_test.go +++ b/pkg/tsdb/postgres/macros_test.go @@ -6,14 +6,27 @@ import ( "testing" "time" + "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/tsdb" . "github.com/smartystreets/goconvey/convey" ) func TestMacroEngine(t *testing.T) { Convey("MacroEngine", t, func() { - engine := &PostgresMacroEngine{} - query := &tsdb.Query{} + engine := NewPostgresMacroEngine() + // datasource with no pg version specified + ds := &models.DataSource{Id: 1, Type: "postgres", JsonData: simplejson.New()} + // datasource with postgres 8.0 configured + ds_80 := &models.DataSource{Id: 2, Type: "postgres", JsonData: simplejson.New()} + ds_80.JsonData.Set("postgresVersion", 80000) + // datasource with postgres 8.1 configured + ds_81 := &models.DataSource{Id: 3, Type: "postgres", JsonData: simplejson.New()} + ds_81.JsonData.Set("postgresVersion", 80100) + + query := &tsdb.Query{RefId: "A", DataSource: ds} + query_80 := &tsdb.Query{RefId: "A", DataSource: ds_80} + query_81 := &tsdb.Query{RefId: "A", DataSource: ds_81} Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() { from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC) @@ -38,7 +51,21 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for postgres 8.0", func() { + sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for postgres 8.1", func() { + sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) }) Convey("interpolate __timeFrom function", func() { @@ -102,7 +129,21 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for 8.0", func() { + sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for 8.1", func() { + sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) }) Convey("interpolate __timeFrom function", func() { @@ -150,7 +191,21 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for 8.0", func() { + sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) + }) + + Convey("interpolate __timeFilter function for 8.1", func() { + sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") + So(err, ShouldBeNil) + + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) }) Convey("interpolate __timeFrom function", func() { From 6d3da9a73df9f3cc74648d2913555437d9bbea1a Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Sun, 15 Apr 2018 22:14:13 +0200 Subject: [PATCH 03/13] remove postgresversion and convert unix timestamp in go --- pkg/tsdb/postgres/macros.go | 10 +-- pkg/tsdb/postgres/macros_test.go | 63 ++----------------- .../app/plugins/datasource/postgres/module.ts | 5 -- .../datasource/postgres/partials/config.html | 16 ----- 4 files changed, 5 insertions(+), 89 deletions(-) diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index b9a7580b3ce..a13912f0e1d 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -83,15 +83,7 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, return "", fmt.Errorf("missing time column argument for macro %v", name) } - pg_version := m.Query.DataSource.JsonData.Get("postgresVersion").MustInt(0) - if pg_version >= 80100 { - // postgres has to_timestamp(double) starting with 8.1 - return fmt.Sprintf("%s BETWEEN to_timestamp(%d) AND to_timestamp(%d)", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil - } - - // dont use to_timestamp in this macro for redshift compatibility #9566 - return fmt.Sprintf("%s BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil - + return fmt.Sprintf("%s BETWEEN '%s' AND '%s'", args[0], m.TimeRange.MustGetFrom().UTC().Format(time.RFC3339), m.TimeRange.MustGetTo().UTC().Format(time.RFC3339)), nil case "__timeFrom": return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil case "__timeTo": diff --git a/pkg/tsdb/postgres/macros_test.go b/pkg/tsdb/postgres/macros_test.go index b4ee043a87d..d1bcaff796d 100644 --- a/pkg/tsdb/postgres/macros_test.go +++ b/pkg/tsdb/postgres/macros_test.go @@ -6,8 +6,6 @@ import ( "testing" "time" - "github.com/grafana/grafana/pkg/components/simplejson" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/tsdb" . "github.com/smartystreets/goconvey/convey" ) @@ -15,18 +13,7 @@ import ( func TestMacroEngine(t *testing.T) { Convey("MacroEngine", t, func() { engine := NewPostgresMacroEngine() - // datasource with no pg version specified - ds := &models.DataSource{Id: 1, Type: "postgres", JsonData: simplejson.New()} - // datasource with postgres 8.0 configured - ds_80 := &models.DataSource{Id: 2, Type: "postgres", JsonData: simplejson.New()} - ds_80.JsonData.Set("postgresVersion", 80000) - // datasource with postgres 8.1 configured - ds_81 := &models.DataSource{Id: 3, Type: "postgres", JsonData: simplejson.New()} - ds_81.JsonData.Set("postgresVersion", 80100) - - query := &tsdb.Query{RefId: "A", DataSource: ds} - query_80 := &tsdb.Query{RefId: "A", DataSource: ds_80} - query_81 := &tsdb.Query{RefId: "A", DataSource: ds_81} + query := &tsdb.Query{} Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() { from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC) @@ -51,21 +38,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for postgres 8.0", func() { - sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for postgres 8.1", func() { - sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN '%s' AND '%s'", from.Format(time.RFC3339), to.Format(time.RFC3339))) }) Convey("interpolate __timeFrom function", func() { @@ -129,21 +102,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for 8.0", func() { - sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for 8.1", func() { - sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN '%s' AND '%s'", from.Format(time.RFC3339), to.Format(time.RFC3339))) }) Convey("interpolate __timeFrom function", func() { @@ -191,21 +150,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for 8.0", func() { - sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix())) - }) - - Convey("interpolate __timeFilter function for 8.1", func() { - sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)") - So(err, ShouldBeNil) - - So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN '%s' AND '%s'", from.Format(time.RFC3339), to.Format(time.RFC3339))) }) Convey("interpolate __timeFrom function", func() { diff --git a/public/app/plugins/datasource/postgres/module.ts b/public/app/plugins/datasource/postgres/module.ts index 766e7b2ec37..9deb7909167 100644 --- a/public/app/plugins/datasource/postgres/module.ts +++ b/public/app/plugins/datasource/postgres/module.ts @@ -11,11 +11,6 @@ class PostgresConfigCtrl { this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'verify-full'; } - /* the values are chosen to be equivalent to `select current_setting('server_version_num');` */ - postgresVersions = [ - { name: '8.0+', value: 80000 }, - { name: '8.1+', value: 80100 }, - ]; } const defaultQuery = `SELECT diff --git a/public/app/plugins/datasource/postgres/partials/config.html b/public/app/plugins/datasource/postgres/partials/config.html index 51fd66d7ed6..77f0dcfa4a5 100644 --- a/public/app/plugins/datasource/postgres/partials/config.html +++ b/public/app/plugins/datasource/postgres/partials/config.html @@ -38,22 +38,6 @@
-

PostgreSQL details

- -
-
- - Version - - This option controls what functions are used when expanding grafana macros. - - - - - -
-
-
User Permission
From 9ca1a94580cc5280939a6769013b5ca4dab3dabc Mon Sep 17 00:00:00 2001 From: David Kaltschmidt Date: Mon, 16 Apr 2018 16:52:44 +0200 Subject: [PATCH 04/13] bra should use the proper build script * `bra run` is used during development, but it was not using build.go which sets a couple of globals, e.g., the commit (currently set to "NA") * This will help in reporting the commit that someone is basing their screenshot on. --- .bra.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.bra.toml b/.bra.toml index 36421a3c5a6..053ae78150a 100644 --- a/.bra.toml +++ b/.bra.toml @@ -1,6 +1,6 @@ [run] init_cmds = [ - ["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"], + ["go", "run", "build.go", "build"], ["./bin/grafana-server", "cfg:app_mode=development"] ] watch_all = true @@ -12,6 +12,6 @@ watch_dirs = [ watch_exts = [".go", ".ini", ".toml"] build_delay = 1500 cmds = [ - ["go", "build", "-o", "./bin/grafana-server", "./pkg/cmd/grafana-server"], + ["go", "run", "build.go", "build"], ["./bin/grafana-server", "cfg:app_mode=development"] ] From e8e554b3da65aeb0007ca6fe93ae07eb22102362 Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Mon, 16 Apr 2018 19:14:25 +0200 Subject: [PATCH 05/13] remove changes to module.ts from this branch --- public/app/plugins/datasource/postgres/module.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/app/plugins/datasource/postgres/module.ts b/public/app/plugins/datasource/postgres/module.ts index 9deb7909167..acd23318b6d 100644 --- a/public/app/plugins/datasource/postgres/module.ts +++ b/public/app/plugins/datasource/postgres/module.ts @@ -8,9 +8,8 @@ class PostgresConfigCtrl { /** @ngInject **/ constructor($scope) { - this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'verify-full'; + this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'require'; } - } const defaultQuery = `SELECT From a2a7d3d436aa3e3da4d38aeef06d880f1e25c888 Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Mon, 16 Apr 2018 19:38:35 +0200 Subject: [PATCH 06/13] add GetFromAsTimeUTC and GetToAsTimeUTC and use them in timeFilter macro --- pkg/tsdb/postgres/macros.go | 2 +- pkg/tsdb/time_range.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index a13912f0e1d..e666d20ae06 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -83,7 +83,7 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, return "", fmt.Errorf("missing time column argument for macro %v", name) } - return fmt.Sprintf("%s BETWEEN '%s' AND '%s'", args[0], m.TimeRange.MustGetFrom().UTC().Format(time.RFC3339), m.TimeRange.MustGetTo().UTC().Format(time.RFC3339)), nil + return fmt.Sprintf("%s BETWEEN '%s' AND '%s'", args[0], m.TimeRange.GetFromAsTimeUTC().Format(time.RFC3339), m.TimeRange.GetToAsTimeUTC().Format(time.RFC3339)), nil case "__timeFrom": return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil case "__timeTo": diff --git a/pkg/tsdb/time_range.go b/pkg/tsdb/time_range.go index 3bd4e228999..777fd15907e 100644 --- a/pkg/tsdb/time_range.go +++ b/pkg/tsdb/time_range.go @@ -37,6 +37,10 @@ func (tr *TimeRange) GetFromAsSecondsEpoch() int64 { return tr.GetFromAsMsEpoch() / 1000 } +func (tr *TimeRange) GetFromAsTimeUTC() time.Time { + return tr.MustGetFrom().UTC() +} + func (tr *TimeRange) GetToAsMsEpoch() int64 { return tr.MustGetTo().UnixNano() / int64(time.Millisecond) } @@ -45,6 +49,10 @@ func (tr *TimeRange) GetToAsSecondsEpoch() int64 { return tr.GetToAsMsEpoch() / 1000 } +func (tr *TimeRange) GetToAsTimeUTC() time.Time { + return tr.MustGetTo().UTC() +} + func (tr *TimeRange) MustGetFrom() time.Time { if res, err := tr.ParseFrom(); err != nil { return time.Unix(0, 0) From ce941a004d6445f1ff809451301d237756798818 Mon Sep 17 00:00:00 2001 From: Mario Trangoni Date: Mon, 16 Apr 2018 20:04:58 +0200 Subject: [PATCH 07/13] fix unconvert issues --- pkg/cmd/grafana-cli/services/services.go | 2 +- pkg/components/apikeygen/apikeygen.go | 4 ++-- pkg/components/imguploader/azureblobuploader.go | 2 +- pkg/components/null/float.go | 2 +- pkg/metrics/metrics.go | 2 +- pkg/models/datasource_cache.go | 2 +- pkg/plugins/models.go | 2 +- pkg/plugins/update_checker.go | 2 +- pkg/services/alerting/notifiers/line.go | 2 +- pkg/tsdb/cloudwatch/annotation_query.go | 4 ++-- pkg/tsdb/prometheus/prometheus.go | 4 ++-- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/cmd/grafana-cli/services/services.go b/pkg/cmd/grafana-cli/services/services.go index d13e90d6a2f..3745dbff90e 100644 --- a/pkg/cmd/grafana-cli/services/services.go +++ b/pkg/cmd/grafana-cli/services/services.go @@ -42,7 +42,7 @@ func Init(version string, skipTLSVerify bool) { } HttpClient = http.Client{ - Timeout: time.Duration(10 * time.Second), + Timeout: 10 * time.Second, Transport: tr, } } diff --git a/pkg/components/apikeygen/apikeygen.go b/pkg/components/apikeygen/apikeygen.go index 310188a80ef..7824cf7667f 100644 --- a/pkg/components/apikeygen/apikeygen.go +++ b/pkg/components/apikeygen/apikeygen.go @@ -33,7 +33,7 @@ func New(orgId int64, name string) KeyGenResult { jsonString, _ := json.Marshal(jsonKey) - result.ClientSecret = base64.StdEncoding.EncodeToString([]byte(jsonString)) + result.ClientSecret = base64.StdEncoding.EncodeToString(jsonString) return result } @@ -44,7 +44,7 @@ func Decode(keyString string) (*ApiKeyJson, error) { } var keyObj ApiKeyJson - err = json.Unmarshal([]byte(jsonString), &keyObj) + err = json.Unmarshal(jsonString, &keyObj) if err != nil { return nil, ErrInvalidApiKey } diff --git a/pkg/components/imguploader/azureblobuploader.go b/pkg/components/imguploader/azureblobuploader.go index 40d2de836be..3c0ac5b8884 100644 --- a/pkg/components/imguploader/azureblobuploader.go +++ b/pkg/components/imguploader/azureblobuploader.go @@ -225,7 +225,7 @@ func (a *Auth) SignRequest(req *http.Request) { ) decodedKey, _ := base64.StdEncoding.DecodeString(a.Key) - sha256 := hmac.New(sha256.New, []byte(decodedKey)) + sha256 := hmac.New(sha256.New, decodedKey) sha256.Write([]byte(strToSign)) signature := base64.StdEncoding.EncodeToString(sha256.Sum(nil)) diff --git a/pkg/components/null/float.go b/pkg/components/null/float.go index 1e78946e878..caf4d8b677c 100644 --- a/pkg/components/null/float.go +++ b/pkg/components/null/float.go @@ -50,7 +50,7 @@ func (f *Float) UnmarshalJSON(data []byte) error { } switch x := v.(type) { case float64: - f.Float64 = float64(x) + f.Float64 = x case map[string]interface{}: err = json.Unmarshal(data, &f.NullFloat64) case nil: diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 4d4a11d0faa..4cefe12d6e5 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -403,6 +403,6 @@ func sendUsageStats() { out, _ := json.MarshalIndent(report, "", " ") data := bytes.NewBuffer(out) - client := http.Client{Timeout: time.Duration(5 * time.Second)} + client := http.Client{Timeout: 5 * time.Second} go client.Post("https://stats.grafana.org/grafana-usage-report", "application/json", data) } diff --git a/pkg/models/datasource_cache.go b/pkg/models/datasource_cache.go index b4a4e7f8a4d..66ba66e4d39 100644 --- a/pkg/models/datasource_cache.go +++ b/pkg/models/datasource_cache.go @@ -33,7 +33,7 @@ func (ds *DataSource) GetHttpClient() (*http.Client, error) { } return &http.Client{ - Timeout: time.Duration(30 * time.Second), + Timeout: 30 * time.Second, Transport: transport, }, nil } diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go index 541b37c8a8a..9677c21ef04 100644 --- a/pkg/plugins/models.go +++ b/pkg/plugins/models.go @@ -69,7 +69,7 @@ func (pb *PluginBase) registerPlugin(pluginDir string) error { for _, include := range pb.Includes { if include.Role == "" { - include.Role = m.RoleType(m.ROLE_VIEWER) + include.Role = m.ROLE_VIEWER } } diff --git a/pkg/plugins/update_checker.go b/pkg/plugins/update_checker.go index 68ccdeaf840..946d215b1c2 100644 --- a/pkg/plugins/update_checker.go +++ b/pkg/plugins/update_checker.go @@ -13,7 +13,7 @@ import ( ) var ( - httpClient http.Client = http.Client{Timeout: time.Duration(10 * time.Second)} + httpClient http.Client = http.Client{Timeout: 10 * time.Second} ) type GrafanaNetPlugin struct { diff --git a/pkg/services/alerting/notifiers/line.go b/pkg/services/alerting/notifiers/line.go index 4fbaa2d543e..4814662f3a9 100644 --- a/pkg/services/alerting/notifiers/line.go +++ b/pkg/services/alerting/notifiers/line.go @@ -90,7 +90,7 @@ func (this *LineNotifier) createAlert(evalContext *alerting.EvalContext) error { } if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { - this.log.Error("Failed to send notification to LINE", "error", err, "body", string(body)) + this.log.Error("Failed to send notification to LINE", "error", err, "body", body) return err } diff --git a/pkg/tsdb/cloudwatch/annotation_query.go b/pkg/tsdb/cloudwatch/annotation_query.go index 287f4e770ef..e0d9158435e 100644 --- a/pkg/tsdb/cloudwatch/annotation_query.go +++ b/pkg/tsdb/cloudwatch/annotation_query.go @@ -72,7 +72,7 @@ func (e *CloudWatchExecutor) executeAnnotationQuery(ctx context.Context, queryCo MetricName: aws.String(metricName), Dimensions: qd, Statistic: aws.String(s), - Period: aws.Int64(int64(period)), + Period: aws.Int64(period), } resp, err := svc.DescribeAlarmsForMetric(params) if err != nil { @@ -88,7 +88,7 @@ func (e *CloudWatchExecutor) executeAnnotationQuery(ctx context.Context, queryCo MetricName: aws.String(metricName), Dimensions: qd, ExtendedStatistic: aws.String(s), - Period: aws.Int64(int64(period)), + Period: aws.Int64(period), } resp, err := svc.DescribeAlarmsForMetric(params) if err != nil { diff --git a/pkg/tsdb/prometheus/prometheus.go b/pkg/tsdb/prometheus/prometheus.go index 1186fccbbf9..bf9fe9f152c 100644 --- a/pkg/tsdb/prometheus/prometheus.go +++ b/pkg/tsdb/prometheus/prometheus.go @@ -108,8 +108,8 @@ func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSourc span, ctx := opentracing.StartSpanFromContext(ctx, "alerting.prometheus") span.SetTag("expr", query.Expr) - span.SetTag("start_unixnano", int64(query.Start.UnixNano())) - span.SetTag("stop_unixnano", int64(query.End.UnixNano())) + span.SetTag("start_unixnano", query.Start.UnixNano()) + span.SetTag("stop_unixnano", query.End.UnixNano()) defer span.Finish() value, err := client.QueryRange(ctx, query.Expr, timeRange) From 45993296836ad2a906a523107ce05e3248e10903 Mon Sep 17 00:00:00 2001 From: Sven Klemm <31455525+svenklemm@users.noreply.github.com> Date: Mon, 16 Apr 2018 22:23:24 +0200 Subject: [PATCH 08/13] set default for sslmode to verify-full in postgres datasource editor (#11615) --- public/app/plugins/datasource/postgres/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/postgres/module.ts b/public/app/plugins/datasource/postgres/module.ts index acd23318b6d..a24971fa1a1 100644 --- a/public/app/plugins/datasource/postgres/module.ts +++ b/public/app/plugins/datasource/postgres/module.ts @@ -8,7 +8,7 @@ class PostgresConfigCtrl { /** @ngInject **/ constructor($scope) { - this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'require'; + this.current.jsonData.sslmode = this.current.jsonData.sslmode || 'verify-full'; } } From 5dc36afe71de80ec2311b942ca137c1c3dec5b70 Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Mon, 16 Apr 2018 23:02:24 +0200 Subject: [PATCH 09/13] calculate datetime for timeFrom and timeTo macro in go --- pkg/tsdb/postgres/macros.go | 4 ++-- pkg/tsdb/postgres/macros_test.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/tsdb/postgres/macros.go b/pkg/tsdb/postgres/macros.go index e666d20ae06..05e39f2c762 100644 --- a/pkg/tsdb/postgres/macros.go +++ b/pkg/tsdb/postgres/macros.go @@ -85,9 +85,9 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, return fmt.Sprintf("%s BETWEEN '%s' AND '%s'", args[0], m.TimeRange.GetFromAsTimeUTC().Format(time.RFC3339), m.TimeRange.GetToAsTimeUTC().Format(time.RFC3339)), nil case "__timeFrom": - return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil + return fmt.Sprintf("'%s'", m.TimeRange.GetFromAsTimeUTC().Format(time.RFC3339)), nil case "__timeTo": - return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetToAsSecondsEpoch()), nil + return fmt.Sprintf("'%s'", m.TimeRange.GetToAsTimeUTC().Format(time.RFC3339)), nil case "__timeGroup": if len(args) < 2 { return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) diff --git a/pkg/tsdb/postgres/macros_test.go b/pkg/tsdb/postgres/macros_test.go index d1bcaff796d..c3c15691e42 100644 --- a/pkg/tsdb/postgres/macros_test.go +++ b/pkg/tsdb/postgres/macros_test.go @@ -45,7 +45,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", from.Format(time.RFC3339))) }) Convey("interpolate __timeGroup function", func() { @@ -68,7 +68,7 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", to.Format(time.RFC3339))) }) Convey("interpolate __unixEpochFilter function", func() { @@ -109,14 +109,14 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", from.Format(time.RFC3339))) }) Convey("interpolate __timeTo function", func() { sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", to.Format(time.RFC3339))) }) Convey("interpolate __unixEpochFilter function", func() { @@ -157,14 +157,14 @@ func TestMacroEngine(t *testing.T) { sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", from.Format(time.RFC3339))) }) Convey("interpolate __timeTo function", func() { sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") So(err, ShouldBeNil) - So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix())) + So(sql, ShouldEqual, fmt.Sprintf("select '%s'", to.Format(time.RFC3339))) }) Convey("interpolate __unixEpochFilter function", func() { From 69d1330ae9f45074b1e34aac768571ec5b167fee Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Mon, 16 Apr 2018 23:46:26 +0200 Subject: [PATCH 10/13] changelog: notes about closing #11578 [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df0746e436..f433b102342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ * **Prometheus**: tooltip for legend format not showing properly [#11516](https://github.com/grafana/grafana/issues/11516), thx [@svenklemm](https://github.com/svenklemm) * **Playlist**: Empty playlists cannot be deleted [#11133](https://github.com/grafana/grafana/issues/11133), thx [@kichristensen](https://github.com/kichristensen) * **Switch Orgs**: Alphabetic order in Switch Organization modal [#11556](https://github.com/grafana/grafana/issues/11556) +* **Postgres**: improve `$__timeFilter` macro [#11578](https://github.com/grafana/grafana/issues/11578), thx [@svenklemm](https://github.com/svenklemm) ### Tech * Migrated JavaScript files to TypeScript From 3a5d1f459466d6929033df198b17ede98e333e44 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Mon, 16 Apr 2018 23:56:14 +0200 Subject: [PATCH 11/13] tsdb: update query and annotation editor help texts for postgres In addition to closing #11578 --- .../datasource/postgres/partials/annotations.editor.html | 8 ++++---- .../datasource/postgres/partials/query.editor.html | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/app/plugins/datasource/postgres/partials/annotations.editor.html b/public/app/plugins/datasource/postgres/partials/annotations.editor.html index 907b1b10be4..b83f5a14832 100644 --- a/public/app/plugins/datasource/postgres/partials/annotations.editor.html +++ b/public/app/plugins/datasource/postgres/partials/annotations.editor.html @@ -28,12 +28,12 @@ An annotation is an event that is overlaid on top of graphs. The query can have Macros: - $__time(column) -> column as "time" - $__timeEpoch -> extract(epoch from column) as "time" -- $__timeFilter(column) -> column ≥ to_timestamp(1492750877) AND column ≤ to_timestamp(1492750877) -- $__unixEpochFilter(column) -> column > 1492750877 AND column < 1492750877 +- $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' +- $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 Or build your own conditionals using these macros which just return the values: -- $__timeFrom() -> to_timestamp(1492750877) -- $__timeTo() -> to_timestamp(1492750877) +- $__timeFrom() -> '2017-04-21T05:01:17Z' +- $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 diff --git a/public/app/plugins/datasource/postgres/partials/query.editor.html b/public/app/plugins/datasource/postgres/partials/query.editor.html index 163970a9ad5..26392c17356 100644 --- a/public/app/plugins/datasource/postgres/partials/query.editor.html +++ b/public/app/plugins/datasource/postgres/partials/query.editor.html @@ -48,8 +48,8 @@ Table: Macros: - $__time(column) -> column as "time" - $__timeEpoch -> extract(epoch from column) as "time" -- $__timeFilter(column) -> extract(epoch from column) BETWEEN 1492750877 AND 1492750877 -- $__unixEpochFilter(column) -> column > 1492750877 AND column < 1492750877 +- $__timeFilter(column) -> column BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:01:17Z' +- $__unixEpochFilter(column) -> column >= 1492750877 AND column <= 1492750877 - $__timeGroup(column,'5m') -> (extract(epoch from column)/300)::bigint*300 AS time Example of group by and order by with $__timeGroup: @@ -61,8 +61,8 @@ GROUP BY time ORDER BY time Or build your own conditionals using these macros which just return the values: -- $__timeFrom() -> to_timestamp(1492750877) -- $__timeTo() -> to_timestamp(1492750877) +- $__timeFrom() -> '2017-04-21T05:01:17Z' +- $__timeTo() -> '2017-04-21T05:01:17Z' - $__unixEpochFrom() -> 1492750877 - $__unixEpochTo() -> 1492750877 From b6b152d9ea41384e87af5d98f211a3bbba598b0b Mon Sep 17 00:00:00 2001 From: Carl Bergquist Date: Tue, 17 Apr 2018 09:00:39 +0200 Subject: [PATCH 12/13] Revert "removes codecov from frontend tests" --- Gruntfile.js | 1 + codecov.yml | 13 +++++++++++++ package.json | 1 + scripts/circle-test-frontend.sh | 9 +++++++-- scripts/grunt/options/exec.js | 7 ++++++- 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 codecov.yml diff --git a/Gruntfile.js b/Gruntfile.js index 03f70565b57..a0607ef49dc 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -22,6 +22,7 @@ module.exports = function (grunt) { } } + config.coverage = grunt.option('coverage'); config.phjs = grunt.option('phjsToRelease'); config.pkg.version = grunt.option('pkgVer') || config.pkg.version; diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 00000000000..82a86e0232b --- /dev/null +++ b/codecov.yml @@ -0,0 +1,13 @@ +coverage: + precision: 2 + round: down + range: "50...100" + + status: + project: yes + patch: yes + changes: no + +comment: + layout: "diff" + behavior: "once" diff --git a/package.json b/package.json index b74d23f33b2..ce861a25f7b 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "watch": "webpack --progress --colors --watch --config scripts/webpack/webpack.dev.js", "build": "grunt build", "test": "grunt test", + "test:coverage": "grunt test --coverage=true", "lint": "tslint -c tslint.json --project tsconfig.json --type-check", "karma": "grunt karma:dev", "jest": "jest --notify --watch", diff --git a/scripts/circle-test-frontend.sh b/scripts/circle-test-frontend.sh index 325c24ae7a9..9857e00f70d 100755 --- a/scripts/circle-test-frontend.sh +++ b/scripts/circle-test-frontend.sh @@ -10,5 +10,10 @@ function exit_if_fail { fi } -exit_if_fail npm run test -exit_if_fail npm run build \ No newline at end of file +exit_if_fail npm run test:coverage +exit_if_fail npm run build + +# publish code coverage +echo "Publishing javascript code coverage" +bash <(curl -s https://codecov.io/bash) -cF javascript +rm -rf coverage diff --git a/scripts/grunt/options/exec.js b/scripts/grunt/options/exec.js index be163581bf6..e22d060ea04 100644 --- a/scripts/grunt/options/exec.js +++ b/scripts/grunt/options/exec.js @@ -1,9 +1,14 @@ module.exports = function(config, grunt) { 'use strict'; + var coverage = ''; + if (config.coverage) { + coverage = '--coverage --maxWorkers 2'; + } + return { tslint: 'node ./node_modules/tslint/lib/tslint-cli.js -c tslint.json --project ./tsconfig.json', - jest: 'node ./node_modules/jest-cli/bin/jest.js --maxWorkers 2', + jest: 'node ./node_modules/jest-cli/bin/jest.js ' + coverage, webpack: 'node ./node_modules/webpack/bin/webpack.js --config scripts/webpack/webpack.prod.js', }; }; From 450a3b4a0080149c2fcf6a59c6b48bbdeff00241 Mon Sep 17 00:00:00 2001 From: Carl Bergquist Date: Tue, 17 Apr 2018 09:00:55 +0200 Subject: [PATCH 13/13] Revert "build: remove code cov" --- scripts/circle-test-backend.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/circle-test-backend.sh b/scripts/circle-test-backend.sh index 71fc598b609..a63d6354fa6 100755 --- a/scripts/circle-test-backend.sh +++ b/scripts/circle-test-backend.sh @@ -20,4 +20,17 @@ echo "building backend with install to cache pkgs" exit_if_fail time go install ./pkg/cmd/grafana-server echo "running go test" -go test ./pkg/... + +set -e +echo "" > coverage.txt + +time for d in $(go list ./pkg/...); do + exit_if_fail go test -coverprofile=profile.out -covermode=atomic $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done + +echo "Publishing go code coverage" +bash <(curl -s https://codecov.io/bash) -cF go