Skip to content

Commit c74a1c1

Browse files
committed
Merge branch 'master' of github.com:grafana/grafana into react-panels
2 parents 542da8d + 3a9a36d commit c74a1c1

File tree

22 files changed

+622
-267
lines changed

22 files changed

+622
-267
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
* **Auth Proxy**: Whitelist proxy IP address instead of client IP address [#10707](https://github.com/grafana/grafana/issues/10707)
2222
* **User Management**: Make sure that a user always has a current org assigned [#11076](https://github.com/grafana/grafana/issues/11076)
2323
* **Snapshots**: Fix: annotations not properly extracted leading to incorrect rendering of annotations [#12278](https://github.com/grafana/grafana/issues/12278)
24+
* **LDAP**: Allow use of DN in group_search_filter_user_attribute and member_of [#3132](https://github.com/grafana/grafana/issues/3132), thx [@mmolnar](https://github.com/mmolnar)
2425

2526
# 5.2.0-beta1 (2018-06-05)
2627

@@ -62,6 +63,10 @@
6263
* **Dashboard list panel**: Search dashboards by folder [#11525](https://github.com/grafana/grafana/issues/11525)
6364
* **Sidenav**: Always show server admin link in sidenav if grafana admin [#11657](https://github.com/grafana/grafana/issues/11657)
6465

66+
# 5.1.4 (2018-06-19)
67+
68+
* **Permissions**: Important security fix for API keys with viewer role [#12343](https://github.com/grafana/grafana/issues/12343)
69+
6570
# 5.1.3 (2018-05-16)
6671

6772
* **Scroll**: Graph panel / legend texts shifts on the left each time we move scrollbar on firefox [#11830](https://github.com/grafana/grafana/issues/11830)

docker/blocks/openldap/Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Fork of https://github.com/dinkel/docker-openldap
2+
13
FROM debian:jessie
24

35
LABEL maintainer="Christian Luginbühl <[email protected]>"

docker/blocks/openldap/notes.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ After adding ldif files to `prepopulate`:
1111
1. Remove your current docker image: `docker rm docker_openldap_1`
1212
2. Build: `docker-compose build`
1313
3. `docker-compose up`
14+
15+
## Enabling LDAP in Grafana
16+
17+
The default `ldap.toml` file in `conf` has host set to `127.0.0.1` and port to set to 389 so all you need to do is enable it in the .ini file to get Grafana to use this block:
18+
19+
```ini
20+
[auth.ldap]
21+
enabled = true
22+
config_file = conf/ldap.toml
23+
; allow_sign_up = true
24+
```

docs/sources/installation/debian.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ weight = 1
1515

1616
Description | Download
1717
------------ | -------------
18-
Stable for Debian-based Linux | [grafana_5.1.3_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.1.3_amd64.deb)
18+
Stable for Debian-based Linux | [grafana_5.1.4_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.1.4_amd64.deb)
1919
<!--
2020
Beta for Debian-based Linux | [grafana_5.1.0-beta1_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.1.0-beta1_amd64.deb)
2121
-->
@@ -27,9 +27,9 @@ installation.
2727

2828

2929
```bash
30-
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.1.3_amd64.deb
30+
wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.1.4_amd64.deb
3131
sudo apt-get install -y adduser libfontconfig
32-
sudo dpkg -i grafana_5.1.3_amd64.deb
32+
sudo dpkg -i grafana_5.1.4_amd64.deb
3333
```
3434

3535
<!-- ## Install Latest Beta

docs/sources/installation/rpm.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ weight = 2
1515

1616
Description | Download
1717
------------ | -------------
18-
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.1.3 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.3-1.x86_64.rpm)
18+
Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [5.1.4 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.4-1.x86_64.rpm)
1919
<!--
2020
Latest Beta for CentOS / Fedora / OpenSuse / Redhat Linux | [5.1.0-beta1 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.0-beta1.x86_64.rpm)
2121
-->
@@ -28,7 +28,7 @@ installation.
2828
You can install Grafana using Yum directly.
2929

3030
```bash
31-
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.3-1.x86_64.rpm
31+
$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.4-1.x86_64.rpm
3232
```
3333

3434
<!-- ## Install Beta
@@ -42,15 +42,15 @@ Or install manually using `rpm`.
4242
#### On CentOS / Fedora / Redhat:
4343

4444
```bash
45-
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.3-1.x86_64.rpm
45+
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.4-1.x86_64.rpm
4646
$ sudo yum install initscripts fontconfig
47-
$ sudo rpm -Uvh grafana-5.1.3-1.x86_64.rpm
47+
$ sudo rpm -Uvh grafana-5.1.4-1.x86_64.rpm
4848
```
4949

5050
#### On OpenSuse:
5151

5252
```bash
53-
$ sudo rpm -i --nodeps grafana-5.1.3-1.x86_64.rpm
53+
$ sudo rpm -i --nodeps grafana-5.1.4-1.x86_64.rpm
5454
```
5555

5656
## Install via YUM Repository

docs/sources/installation/windows.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ weight = 3
1212

1313
Description | Download
1414
------------ | -------------
15-
Latest stable package for Windows | [grafana-5.1.3.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.3.windows-x64.zip)
15+
Latest stable package for Windows | [grafana-5.1.4.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1.4.windows-x64.zip)
1616

1717
<!--
1818
Latest beta package for Windows | [grafana.5.1.0-beta1.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta5.windows-x64.zip)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
+++
2+
title = "Authentication for Datasource Plugins"
3+
type = "docs"
4+
[menu.docs]
5+
name = "Authentication for Datasource Plugins"
6+
parent = "developing"
7+
weight = 3
8+
+++
9+
10+
# Authentication for Datasource Plugins
11+
12+
Grafana has a proxy feature that proxies all data requests through the Grafana backend. This is very useful when your datasource plugin calls an external/thirdy-party API. The Grafana proxy adds CORS headers and can authenticate against the external API. This means that a datasource plugin that proxies all requests via Grafana can enable token authentication and the token will be renewed automatically for the user when it expires.
13+
14+
The plugin config page should save the API key/password to be encrypted (using the `secureJsonData` feature) and then when a request from the datasource is made, the Grafana Proxy will:
15+
16+
1. decrypt the API key/password on the backend.
17+
2. carry out authentication and generate an OAuth token that will be added as an `Authorization` HTTP header to all requests (or it will add a HTTP header with the API key).
18+
3. renew the token if it expires.
19+
20+
This means that users that access the datasource config page cannot access the API key or password after is saved the first time and that no secret keys are sent in plain text through the browser where they can be spied on.
21+
22+
For backend authentication to work, the external/third-party API must either have an OAuth endpoint or that the API accepts an API key as a HTTP header for authentication.
23+
24+
## Plugin Routes
25+
26+
You can specify routes in the `plugin.json` file for your datasource plugin. [Here is an example](https://github.com/grafana/azure-monitor-datasource/blob/d74c82145c0a4af07a7e96cc8dde231bfd449bd9/src/plugin.json#L30-L95) with lots of routes (though most plugins will just have one route).
27+
28+
When you build your url to the third-party API in your datasource class, the url should start with the text specified in the path field for a route. The proxy will strip out the path text and replace it with the value in the url field.
29+
30+
For example, if my code makes a call to url `azuremonitor/foo/bar` with this code:
31+
32+
```js
33+
this.backendSrv.datasourceRequest({
34+
url: url,
35+
method: 'GET',
36+
})
37+
```
38+
39+
and this route:
40+
41+
```json
42+
"routes": [{
43+
"path": "azuremonitor",
44+
"method": "GET",
45+
"url": "https://management.azure.com",
46+
...
47+
}]
48+
```
49+
50+
then the Grafana proxy will transform it into "https://management.azure.com/foo/bar" and add CORS headers.
51+
52+
The `method` parameter is optional. It can be set to any HTTP verb to provide more fine-grained control.
53+
54+
## Encrypting Sensitive Data
55+
56+
When a user saves a password or secret with your datasource plugin's Config page, then you can save data to a column in the datasource table called `secureJsonData` that is an encrypted blob. Any data saved in the blob is encrypted by Grafana and can only be decrypted by the Grafana server on the backend. This means once a password is saved, no sensitive data is sent to the browser. If the password is saved in the `jsonData` blob or the `password` field then it is unencrypted and anyone with Admin access (with the help of Chrome Developer Tools) can read it.
57+
58+
This is an example of using the `secureJsonData` blob to save a property called `password`:
59+
60+
```html
61+
<input type="password" class="gf-form-input" ng-model='ctrl.current.secureJsonData.password' placeholder="password"></input>
62+
```
63+
64+
## API Key/HTTP Header Authentication
65+
66+
Some third-party API's accept a HTTP Header for authentication. The [example](https://github.com/grafana/azure-monitor-datasource/blob/d74c82145c0a4af07a7e96cc8dde231bfd449bd9/src/plugin.json#L91-L93) below has a `headers` section that defines the name of the HTTP Header that the API expects and it uses the `SecureJSONData` blob to fetch an encrypted API key. The Grafana server proxy will decrypt the key, add the `X-API-Key` header to the request and forward it to the third-party API.
67+
68+
```json
69+
{
70+
"path": "appinsights",
71+
"method": "GET",
72+
"url": "https://api.applicationinsights.io",
73+
"headers": [
74+
{"name": "X-API-Key", "content": "{{.SecureJsonData.appInsightsApiKey}}"}
75+
]
76+
}
77+
```
78+
79+
## How Token Authentication Works
80+
81+
The token auth section in the `plugin.json` file looks like this:
82+
83+
```json
84+
"tokenAuth": {
85+
"url": "https://login.microsoftonline.com/{{.JsonData.tenantId}}/oauth2/token",
86+
"params": {
87+
"grant_type": "client_credentials",
88+
"client_id": "{{.JsonData.clientId}}",
89+
"client_secret": "{{.SecureJsonData.clientSecret}}",
90+
"resource": "https://management.azure.com/"
91+
}
92+
}
93+
```
94+
95+
This interpolates in data from both `jsonData` and `secureJsonData` to generate the token request to the third-party API. It is common for tokens to have a short expiry period (30 minutes). The proxy in Grafana server will automatically renew the token if it has expired.
96+
97+
## Always Restart the Grafana Server After Route Changes
98+
99+
The plugin.json files are only loaded when the Grafana server starts so when a route is added or changed then the Grafana server has to be restarted for the changes to take effect.
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
+++
2+
title = "Plugin Review Guidelines"
3+
type = "docs"
4+
[menu.docs]
5+
name = "Plugin Review Guidelines"
6+
parent = "developing"
7+
weight = 2
8+
+++
9+
10+
# Plugin Review Guidelines
11+
12+
The Grafana team reviews all plugins that are published on Grafana.com. There are two areas we review, the metadata for the plugin and the plugin functionality.
13+
14+
## Metadata
15+
16+
The plugin metadata consists of a `plugin.json` file and the README.md file. These `plugin.json` file is used by Grafana to load the plugin and the README.md file is shown in the plugins section of Grafana and the plugins section of Grafana.com.
17+
18+
### README.md
19+
20+
The README.md file is shown on the plugins page in Grafana and the plugin page on Grafana.com. There are some differences between the GitHub markdown and the markdown allowed in Grafana/Grafana.com:
21+
22+
- Cannot contain inline HTML.
23+
- Any image links should be absolute links. For example: https://raw.githubusercontent.com/grafana/azure-monitor-datasource/master/dist/img/grafana_cloud_install.png
24+
25+
The README should:
26+
27+
- describe the purpose of the plugin.
28+
- contain steps on how to get started.
29+
30+
### Plugin.json
31+
32+
The `plugin.json` file is the same concept as the `package.json` file for an npm package. When the Grafana server starts it will scan the plugin folders (all folders in the data/plugins subfolder) and load every folder that contains a `plugin.json` file unless the folder contains a subfolder named `dist`. In that case, the Grafana server will load the `dist` folder instead.
33+
34+
A minimal `plugin.json` file:
35+
36+
```json
37+
{
38+
"type": "panel",
39+
"name": "Clock",
40+
"id": "yourorg-clock-panel",
41+
42+
"info": {
43+
"description": "Clock panel for grafana",
44+
"author": {
45+
"name": "Author Name",
46+
"url": "http://yourwebsite.com"
47+
},
48+
"keywords": ["clock", "panel"],
49+
"version": "1.0.0",
50+
"updated": "2018-03-24"
51+
},
52+
53+
"dependencies": {
54+
"grafanaVersion": "3.x.x",
55+
"plugins": [ ]
56+
}
57+
}
58+
```
59+
60+
- The convention for the plugin id is [github username/org]-[plugin name]-[datasource|app|panel] and it has to be unique. Although if org and plugin name are the same then [plugin name]-[datasource|app|panel] is also valid. The org **cannot** be `grafana` unless it is a plugin created by the Grafana core team.
61+
62+
Examples:
63+
64+
- raintank-worldping-app
65+
- ryantxu-ajax-panel
66+
- alexanderzobnin-zabbix-app
67+
- hawkular-datasource
68+
69+
- The `type` field should be either `datasource` `app` or `panel`.
70+
- The `version` field should be in the form: x.x.x e.g. `1.0.0` or `0.4.1`.
71+
72+
The full file format for the `plugin.json` file is described [here](http://docs.grafana.org/plugins/developing/plugin.json/).
73+
74+
## Plugin Language
75+
76+
JavaScript, TypeScript, ES6 (or any other language) are all fine as long as the contents of the `dist` subdirectory are transpiled to JavaScript (ES5).
77+
78+
## File and Directory Structure Conventions
79+
80+
Here is a typical directory structure for a plugin.
81+
82+
```bash
83+
johnnyb-awesome-datasource
84+
|-- dist
85+
|-- src
86+
| |-- img
87+
| | |-- logo.svg
88+
| |-- partials
89+
| | |-- annotations.editor.html
90+
| | |-- config.html
91+
| | |-- query.editor.html
92+
| |-- datasource.js
93+
| |-- module.js
94+
| |-- plugin.json
95+
| |-- query_ctrl.js
96+
|-- Gruntfile.js
97+
|-- LICENSE
98+
|-- package.json
99+
|-- README.md
100+
```
101+
102+
Most JavaScript projects have a build step. The generated JavaScript should be placed in the `dist` directory and the source code in the `src` directory. We recommend that the plugin.json file be placed in the src directory and then copied over to the dist directory when building. The `README.md` can be placed in the root or in the dist directory.
103+
104+
Directories:
105+
106+
- `src/` contains plugin source files.
107+
- `src/partials` contains html templates.
108+
- `src/img` contains plugin logos and other images.
109+
- `dist/` contains built content.
110+
111+
## HTML and CSS
112+
113+
For the HTML on editor tabs, we recommend using the inbuilt Grafana styles rather than defining your own. This makes plugins feel like a more natural part of Grafana. If done correctly, the html will also be responsive and adapt to smaller screens. The `gf-form` css classes should be used for labels and inputs.
114+
115+
Below is a minimal example of an editor row with one form group and two fields, a dropdown and a text input:
116+
117+
```html
118+
<div class="editor-row">
119+
<div class="section gf-form-group">
120+
<h5 class="section-heading">My Plugin Options</h5>
121+
<div class="gf-form">
122+
<label class="gf-form-label width-10">Label1</label>
123+
<div class="gf-form-select-wrapper max-width-10">
124+
<select class="input-small gf-form-input" ng-model="ctrl.panel.mySelectProperty" ng-options="t for t in ['option1', 'option2', 'option3']" ng-change="ctrl.onSelectChange()"></select>
125+
</div>
126+
<div class="gf-form">
127+
<label class="gf-form-label width-10">Label2</label>
128+
<input type="text" class="input-small gf-form-input width-10" ng-model="ctrl.panel.myProperty" ng-change="ctrl.onFieldChange()" placeholder="suggestion for user" ng-model-onblur />
129+
</div>
130+
</div>
131+
</div>
132+
</div>
133+
```
134+
135+
Use the `width-x` and `max-width-x` classes to control the width of your labels and input fields. Try to get labels and input fields to line up neatly by having the same width for all the labels in a group and the same width for all inputs in a group if possible.
136+
137+
## Data Sources
138+
139+
A basic guide for data sources can be found [here](http://docs.grafana.org/plugins/developing/datasources/).
140+
141+
### Config Page Guidelines
142+
143+
- It should be as easy as possible for a user to configure a url. If the data source is using the `datasource-http-settings` component, it should use the `suggest-url` attribute to suggest the default url or a url that is similar to what it should be (especially important if the url refers to a REST endpoint that is not common knowledge for most users e.g. `https://yourserver:4000/api/custom-endpoint`).
144+
145+
```html
146+
<datasource-http-settings
147+
current="ctrl.current"
148+
suggest-url="http://localhost:8080">
149+
</datasource-http-settings>
150+
```
151+
152+
- The `testDatasource` function should make a query to the data source that will also test that the authentication details are correct. This is so the data source is correctly configured when the user tries to write a query in a new dashboard.
153+
154+
#### Password Security
155+
156+
If possible, any passwords or secrets should be be saved in the `secureJsonData` blob. To encrypt sensitive data, the Grafana server's proxy feature must be used. The Grafana server has support for token authentication (OAuth) and HTTP Header authentication. If the calls have to be sent directly from the browser to a third-party API then this will not be possible and sensitive data will not be encrypted.
157+
158+
Read more here about how [Authentication for Datasources]({{< relref "auth-for-datasources.md" >}}) works.
159+
160+
If using the proxy feature then the Config page should use the `secureJsonData` blob like this:
161+
162+
- good: `<input type="password" class="gf-form-input" ng-model='ctrl.current.secureJsonData.password' placeholder="password"></input>`
163+
- bad: `<input type="password" class="gf-form-input" ng-model='ctrl.current.password' placeholder="password"></input>`
164+
165+
### Query Editor
166+
167+
Each query editor is unique and can have a unique style. It should be adapted to what the users of the data source are used to.
168+
169+
- Should use the Grafana CSS `gf-form` classes.
170+
- Should be neat and tidy. Labels and fields in columns should be aligned and should be the same width if possible.
171+
- The datasource should be able to handle when a user toggles a query (by clicking on the eye icon) and not execute the query. This is done by checking the `hide` property - an [example](https://github.com/grafana/grafana/blob/master/public/app/plugins/datasource/postgres/datasource.ts#L35-L38).
172+
- Should not execute queries if fields in the Query Editor are empty and the query will throw an exception (defensive programming).
173+
- Should handle errors. There are two main ways to do this:
174+
- use the notification system in Grafana to show a toaster popup with the error message. Example [here](https://github.com/alexanderzobnin/grafana-zabbix/blob/fdbbba2fb03f5f2a4b3b0715415e09d5a4cf6cde/src/panel-triggers/triggers_panel_ctrl.js#L467-L471).
175+
- provide an error notification in the query editor like the MySQL/Postgres data sources do. Example code in the `query_ctrl` [here](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/query_ctrl.ts#L36-L51) and in the [html](https://github.com/grafana/azure-monitor-datasource/blob/b184d077f082a69f962120ef0d1f8296a0d46f03/src/partials/query.editor.html#L190-L193).

0 commit comments

Comments
 (0)