diff --git a/CHANGELOG.md b/CHANGELOG.md index ebb62e80fdc..8d16e816f3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 5.0.0-beta4 (2018-02-19) + +### Fixes + +- **Dashboard** Fixed dashboard overwrite permission issue [#10814](https://github.com/grafana/grafana/issues/10814) +- **Keyboard shortcuts** Fixed Esc key when in panel edit/view mode [#10945](https://github.com/grafana/grafana/issues/10945) +- **Save dashboard** Fixed issue with time range & variable reset after saving [#10946](https://github.com/grafana/grafana/issues/10946) + # 5.0.0-beta3 (2018-02-16) ### Fixes diff --git a/conf/provisioning/dashboards/sample.yaml b/conf/provisioning/dashboards/sample.yaml index caaf3754b0f..d70bd425634 100644 --- a/conf/provisioning/dashboards/sample.yaml +++ b/conf/provisioning/dashboards/sample.yaml @@ -1,8 +1,5 @@ -# This file is only an example. -# Grafana will never read sample.yaml files - # # config file version -# apiVersion: 1 +apiVersion: 1 #providers: # - name: 'default' diff --git a/conf/provisioning/datasources/sample.yaml b/conf/provisioning/datasources/sample.yaml index 740b4c19772..877e229183d 100644 --- a/conf/provisioning/datasources/sample.yaml +++ b/conf/provisioning/datasources/sample.yaml @@ -1,8 +1,5 @@ -# This file is only an example. -# Grafana will never read sample.yaml files - # # config file version -# apiVersion: 1 +apiVersion: 1 # # list of datasources that should be deleted from the database #deleteDatasources: diff --git a/docker/blocks/prometheus2/docker-compose.yaml b/docker/blocks/prometheus2/docker-compose.yaml new file mode 100644 index 00000000000..7b133ed9000 --- /dev/null +++ b/docker/blocks/prometheus2/docker-compose.yaml @@ -0,0 +1,25 @@ + prometheus: + build: blocks/prometheus2 + network_mode: host + ports: + - "9090:9090" + + node_exporter: + image: prom/node-exporter + network_mode: host + ports: + - "9100:9100" + + fake-prometheus-data: + image: grafana/fake-data-gen + network_mode: host + ports: + - "9091:9091" + environment: + FD_DATASOURCE: prom + + alertmanager: + image: quay.io/prometheus/alertmanager + network_mode: host + ports: + - "9093:9093" diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index 9df942c6bed..a45afe35e6b 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -16,7 +16,7 @@ weight = 1 Description | Download ------------ | ------------- Stable for Debian-based Linux | [grafana_4.6.3_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_4.6.3_amd64.deb) -Beta for Debian-based Linux | [grafana_5.0.0-beta3_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.0-beta3_amd64.deb) +Beta for Debian-based Linux | [grafana_5.0.0-beta4_amd64.deb](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.0-beta4_amd64.deb) Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing installation. @@ -33,9 +33,9 @@ sudo dpkg -i grafana_4.6.3_amd64.deb ## Install Latest Beta ```bash -wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.0-beta3_amd64.deb +wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.0.0-beta4_amd64.deb sudo apt-get install -y adduser libfontconfig -sudo dpkg -i grafana_5.0.0-beta3_amd64.deb +sudo dpkg -i grafana_5.0.0-beta4_amd64.deb ``` ## APT Repository diff --git a/docs/sources/installation/rpm.md b/docs/sources/installation/rpm.md index db29ecb3343..e97ab17a697 100644 --- a/docs/sources/installation/rpm.md +++ b/docs/sources/installation/rpm.md @@ -16,7 +16,7 @@ weight = 2 Description | Download ------------ | ------------- Stable for CentOS / Fedora / OpenSuse / Redhat Linux | [4.6.3 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.3-1.x86_64.rpm) -Latest Beta for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.0-beta3 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta3.x86_64.rpm) +Latest Beta for CentOS / Fedora / OpenSuse / Redhat Linux | [5.0.0-beta4 (x86-64 rpm)](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta4.x86_64.rpm) Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing installation. @@ -32,7 +32,7 @@ $ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/g ## Install Beta ```bash -$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta3.x86_64.rpm +$ sudo yum install https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta4.x86_64.rpm ``` Or install manually using `rpm`. diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md index fb052101f44..07f5abde52f 100644 --- a/docs/sources/installation/windows.md +++ b/docs/sources/installation/windows.md @@ -14,7 +14,7 @@ weight = 3 Description | Download ------------ | ------------- Latest stable package for Windows | [grafana.4.6.3.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.6.3.windows-x64.zip) -Latest beta package for Windows | [grafana.5.0.0-beta3.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta3.windows-x64.zip) +Latest beta package for Windows | [grafana.5.0.0-beta4.windows-x64.zip](https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.0.0-beta4.windows-x64.zip) Read [Upgrading Grafana]({{< relref "installation/upgrading.md" >}}) for tips and guidance on updating an existing installation. diff --git a/package.json b/package.json index 645982e2b4c..1cae6360f01 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Grafana Labs" }, "name": "grafana", - "version": "5.0.0-beta3", + "version": "5.0.0-beta4", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" diff --git a/packaging/publish/publish_testing.sh b/packaging/publish/publish_testing.sh index f009631a52d..5dea3655251 100755 --- a/packaging/publish/publish_testing.sh +++ b/packaging/publish/publish_testing.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash -deb_ver=5.0.0-beta3 -rpm_ver=5.0.0-beta3 +deb_ver=5.0.0-beta4 +rpm_ver=5.0.0-beta4 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_${deb_ver}_amd64.deb diff --git a/pkg/models/datasource.go b/pkg/models/datasource.go index 9c1cb6fe9e2..d2b93c5c1d6 100644 --- a/pkg/models/datasource.go +++ b/pkg/models/datasource.go @@ -58,21 +58,22 @@ type DataSource struct { } var knownDatasourcePlugins map[string]bool = map[string]bool{ - DS_ES: true, - DS_GRAPHITE: true, - DS_INFLUXDB: true, - DS_INFLUXDB_08: true, - DS_KAIROSDB: true, - DS_CLOUDWATCH: true, - DS_PROMETHEUS: true, - DS_OPENTSDB: true, - DS_POSTGRES: true, - DS_MYSQL: true, - "opennms": true, - "druid": true, - "dalmatinerdb": true, - "gnocci": true, - "zabbix": true, + DS_ES: true, + DS_GRAPHITE: true, + DS_INFLUXDB: true, + DS_INFLUXDB_08: true, + DS_KAIROSDB: true, + DS_CLOUDWATCH: true, + DS_PROMETHEUS: true, + DS_OPENTSDB: true, + DS_POSTGRES: true, + DS_MYSQL: true, + "opennms": true, + "abhisant-druid-datasource": true, + "dalmatinerdb-datasource": true, + "gnocci": true, + "zabbix": true, + "alexanderzobnin-zabbix-datasource": true, "newrelic-app": true, "grafana-datadog-datasource": true, "grafana-simple-json": true, diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index 558f61871ba..53012f3e817 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -35,7 +35,7 @@ type DashboardInputMissingError struct { } func (e DashboardInputMissingError) Error() string { - return fmt.Sprintf("Dashbord input variable: %v missing from import command", e.VariableName) + return fmt.Sprintf("Dashboard input variable: %v missing from import command", e.VariableName) } func init() { diff --git a/pkg/services/dashboards/dashboard_service.go b/pkg/services/dashboards/dashboard_service.go index d10a44ac6a6..1f39394d757 100644 --- a/pkg/services/dashboards/dashboard_service.go +++ b/pkg/services/dashboards/dashboard_service.go @@ -118,6 +118,7 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO, UserId: dto.User.UserId, FolderId: dash.FolderId, IsFolder: dash.IsFolder, + PluginId: dash.PluginId, } if !dto.UpdatedAt.IsZero() { diff --git a/pkg/services/provisioning/dashboards/config_reader.go b/pkg/services/provisioning/dashboards/config_reader.go index 3183d21262a..9030ba609b9 100644 --- a/pkg/services/provisioning/dashboards/config_reader.go +++ b/pkg/services/provisioning/dashboards/config_reader.go @@ -63,7 +63,7 @@ func (cr *configReader) readConfig() ([]*DashboardsAsConfig, error) { } for _, file := range files { - if (!strings.HasSuffix(file.Name(), ".yaml") && !strings.HasSuffix(file.Name(), ".yml")) || file.Name() == "sample.yaml" { + if !strings.HasSuffix(file.Name(), ".yaml") && !strings.HasSuffix(file.Name(), ".yml") { continue } diff --git a/pkg/services/provisioning/dashboards/test-configs/dashboards-from-disk/sample.yaml b/pkg/services/provisioning/dashboards/test-configs/dashboards-from-disk/sample.yaml index 9090e5f472a..5b73632b1ff 100644 --- a/pkg/services/provisioning/dashboards/test-configs/dashboards-from-disk/sample.yaml +++ b/pkg/services/provisioning/dashboards/test-configs/dashboards-from-disk/sample.yaml @@ -1,10 +1,10 @@ apiVersion: 1 -providers: -- name: 'gasdf' - orgId: 2 - folder: 'developers' - editable: true - type: file - options: - path: /var/lib/grafana/dashboards +#providers: +#- name: 'gasdf' +# orgId: 2 +# folder: 'developers' +# editable: true +# type: file +# options: +# path: /var/lib/grafana/dashboards diff --git a/pkg/services/provisioning/datasources/config_reader.go b/pkg/services/provisioning/datasources/config_reader.go index 82504f4972b..58ed5472a6b 100644 --- a/pkg/services/provisioning/datasources/config_reader.go +++ b/pkg/services/provisioning/datasources/config_reader.go @@ -24,7 +24,7 @@ func (cr *configReader) readConfig(path string) ([]*DatasourcesAsConfig, error) } for _, file := range files { - if (strings.HasSuffix(file.Name(), ".yaml") || strings.HasSuffix(file.Name(), ".yml")) && file.Name() != "sample.yaml" { + if strings.HasSuffix(file.Name(), ".yaml") || strings.HasSuffix(file.Name(), ".yml") { datasource, err := cr.parseDatasourceConfig(path, file) if err != nil { return nil, err diff --git a/pkg/services/provisioning/datasources/config_reader_test.go b/pkg/services/provisioning/datasources/config_reader_test.go index 9a0419232ac..3198329e0ae 100644 --- a/pkg/services/provisioning/datasources/config_reader_test.go +++ b/pkg/services/provisioning/datasources/config_reader_test.go @@ -138,7 +138,7 @@ func TestDatasourceAsConfig(t *testing.T) { t.Fatalf("readConfig return an error %v", err) } - So(len(cfg), ShouldEqual, 2) + So(len(cfg), ShouldEqual, 3) dsCfg := cfg[0] @@ -146,6 +146,17 @@ func TestDatasourceAsConfig(t *testing.T) { validateDatasource(dsCfg) validateDeleteDatasources(dsCfg) + + dsCount := 0 + delDsCount := 0 + + for _, c := range cfg { + dsCount += len(c.Datasources) + delDsCount += len(c.DeleteDatasources) + } + + So(dsCount, ShouldEqual, 2) + So(delDsCount, ShouldEqual, 1) }) Convey("can read all properties from version 0", func() { diff --git a/pkg/services/provisioning/datasources/test-configs/all-properties/sample.yaml b/pkg/services/provisioning/datasources/test-configs/all-properties/sample.yaml index 70ad6c6d2f6..2187eabdc46 100644 --- a/pkg/services/provisioning/datasources/test-configs/all-properties/sample.yaml +++ b/pkg/services/provisioning/datasources/test-configs/all-properties/sample.yaml @@ -3,30 +3,30 @@ apiVersion: 1 -datasources: - - name: name - type: type - access: proxy - orgId: 2 - url: url - password: password - user: user - database: database - basicAuth: true - basicAuthUser: basic_auth_user - basicAuthPassword: basic_auth_password - withCredentials: true - jsonData: - graphiteVersion: "1.1" - tlsAuth: true - tlsAuthWithCACert: true - secureJsonData: - tlsCACert: "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA==" - tlsClientCert: "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ==" - tlsClientKey: "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A==" - editable: true - version: 10 - -deleteDatasources: - - name: old-graphite3 - orgId: 2 +#datasources: +# - name: name +# type: type +# access: proxy +# orgId: 2 +# url: url +# password: password +# user: user +# database: database +# basicAuth: true +# basicAuthUser: basic_auth_user +# basicAuthPassword: basic_auth_password +# withCredentials: true +# jsonData: +# graphiteVersion: "1.1" +# tlsAuth: true +# tlsAuthWithCACert: true +# secureJsonData: +# tlsCACert: "MjNOcW9RdkbUDHZmpco2HCYzVq9dE+i6Yi+gmUJotq5CDA==" +# tlsClientCert: "ckN0dGlyMXN503YNfjTcf9CV+GGQneN+xmAclQ==" +# tlsClientKey: "ZkN4aG1aNkja/gKAB1wlnKFIsy2SRDq4slrM0A==" +# editable: true +# version: 10 +# +#deleteDatasources: +# - name: old-graphite3 +# orgId: 2 diff --git a/pkg/social/github_oauth.go b/pkg/social/github_oauth.go index c74e8825bc1..6f00cd2cd9e 100644 --- a/pkg/social/github_oauth.go +++ b/pkg/social/github_oauth.go @@ -210,7 +210,7 @@ func (s *SocialGithub) UserInfo(client *http.Client, token *oauth2.Token) (*Basi if err != nil { return nil, fmt.Errorf("Error getting user info: %s", err) } - data.OrganizationsUrl = s.apiUrl + "/user/orgs" + userInfo := &BasicUserInfo{ Name: data.Login, Login: data.Login, diff --git a/pkg/tsdb/influxdb/query.go b/pkg/tsdb/influxdb/query.go index 499f446e9f0..0a16a507877 100644 --- a/pkg/tsdb/influxdb/query.go +++ b/pkg/tsdb/influxdb/query.go @@ -70,7 +70,7 @@ func (query *Query) renderTags() []string { } else if tag.Operator == "<" || tag.Operator == ">" { textValue = tag.Value } else { - textValue = fmt.Sprintf("'%s'", tag.Value) + textValue = fmt.Sprintf("'%s'", strings.Replace(tag.Value, `\`, `\\`, -1)) } res = append(res, fmt.Sprintf(`%s"%s" %s %s`, str, tag.Key, tag.Operator, textValue)) diff --git a/pkg/tsdb/influxdb/query_test.go b/pkg/tsdb/influxdb/query_test.go index 4a620539a26..f1270560269 100644 --- a/pkg/tsdb/influxdb/query_test.go +++ b/pkg/tsdb/influxdb/query_test.go @@ -170,6 +170,12 @@ func TestInfluxdbQueryBuilder(t *testing.T) { So(strings.Join(query.renderTags(), ""), ShouldEqual, `"key" = 'value'`) }) + Convey("can escape backslashes when rendering string tags", func() { + query := &Query{Tags: []*Tag{{Operator: "=", Value: `C:\test\`, Key: "key"}}} + + So(strings.Join(query.renderTags(), ""), ShouldEqual, `"key" = 'C:\\test\\'`) + }) + Convey("can render regular measurement", func() { query := &Query{Measurement: `apa`, Policy: "policy"} diff --git a/public/app/core/components/org_switcher.ts b/public/app/core/components/org_switcher.ts index 1816e11af49..f7b53fa3c81 100644 --- a/public/app/core/components/org_switcher.ts +++ b/public/app/core/components/org_switcher.ts @@ -15,8 +15,7 @@ const template = ` - - diff --git a/public/app/features/org/select_org_ctrl.ts b/public/app/features/org/select_org_ctrl.ts index 1001b4b41e5..199d1f8ac94 100644 --- a/public/app/features/org/select_org_ctrl.ts +++ b/public/app/features/org/select_org_ctrl.ts @@ -6,6 +6,14 @@ export class SelectOrgCtrl { constructor($scope, backendSrv, contextSrv) { contextSrv.sidemenu = false; + $scope.navModel = { + main: { + icon: 'gicon gicon-branding', + subTitle: 'Preferences', + text: 'Select active organization', + }, + }; + $scope.init = function() { $scope.getUserOrgs(); }; diff --git a/public/app/features/plugins/import_list/import_list.html b/public/app/features/plugins/import_list/import_list.html index fec7ba190ec..523005ae87b 100644 --- a/public/app/features/plugins/import_list/import_list.html +++ b/public/app/features/plugins/import_list/import_list.html @@ -9,9 +9,7 @@ {{dash.title}} - - {{dash.title}} - + {{dash.title}}