Skip to content

Commit 15c8ef6

Browse files
committed
Merge branch 'master' into postgres-query-builder
2 parents 3f5d325 + a1ed3ae commit 15c8ef6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2167
-2595
lines changed

.bra.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ watch_dirs = [
99
"$WORKDIR/public/views",
1010
"$WORKDIR/conf",
1111
]
12-
watch_exts = [".go", ".ini", ".toml"]
12+
watch_exts = [".go", ".ini", ".toml", ".template.html"]
1313
build_delay = 1500
1414
cmds = [
1515
["go", "run", "build.go", "-dev", "build-server"],

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ jobs:
104104
- run:
105105
name: yarn install
106106
command: 'yarn install --pure-lockfile --no-progress'
107+
no_output_timeout: 15m
107108
- save_cache:
108109
key: dependency-cache-{{ checksum "yarn.lock" }}
109110
paths:

.jscs.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

.jshintrc

Lines changed: 0 additions & 37 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
* **LDAP**: Define Grafana Admin permission in ldap group mappings [#2469](https://github.com/grafana/grafana/issues/2496), PR [#12622](https://github.com/grafana/grafana/issues/12622)
66
* **Cloudwatch**: CloudWatch GetMetricData support [#11487](https://github.com/grafana/grafana/issues/11487), thx [@mtanda](https://github.com/mtanda)
77
* **Configuration**: Allow auto-assigning users to specific organization (other than Main. Org) [#1823](https://github.com/grafana/grafana/issues/1823) [#12801](https://github.com/grafana/grafana/issues/12801), thx [@gzzo](https://github.com/gzzo) and [@ofosos](https://github.com/ofosos)
8+
* **Profile**: List teams that the user is member of in current/active organization [#12476](https://github.com/grafana/grafana/issues/12476)
9+
* **LDAP**: Client certificates support [#12805](https://github.com/grafana/grafana/issues/12805), thx [@nyxi](https://github.com/nyxi)
10+
* **Postgres**: TimescaleDB support, e.g. use `time_bucket` for grouping by time when option enabled [#12680](https://github.com/grafana/grafana/pull/12680), thx [svenklemm](https://github.com/svenklemm)
811

912
### Minor
1013

1114
* **Api**: Delete nonexistent datasource should return 404 [#12313](https://github.com/grafana/grafana/issues/12313), thx [@AustinWinstanley](https://github.com/AustinWinstanley)
1215
* **Dashboard**: Fix selecting current dashboard from search should not reload dashboard [#12248](https://github.com/grafana/grafana/issues/12248)
16+
* **Dashboard**: Use uid when linking to dashboards internally in a dashboard [#10705](https://github.com/grafana/grafana/issues/10705)
1317
* **Singlestat**: Make colorization of prefix and postfix optional in singlestat [#11892](https://github.com/grafana/grafana/pull/11892), thx [@ApsOps](https://github.com/ApsOps)
14-
* **Table**: Make table sorting stable when null values exist [#12362](https://github.com/grafana/grafana/pull/12362), thx [@bz2](https://github.com/bz2)
1518
* **Prometheus**: Fix graph panel bar width issue in aligned prometheus queries [#12379](https://github.com/grafana/grafana/issues/12379)
1619
* **Prometheus**: Heatmap - fix unhandled error when some points are missing [#12484](https://github.com/grafana/grafana/issues/12484)
1720
* **Prometheus**: Add $__interval, $__interval_ms, $__range, $__range_s & $__range_ms support for dashboard and template queries [#12597](https://github.com/grafana/grafana/issues/12597) [#12882](https://github.com/grafana/grafana/issues/12882), thx [@roidelapluie](https://github.com/roidelapluie)
@@ -25,22 +28,28 @@
2528
* **Postgres**: Escape ssl mode parameter in connectionstring [#12644](https://github.com/grafana/grafana/issues/12644), thx [@yogyrahmawan](https://github.com/yogyrahmawan)
2629
* **Github OAuth**: Allow changes of user info at Github to be synched to Grafana when signing in [#11818](https://github.com/grafana/grafana/issues/11818), thx [@rwaweber](https://github.com/rwaweber)
2730
* **Alerting**: Fix diff and percent_diff reducers [#11563](https://github.com/grafana/grafana/issues/11563), thx [@jessetane](https://github.com/jessetane)
28-
* **Units**: Polish złoty currency [#12691](https://github.com/grafana/grafana/pull/12691), thx [@mwegrzynek](https://github.com/mwegrzynek)
31+
* **Alerting**: Fix rendering timeout which could cause notifications to not be sent due to rendering timing out [#12151](https://github.com/grafana/grafana/issues/12151)
2932
* **Cloudwatch**: Improved error handling [#12489](https://github.com/grafana/grafana/issues/12489), thx [@mtanda](https://github.com/mtanda)
3033
* **Cloudwatch**: AppSync metrics and dimensions [#12300](https://github.com/grafana/grafana/issues/12300), thx [@franciscocpg](https://github.com/franciscocpg)
3134
* **Cloudwatch**: Direct Connect metrics and dimensions [#12762](https://github.com/grafana/grafana/pulls/12762), thx [@mindriot88](https://github.com/mindriot88)
3235
* **Cloudwatch**: Added BurstBalance metric to list of AWS RDS metrics [#12561](https://github.com/grafana/grafana/pulls/12561), thx [@activeshadow](https://github.com/activeshadow)
3336
* **Cloudwatch**: Add new Redshift metrics and dimensions [#12063](https://github.com/grafana/grafana/pulls/12063), thx [@A21z](https://github.com/A21z)
3437
* **Table**: Adjust header contrast for the light theme [#12668](https://github.com/grafana/grafana/issues/12668)
3538
* **Table**: Fix link color when using light theme and thresholds in use [#12766](https://github.com/grafana/grafana/issues/12766)
39+
om/grafana/grafana/issues/12668)
40+
* **Table**: Fix for useless horizontal scrollbar for table panel [#9964](https://github.com/grafana/grafana/issues/9964)
41+
* **Table**: Make table sorting stable when null values exist [#12362](https://github.com/grafana/grafana/pull/12362), thx [@bz2](https://github.com/bz2)
3642
* **Elasticsearch**: For alerting/backend, support having index name to the right of pattern in index pattern [#12731](https://github.com/grafana/grafana/issues/12731)
3743
* **OAuth**: Fix overriding tls_skip_verify_insecure using environment variable [#12747](https://github.com/grafana/grafana/issues/12747), thx [@jangaraj](https://github.com/jangaraj)
3844
* **Units**: Change units to include characters for power of 2 and 3 [#12744](https://github.com/grafana/grafana/pull/12744), thx [@Worty](https://github.com/Worty)
45+
* **Units**: Polish złoty currency [#12691](https://github.com/grafana/grafana/pull/12691), thx [@mwegrzynek](https://github.com/mwegrzynek)
3946
* **Graph**: Option to hide series from tooltip [#3341](https://github.com/grafana/grafana/issues/3341), thx [@mtanda](https://github.com/mtanda)
4047
* **UI**: Fix iOS home screen "app" icon and Windows 10 app experience [#12752](https://github.com/grafana/grafana/issues/12752), thx [@andig](https://github.com/andig)
4148
* **Datasource**: Fix UI issue with secret fields after updating datasource [#11270](https://github.com/grafana/grafana/issues/11270)
4249
* **Plugins**: Convert URL-like text to links in plugins readme [#12843](https://github.com/grafana/grafana/pull/12843), thx [pgiraud](https://github.com/pgiraud)
4350
* **Docker**: Make it possible to set a specific plugin url [#12861](https://github.com/grafana/grafana/pull/12861), thx [ClementGautier](https://github.com/ClementGautier)
51+
* **Graphite**: Fix for quoting of int function parameters (when using variables) [#11927](https://github.com/grafana/grafana/pull/11927)
52+
* **InfluxDB**: Support timeFilter in query templating for InfluxDB [#12598](https://github.com/grafana/grafana/pull/12598), thx [kichristensen](https://github.com/kichristensen)
4453

4554
### Breaking changes
4655

Gruntfile.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* jshint node:true */
21
'use strict';
32
module.exports = function (grunt) {
43
var os = require('os');

conf/defaults.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,9 @@ api_url =
315315
team_ids =
316316
allowed_organizations =
317317
tls_skip_verify_insecure = false
318+
tls_client_cert =
319+
tls_client_key =
320+
tls_client_ca =
318321

319322
#################################### Basic Auth ##########################
320323
[auth.basic]

conf/ldap.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ start_tls = false
1515
ssl_skip_verify = false
1616
# set to the path to your root CA certificate or leave unset to use system defaults
1717
# root_ca_cert = "/path/to/certificate.crt"
18+
# Authentication against LDAP servers requiring client certificates
19+
# client_cert = "/path/to/client.crt"
20+
# client_key = "/path/to/client.key"
1821

1922
# Search user bind dn
2023
bind_dn = "cn=admin,dc=grafana,dc=org"

conf/sample.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ log_queries =
272272
;api_url = https://foo.bar/user
273273
;team_ids =
274274
;allowed_organizations =
275+
;tls_skip_verify_insecure = false
276+
;tls_client_cert =
277+
;tls_client_key =
278+
;tls_client_ca =
275279

276280
#################################### Grafana.com Auth ####################
277281
[auth.grafana_com]

docs/sources/features/datasources/postgres.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Name | Description
3131
*User* | Database user's login/username
3232
*Password* | Database user's password
3333
*SSL Mode* | This option determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server.
34+
*TimescaleDB* | With this option enabled Grafana will use TimescaleDB features, e.g. use ```time_bucket``` for grouping by time (only available in Grafana 5.3+).
3435

3536
### Database User Permissions (Important!)
3637

@@ -289,4 +290,5 @@ datasources:
289290
password: "Password!"
290291
jsonData:
291292
sslmode: "disable" # disable/require/verify-ca/verify-full
293+
timescaledb: false
292294
```

docs/sources/http_api/user.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,39 @@ Content-Type: application/json
363363
]
364364
```
365365

366+
## Teams that the actual User is member of
367+
368+
`GET /api/user/teams`
369+
370+
Return a list of all teams that the current user is member of.
371+
372+
**Example Request**:
373+
374+
```http
375+
GET /api/user/teams HTTP/1.1
376+
Accept: application/json
377+
Content-Type: application/json
378+
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
379+
```
380+
381+
**Example Response**:
382+
383+
```http
384+
HTTP/1.1 200
385+
Content-Type: application/json
386+
387+
[
388+
{
389+
"id": 1,
390+
"orgId": 1,
391+
"name": "MyTestTeam",
392+
"email": "",
393+
"avatarUrl": "\/avatar\/3f49c15916554246daa714b9bd0ee398",
394+
"memberCount": 1
395+
}
396+
]
397+
```
398+
366399
## Star a dashboard
367400

368401
`POST /api/user/stars/dashboard/:dashboardId`

docs/sources/installation/ldap.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ start_tls = false
4040
ssl_skip_verify = false
4141
# set to the path to your root CA certificate or leave unset to use system defaults
4242
# root_ca_cert = "/path/to/certificate.crt"
43+
# Authentication against LDAP servers requiring client certificates
44+
# client_cert = "/path/to/client.crt"
45+
# client_key = "/path/to/client.key"
4346

4447
# Search user bind dn
4548
bind_dn = "cn=admin,dc=grafana,dc=org"

package.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@
4545
"grunt-contrib-concat": "^1.0.1",
4646
"grunt-contrib-copy": "~1.0.0",
4747
"grunt-contrib-cssmin": "~1.0.2",
48-
"grunt-contrib-jshint": "~1.1.0",
4948
"grunt-exec": "^1.0.1",
50-
"grunt-jscs": "3.0.1",
5149
"grunt-karma": "~2.0.0",
5250
"grunt-notify": "^0.4.5",
5351
"grunt-postcss": "^0.8.0",
@@ -60,7 +58,6 @@
6058
"html-webpack-plugin": "^3.2.0",
6159
"husky": "^0.14.3",
6260
"jest": "^22.0.4",
63-
"jshint-stylish": "~2.2.1",
6461
"karma": "1.7.0",
6562
"karma-chrome-launcher": "~2.2.0",
6663
"karma-expect": "~1.1.3",

pkg/api/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ func (hs *HTTPServer) registerRoutes() {
120120
userRoute.Put("/", bind(m.UpdateUserCommand{}), Wrap(UpdateSignedInUser))
121121
userRoute.Post("/using/:id", Wrap(UserSetUsingOrg))
122122
userRoute.Get("/orgs", Wrap(GetSignedInUserOrgList))
123+
userRoute.Get("/teams", Wrap(GetSignedInUserTeamList))
123124

124125
userRoute.Post("/stars/dashboard/:id", Wrap(StarDashboard))
125126
userRoute.Delete("/stars/dashboard/:id", Wrap(UnstarDashboard))

pkg/api/user.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ func GetSignedInUserOrgList(c *m.ReqContext) Response {
111111
return getUserOrgList(c.UserId)
112112
}
113113

114+
// GET /api/user/teams
115+
func GetSignedInUserTeamList(c *m.ReqContext) Response {
116+
query := m.GetTeamsByUserQuery{OrgId: c.OrgId, UserId: c.UserId}
117+
118+
if err := bus.Dispatch(&query); err != nil {
119+
return Error(500, "Failed to get user teams", err)
120+
}
121+
122+
for _, team := range query.Result {
123+
team.AvatarUrl = dtos.GetGravatarUrlWithDefault(team.Email, team.Name)
124+
}
125+
126+
return JSON(200, query.Result)
127+
}
128+
114129
// GET /api/user/:id/orgs
115130
func GetUserOrgList(c *m.ReqContext) Response {
116131
return getUserOrgList(c.ParamsInt64(":id"))

pkg/login/ldap.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ func (a *ldapAuther) Dial() error {
5959
}
6060
}
6161
}
62+
var clientCert tls.Certificate
63+
if a.server.ClientCert != "" && a.server.ClientKey != "" {
64+
clientCert, err = tls.LoadX509KeyPair(a.server.ClientCert, a.server.ClientKey)
65+
if err != nil {
66+
return err
67+
}
68+
}
6269
for _, host := range strings.Split(a.server.Host, " ") {
6370
address := fmt.Sprintf("%s:%d", host, a.server.Port)
6471
if a.server.UseSSL {
@@ -67,6 +74,9 @@ func (a *ldapAuther) Dial() error {
6774
ServerName: host,
6875
RootCAs: certPool,
6976
}
77+
if len(clientCert.Certificate) > 0 {
78+
tlsCfg.Certificates = append(tlsCfg.Certificates, clientCert)
79+
}
7080
if a.server.StartTLS {
7181
a.conn, err = ldap.Dial("tcp", address)
7282
if err == nil {

pkg/login/ldap_settings.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ type LdapServerConf struct {
2121
StartTLS bool `toml:"start_tls"`
2222
SkipVerifySSL bool `toml:"ssl_skip_verify"`
2323
RootCACert string `toml:"root_ca_cert"`
24+
ClientCert string `toml:"client_cert"`
25+
ClientKey string `toml:"client_key"`
2426
BindDN string `toml:"bind_dn"`
2527
BindPassword string `toml:"bind_password"`
2628
Attr LdapAttributeMap `toml:"attributes"`

pkg/services/alerting/notifier.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package alerting
33
import (
44
"errors"
55
"fmt"
6-
"time"
76

87
"golang.org/x/sync/errgroup"
98

@@ -81,7 +80,7 @@ func (n *notificationService) uploadImage(context *EvalContext) (err error) {
8180
renderOpts := rendering.Opts{
8281
Width: 1000,
8382
Height: 500,
84-
Timeout: time.Second * 30,
83+
Timeout: alertTimeout / 2,
8584
OrgId: context.Rule.OrgId,
8685
OrgRole: m.ROLE_ADMIN,
8786
}

pkg/tsdb/postgres/macros.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ const rsIdentifier = `([_a-zA-Z0-9]+)`
1414
const sExpr = `\$` + rsIdentifier + `\(([^\)]*)\)`
1515

1616
type postgresMacroEngine struct {
17-
timeRange *tsdb.TimeRange
18-
query *tsdb.Query
17+
timeRange *tsdb.TimeRange
18+
query *tsdb.Query
19+
timescaledb bool
1920
}
2021

21-
func newPostgresMacroEngine() tsdb.SqlMacroEngine {
22-
return &postgresMacroEngine{}
22+
func newPostgresMacroEngine(timescaledb bool) tsdb.SqlMacroEngine {
23+
return &postgresMacroEngine{timescaledb: timescaledb}
2324
}
2425

2526
func (m *postgresMacroEngine) Interpolate(query *tsdb.Query, timeRange *tsdb.TimeRange, sql string) (string, error) {
@@ -118,7 +119,12 @@ func (m *postgresMacroEngine) evaluateMacro(name string, args []string) (string,
118119
return "", err
119120
}
120121
}
121-
return fmt.Sprintf("floor(extract(epoch from %s)/%v)*%v", args[0], interval.Seconds(), interval.Seconds()), nil
122+
123+
if m.timescaledb {
124+
return fmt.Sprintf("time_bucket('%vs',%s)", interval.Seconds(), args[0]), nil
125+
} else {
126+
return fmt.Sprintf("floor(extract(epoch from %s)/%v)*%v", args[0], interval.Seconds(), interval.Seconds()), nil
127+
}
122128
case "__timeGroupAlias":
123129
tg, err := m.evaluateMacro("__timeGroup", args)
124130
if err == nil {

pkg/tsdb/postgres/macros_test.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import (
1212

1313
func TestMacroEngine(t *testing.T) {
1414
Convey("MacroEngine", t, func() {
15-
engine := newPostgresMacroEngine()
15+
timescaledbEnabled := false
16+
engine := newPostgresMacroEngine(timescaledbEnabled)
17+
timescaledbEnabled = true
18+
engineTS := newPostgresMacroEngine(timescaledbEnabled)
1619
query := &tsdb.Query{}
1720

1821
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
@@ -83,6 +86,22 @@ func TestMacroEngine(t *testing.T) {
8386
So(sql2, ShouldEqual, sql+" AS \"time\"")
8487
})
8588

89+
Convey("interpolate __timeGroup function with TimescaleDB enabled", func() {
90+
91+
sql, err := engineTS.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
92+
So(err, ShouldBeNil)
93+
94+
So(sql, ShouldEqual, "GROUP BY time_bucket('300s',time_column)")
95+
})
96+
97+
Convey("interpolate __timeGroup function with spaces between args and TimescaleDB enabled", func() {
98+
99+
sql, err := engineTS.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
100+
So(err, ShouldBeNil)
101+
102+
So(sql, ShouldEqual, "GROUP BY time_bucket('300s',time_column)")
103+
})
104+
86105
Convey("interpolate __timeTo function", func() {
87106
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
88107
So(err, ShouldBeNil)

pkg/tsdb/postgres/postgres.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ func newPostgresQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndp
3232
log: logger,
3333
}
3434

35-
return tsdb.NewSqlQueryEndpoint(&config, &rowTransformer, newPostgresMacroEngine(), logger)
35+
timescaledb := datasource.JsonData.Get("timescaledb").MustBool(false)
36+
37+
return tsdb.NewSqlQueryEndpoint(&config, &rowTransformer, newPostgresMacroEngine(timescaledb), logger)
3638
}
3739

3840
func generateConnectionString(datasource *models.DataSource) string {

0 commit comments

Comments
 (0)