Pārlūkot izejas kodu

Merge branch 'master' into influxdb_stop_hidden_queries

bergquist 9 gadi atpakaļ
vecāks
revīzija
b47a307106
34 mainītis faili ar 201 papildinājumiem un 72 dzēšanām
  1. 13 2
      CHANGELOG.md
  2. 3 0
      conf/defaults.ini
  3. 1 1
      docs/VERSION
  4. 10 3
      docs/sources/installation/debian.md
  5. 20 2
      docs/sources/installation/rpm.md
  6. 9 1
      docs/sources/reference/export_import.md
  7. 1 0
      docs/sources/versions.html_fragment
  8. 2 2
      package.json
  9. 8 8
      packaging/publish/publish.sh
  10. 19 15
      pkg/api/cloudwatch/metrics.go
  11. 1 0
      pkg/api/login.go
  12. 11 0
      pkg/cmd/grafana-cli/commands/command_line.go
  13. 8 0
      pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go
  14. 4 4
      pkg/cmd/grafana-cli/commands/install_command.go
  15. 1 1
      pkg/cmd/grafana-cli/commands/listremote_command.go
  16. 1 1
      pkg/cmd/grafana-cli/commands/ls_command.go
  17. 10 8
      pkg/cmd/grafana-cli/commands/remove_command.go
  18. 1 1
      pkg/cmd/grafana-cli/commands/upgrade_all_command.go
  19. 2 2
      pkg/cmd/grafana-cli/commands/upgrade_command.go
  20. 10 3
      pkg/cmd/grafana-cli/services/services.go
  21. 0 2
      pkg/middleware/middleware_test.go
  22. 2 0
      pkg/setting/setting.go
  23. 1 0
      public/app/core/controllers/login_ctrl.js
  24. 0 4
      public/app/core/services/alert_srv.ts
  25. 1 1
      public/app/core/services/backend_srv.ts
  26. 6 0
      public/app/core/utils/kbn.js
  27. 4 4
      public/app/partials/login.html
  28. 1 1
      public/app/plugins/datasource/prometheus/datasource.ts
  29. 1 1
      public/app/plugins/panel/graph/series_overrides_ctrl.js
  30. 4 1
      public/app/plugins/panel/singlestat/editor.html
  31. 18 4
      public/app/plugins/panel/singlestat/module.ts
  32. 16 0
      public/app/plugins/panel/singlestat/specs/singlestat-specs.ts
  33. 7 0
      public/sass/_old_responsive.scss
  34. 5 0
      public/sass/components/_gf-form.scss

+ 13 - 2
CHANGELOG.md

@@ -1,4 +1,16 @@
-# 3.1.0 (unreleased)
+# 3.2.0-pre (unreleased)
+
+### Enhancements
+* **Login**: Adds option to disable username/password logins, closes [#4674](https://github.com/grafana/grafana/issues/4674)
+* **SingleStat**: Add seriename as option in singlestat panel, closes [#4740](https://github.com/grafana/grafana/issues/4740)
+
+
+# 3.1.0 stable (unreleased)
+
+### Bugfixes
+* **User Alert Notices**: Backend error alert popups did not show properly, fixes [#5435](https://github.com/grafana/grafana/issues/5435)
+
+# 3.1.0-beta1 (2016-06-23)
 
 
 ### Enhancements
 ### Enhancements
 * **Dashboard Export/Import**: Dashboard export now templetize data sources and constant variables, users pick these on import, closes [#5084](https://github.com/grafana/grafana/issues/5084)
 * **Dashboard Export/Import**: Dashboard export now templetize data sources and constant variables, users pick these on import, closes [#5084](https://github.com/grafana/grafana/issues/5084)
@@ -11,7 +23,6 @@
 * **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211)
 * **InfluxDB**: Add spread function, closes [#5211](https://github.com/grafana/grafana/issues/5211)
 * **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282)
 * **Scripts**: Use restart instead of start for deb package script, closes [#5282](https://github.com/grafana/grafana/pull/5282)
 * **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590)
 * **Logging**: Moved to structured logging lib, and moved to component specific level filters via config file, closes [#4590](https://github.com/grafana/grafana/issues/4590)
-* **Search**: Add search limit query parameter, closes [#5292](https://github.com/grafana/grafana/pull/5292)
 * **OpenTSDB**: Support nested template variables in tag_values function, closes [#4398](https://github.com/grafana/grafana/issues/4398)
 * **OpenTSDB**: Support nested template variables in tag_values function, closes [#4398](https://github.com/grafana/grafana/issues/4398)
 * **Datasource**: Pending data source requests are cancelled before new ones are issues (Graphite & Prometheus), closes [#5321](https://github.com/grafana/grafana/issues/5321)
 * **Datasource**: Pending data source requests are cancelled before new ones are issues (Graphite & Prometheus), closes [#5321](https://github.com/grafana/grafana/issues/5321)
 
 

+ 3 - 0
conf/defaults.ini

@@ -178,6 +178,9 @@ login_hint = email or username
 # Default UI theme ("dark" or "light")
 # Default UI theme ("dark" or "light")
 default_theme = dark
 default_theme = dark
 
 
+# Allow users to sign in using username and password
+allow_user_pass_login = true
+
 #################################### Anonymous Auth ##########################
 #################################### Anonymous Auth ##########################
 [auth.anonymous]
 [auth.anonymous]
 # enable anonymous access
 # enable anonymous access

+ 1 - 1
docs/VERSION

@@ -1 +1 @@
-3.0.0
+3.1.0

+ 10 - 3
docs/sources/installation/debian.md

@@ -10,7 +10,8 @@ page_keywords: grafana, installation, debian, ubuntu, guide
 
 
 Description | Download
 Description | Download
 ------------ | -------------
 ------------ | -------------
-Stable .deb for Debian-based Linux | [grafana_3.0.4-1464167696.deb](https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.4-1464167696_amd64.deb)
+Stable .deb for Debian-based Linux | [3.0.4](https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.4-1464167696_amd64.deb)
+Beta .deb for Debian-based Linux | [3.1.0-beta1](https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.0-1466666977beta1_amd64.deb)
 
 
 ## Install Stable
 ## Install Stable
 
 
@@ -18,17 +19,23 @@ Stable .deb for Debian-based Linux | [grafana_3.0.4-1464167696.deb](https://graf
     $ sudo apt-get install -y adduser libfontconfig
     $ sudo apt-get install -y adduser libfontconfig
     $ sudo dpkg -i grafana_3.0.4-1464167696_amd64.deb
     $ sudo dpkg -i grafana_3.0.4-1464167696_amd64.deb
 
 
+## Install 3.1 beta
+
+    $ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.1.0-1466666977beta1_amd64.deb
+    $ sudo apt-get install -y adduser libfontconfig
+    $ sudo dpkg -i grafana_3.1.0-1466666977beta1_amd64.deb
+
 ## APT Repository
 ## APT Repository
 
 
 Add the following line to your `/etc/apt/sources.list` file.
 Add the following line to your `/etc/apt/sources.list` file.
 
 
-    deb https://packagecloud.io/grafana/stable/debian/ wheezy main
+    deb https://packagecloud.io/grafana/stable/debian/ jessie main
 
 
 Use the above line even if you are on Ubuntu or another Debian version.
 Use the above line even if you are on Ubuntu or another Debian version.
 There is also a testing repository if you want beta or release
 There is also a testing repository if you want beta or release
 candidates.
 candidates.
 
 
-    deb https://packagecloud.io/grafana/testing/debian/ wheezy main
+    deb https://packagecloud.io/grafana/testing/debian/ jessie main
 
 
 Then add the [Package Cloud](https://packagecloud.io/grafana) key. This
 Then add the [Package Cloud](https://packagecloud.io/grafana) key. This
 allows you to install signed packages.
 allows you to install signed packages.

+ 20 - 2
docs/sources/installation/rpm.md

@@ -10,9 +10,10 @@ page_keywords: grafana, installation, centos, fedora, opensuse, redhat, guide
 
 
 Description | Download
 Description | Download
 ------------ | -------------
 ------------ | -------------
-Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [grafana-3.0.4-1464167696.x86_64.rpm](https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.4-1464167696.x86_64.rpm)
+Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [3.0.4 (x86-64 rpm)](https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.4-1464167696.x86_64.rpm)
+Beta .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [3.1.0-beta1 (x86-64 rpm)](https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1466666977beta1.x86_64.rpm)
 
 
-## Install Stable Release from package file
+## Install Latest Stable
 
 
 You can install Grafana using Yum directly.
 You can install Grafana using Yum directly.
 
 
@@ -29,6 +30,23 @@ Or install manually using `rpm`.
 
 
     $ sudo rpm -i --nodeps grafana-3.0.4-1464167696.x86_64.rpm
     $ sudo rpm -i --nodeps grafana-3.0.4-1464167696.x86_64.rpm
 
 
+## Install 3.1 Beta
+
+You can install Grafana using Yum directly.
+
+    $ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1466666977beta1.x86_64.rpm
+
+Or install manually using `rpm`.
+
+#### On CentOS / Fedora / Redhat:
+
+    $ sudo yum install initscripts fontconfig
+    $ sudo rpm -Uvh https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1466666977beta1.x86_64.rpm
+
+#### On OpenSuse:
+
+    $ sudo rpm -i --nodeps https://grafanarel.s3.amazonaws.com/builds/grafana-3.1.0-1466666977beta1.x86_64.rpm
+
 ## Install via YUM Repository
 ## Install via YUM Repository
 
 
 Add the following to a new file at `/etc/yum.repos.d/grafana.repo`
 Add the following to a new file at `/etc/yum.repos.d/grafana.repo`

+ 9 - 1
docs/sources/reference/export_import.md

@@ -14,9 +14,17 @@ The export feature is accessed from the share menu.
 
 
 <img src="/img/v31/export_menu.png">
 <img src="/img/v31/export_menu.png">
 
 
+### Making a dashboard portable
+
+If you want to export a dashboard for others to use then it could be a good idea to
+add template variables for things like a metric prefix (use contant variable) and server name.
+
+A template varible of the type `Constant` will automatically be hidden in
+the dashboard, and will also be added as an required input when the dashboard is imported.
+
 ## Importing a dashboard
 ## Importing a dashboard
 
 
-To import a dasbhoard open dashboard search and then hit the import button.
+To import a dashboard open dashboard search and then hit the import button.
 
 
 <img src="/img/v31/import_step1.png">
 <img src="/img/v31/import_step1.png">
 
 

+ 1 - 0
docs/sources/versions.html_fragment

@@ -1,3 +1,4 @@
+<li><a class='version' href='/v3.1'>Version v3.1</a></li>
 <li><a class='version' href='/v3.0'>Version v3.0</a></li>
 <li><a class='version' href='/v3.0'>Version v3.0</a></li>
 <li><a class='version' href='/v2.6'>Version v2.6</a></li>
 <li><a class='version' href='/v2.6'>Version v2.6</a></li>
 <li><a class='version' href='/v2.5'>Version v2.5</a></li>
 <li><a class='version' href='/v2.5'>Version v2.5</a></li>

+ 2 - 2
package.json

@@ -4,7 +4,7 @@
     "company": "Coding Instinct AB"
     "company": "Coding Instinct AB"
   },
   },
   "name": "grafana",
   "name": "grafana",
-  "version": "3.1.0",
+  "version": "3.2.0-pre1",
   "repository": {
   "repository": {
     "type": "git",
     "type": "git",
     "url": "http://github.com/grafana/grafana.git"
     "url": "http://github.com/grafana/grafana.git"
@@ -57,7 +57,7 @@
     "systemjs": "0.19.24"
     "systemjs": "0.19.24"
   },
   },
   "engines": {
   "engines": {
-    "node": "0.4.x",
+    "node": "4.x",
     "npm": "2.14.x"
     "npm": "2.14.x"
   },
   },
   "scripts": {
   "scripts": {

+ 8 - 8
packaging/publish/publish.sh

@@ -1,20 +1,20 @@
 #! /usr/bin/env bash
 #! /usr/bin/env bash
 
 
-deb_ver=3.0.4-1464167696
-rpm_ver=3.0.4-1464167696
+deb_ver=3.1.0-1466666977beta1
+rpm_ver=3.1.0-1466666977beta1
 
 
-wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
+# wget https://grafanarel.s3.amazonaws.com/builds/grafana_${deb_ver}_amd64.deb
 
 
-package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
-package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
+# package_cloud push grafana/stable/debian/jessie grafana_${deb_ver}_amd64.deb
+# package_cloud push grafana/stable/debian/wheezy grafana_${deb_ver}_amd64.deb
 
 
 package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb
 package_cloud push grafana/testing/debian/jessie grafana_${deb_ver}_amd64.deb
 package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb
 package_cloud push grafana/testing/debian/wheezy grafana_${deb_ver}_amd64.deb
 
 
-wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
+# wget https://grafanarel.s3.amazonaws.com/builds/grafana-${rpm_ver}.x86_64.rpm
 
 
 package_cloud push grafana/testing/el/6 grafana-${rpm_ver}.x86_64.rpm
 package_cloud push grafana/testing/el/6 grafana-${rpm_ver}.x86_64.rpm
 package_cloud push grafana/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
 package_cloud push grafana/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
 
 
-package_cloud push grafana/stable/el/7 grafana-${rpm_ver}.x86_64.rpm
-package_cloud push grafana/stable/el/6 grafana-${rpm_ver}.x86_64.rpm
+# package_cloud push grafana/stable/el/7 grafana-${rpm_ver}.x86_64.rpm
+# package_cloud push grafana/stable/el/6 grafana-${rpm_ver}.x86_64.rpm

+ 19 - 15
pkg/api/cloudwatch/metrics.go

@@ -32,8 +32,13 @@ func init() {
 		"AWS/Billing":     {"EstimatedCharges"},
 		"AWS/Billing":     {"EstimatedCharges"},
 		"AWS/CloudFront":  {"Requests", "BytesDownloaded", "BytesUploaded", "TotalErrorRate", "4xxErrorRate", "5xxErrorRate"},
 		"AWS/CloudFront":  {"Requests", "BytesDownloaded", "BytesUploaded", "TotalErrorRate", "4xxErrorRate", "5xxErrorRate"},
 		"AWS/CloudSearch": {"SuccessfulRequests", "SearchableDocuments", "IndexUtilization", "Partitions"},
 		"AWS/CloudSearch": {"SuccessfulRequests", "SearchableDocuments", "IndexUtilization", "Partitions"},
-		"AWS/DynamoDB":    {"ConditionalCheckFailedRequests", "ConsumedReadCapacityUnits", "ConsumedWriteCapacityUnits", "OnlineIndexConsumedWriteCapacity", "OnlineIndexPercentageProgress", "OnlineIndexThrottleEvents", "ProvisionedReadCapacityUnits", "ProvisionedWriteCapacityUnits", "ReadThrottleEvents", "ReturnedItemCount", "SuccessfulRequestLatency", "SystemErrors", "ThrottledRequests", "UserErrors", "WriteThrottleEvents"},
-		"AWS/ECS":         {"CPUUtilization", "MemoryUtilization"},
+		"AWS/DynamoDB":    {"ConditionalCheckFailedRequests", "ConsumedReadCapacityUnits", "ConsumedWriteCapacityUnits", "OnlineIndexConsumedWriteCapacity", "OnlineIndexPercentageProgress", "OnlineIndexThrottleEvents", "ProvisionedReadCapacityUnits", "ProvisionedWriteCapacityUnits", "ReadThrottleEvents", "ReturnedBytes", "ReturnedItemCount", "ReturnedRecordsCount", "SuccessfulRequestLatency", "SystemErrors", "ThrottledRequests", "UserErrors", "WriteThrottleEvents"},
+		"AWS/EBS":         {"VolumeReadBytes", "VolumeWriteBytes", "VolumeReadOps", "VolumeWriteOps", "VolumeTotalReadTime", "VolumeTotalWriteTime", "VolumeIdleTime", "VolumeQueueLength", "VolumeThroughputPercentage", "VolumeConsumedReadWriteOps", "BurstBalance"},
+		"AWS/EC2":         {"CPUCreditUsage", "CPUCreditBalance", "CPUUtilization", "DiskReadOps", "DiskWriteOps", "DiskReadBytes", "DiskWriteBytes", "NetworkIn", "NetworkOut", "NetworkPacketsIn", "NetworkPacketsOut", "StatusCheckFailed", "StatusCheckFailed_Instance", "StatusCheckFailed_System"},
+		"AWS/EC2Spot":     {"AvailableInstancePoolsCount", "BidsSubmittedForCapacity", "EligibleInstancePoolCount", "FulfilledCapacity", "MaxPercentCapacityAllocation", "PendingCapacity", "PercentCapacityAllocation", "TargetCapacity", "TerminatingCapacity"},
+		"AWS/ECS":         {"CPUReservation", "MemoryReservation", "CPUUtilization", "MemoryUtilization"},
+		"AWS/EFS":         {"BurstCreditBalance", "ClientConnections", "DataReadIOBytes", "DataWriteIOBytes", "MetadataIOBytes", "TotalIOBytes", "PermittedThroughput", "PercentIOLimit"},
+		"AWS/ELB":         {"HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount"},
 		"AWS/ElastiCache": {
 		"AWS/ElastiCache": {
 			"CPUUtilization", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut", "SwapUsage",
 			"CPUUtilization", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut", "SwapUsage",
 			"BytesUsedForCacheItems", "BytesReadIntoMemcached", "BytesWrittenOutFromMemcached", "CasBadval", "CasHits", "CasMisses", "CmdFlush", "CmdGet", "CmdSet", "CurrConnections", "CurrItems", "DecrHits", "DecrMisses", "DeleteHits", "DeleteMisses", "Evictions", "GetHits", "GetMisses", "IncrHits", "IncrMisses", "Reclaimed",
 			"BytesUsedForCacheItems", "BytesReadIntoMemcached", "BytesWrittenOutFromMemcached", "CasBadval", "CasHits", "CasMisses", "CmdFlush", "CmdGet", "CmdSet", "CurrConnections", "CurrItems", "DecrHits", "DecrMisses", "DeleteHits", "DeleteMisses", "Evictions", "GetHits", "GetMisses", "IncrHits", "IncrMisses", "Reclaimed",
@@ -42,9 +47,6 @@ func init() {
 			"BytesUsedForCache", "CacheHits", "CacheMisses", "CurrConnections", "Evictions", "HyperLogLogBasedCmds", "NewConnections", "Reclaimed", "ReplicationBytes", "ReplicationLag", "SaveInProgress",
 			"BytesUsedForCache", "CacheHits", "CacheMisses", "CurrConnections", "Evictions", "HyperLogLogBasedCmds", "NewConnections", "Reclaimed", "ReplicationBytes", "ReplicationLag", "SaveInProgress",
 			"CurrItems", "GetTypeCmds", "HashBasedCmds", "KeyBasedCmds", "ListBasedCmds", "SetBasedCmds", "SetTypeCmds", "SortedSetBasedCmds", "StringBasedCmds",
 			"CurrItems", "GetTypeCmds", "HashBasedCmds", "KeyBasedCmds", "ListBasedCmds", "SetBasedCmds", "SetTypeCmds", "SortedSetBasedCmds", "StringBasedCmds",
 		},
 		},
-		"AWS/EBS": {"VolumeReadBytes", "VolumeWriteBytes", "VolumeReadOps", "VolumeWriteOps", "VolumeTotalReadTime", "VolumeTotalWriteTime", "VolumeIdleTime", "VolumeQueueLength", "VolumeThroughputPercentage", "VolumeConsumedReadWriteOps"},
-		"AWS/EC2": {"CPUCreditUsage", "CPUCreditBalance", "CPUUtilization", "DiskReadOps", "DiskWriteOps", "DiskReadBytes", "DiskWriteBytes", "NetworkIn", "NetworkOut", "StatusCheckFailed", "StatusCheckFailed_Instance", "StatusCheckFailed_System"},
-		"AWS/ELB": {"HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount"},
 		"AWS/ElasticBeanstalk": {
 		"AWS/ElasticBeanstalk": {
 			"EnvironmentHealth",
 			"EnvironmentHealth",
 			"ApplicationLatencyP10", "ApplicationLatencyP50", "ApplicationLatencyP75", "ApplicationLatencyP85", "ApplicationLatencyP90", "ApplicationLatencyP95", "ApplicationLatencyP99", "ApplicationLatencyP99.9",
 			"ApplicationLatencyP10", "ApplicationLatencyP50", "ApplicationLatencyP75", "ApplicationLatencyP85", "ApplicationLatencyP90", "ApplicationLatencyP95", "ApplicationLatencyP99", "ApplicationLatencyP99.9",
@@ -73,13 +75,13 @@ func init() {
 		"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
 		"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
 		"AWS/RDS":      {"BinLogDiskUsage", "CPUUtilization", "CPUCreditUsage", "CPUCreditBalance", "DatabaseConnections", "DiskQueueDepth", "FreeableMemory", "FreeStorageSpace", "ReplicaLag", "SwapUsage", "ReadIOPS", "WriteIOPS", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "NetworkReceiveThroughput", "NetworkTransmitThroughput"},
 		"AWS/RDS":      {"BinLogDiskUsage", "CPUUtilization", "CPUCreditUsage", "CPUCreditBalance", "DatabaseConnections", "DiskQueueDepth", "FreeableMemory", "FreeStorageSpace", "ReplicaLag", "SwapUsage", "ReadIOPS", "WriteIOPS", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "NetworkReceiveThroughput", "NetworkTransmitThroughput"},
 		"AWS/Route53":  {"HealthCheckStatus", "HealthCheckPercentageHealthy", "ConnectionTime", "SSLHandshakeTime", "TimeToFirstByte"},
 		"AWS/Route53":  {"HealthCheckStatus", "HealthCheckPercentageHealthy", "ConnectionTime", "SSLHandshakeTime", "TimeToFirstByte"},
+		"AWS/S3":       {"BucketSizeBytes", "NumberOfObjects"},
 		"AWS/SNS":      {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"},
 		"AWS/SNS":      {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"},
 		"AWS/SQS":      {"NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"},
 		"AWS/SQS":      {"NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"},
-		"AWS/S3":       {"BucketSizeBytes", "NumberOfObjects"},
-		"AWS/SWF": {"DecisionTaskScheduleToStartTime", "DecisionTaskStartToCloseTime", "DecisionTasksCompleted", "StartedDecisionTasksTimedOutOnClose", "WorkflowStartToCloseTime", "WorkflowsCanceled", "WorkflowsCompleted", "WorkflowsContinuedAsNew", "WorkflowsFailed", "WorkflowsTerminated", "WorkflowsTimedOut",
-			"ActivityTaskScheduleToCloseTime", "ActivityTaskScheduleToStartTime", "ActivityTaskStartToCloseTime", "ActivityTasksCanceled", "ActivityTasksCompleted", "ActivityTasksFailed", "ScheduledActivityTasksTimedOutOnClose", "ScheduledActivityTasksTimedOutOnStart", "StartedActivityTasksTimedOutOnClose", "StartedActivityTasksTimedOutOnHeartbeat"},
 		"AWS/StorageGateway": {"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "CloudBytesDownloaded", "CloudDownloadLatency", "CloudBytesUploaded", "UploadBufferFree", "UploadBufferPercentUsed", "UploadBufferUsed", "QueuedWrites", "ReadBytes", "ReadTime", "TotalCacheSize", "WriteBytes", "WriteTime", "TimeSinceLastRecoveryPoint", "WorkingStorageFree", "WorkingStoragePercentUsed", "WorkingStorageUsed",
 		"AWS/StorageGateway": {"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "CloudBytesDownloaded", "CloudDownloadLatency", "CloudBytesUploaded", "UploadBufferFree", "UploadBufferPercentUsed", "UploadBufferUsed", "QueuedWrites", "ReadBytes", "ReadTime", "TotalCacheSize", "WriteBytes", "WriteTime", "TimeSinceLastRecoveryPoint", "WorkingStorageFree", "WorkingStoragePercentUsed", "WorkingStorageUsed",
 			"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "ReadBytes", "ReadTime", "WriteBytes", "WriteTime", "QueuedWrites"},
 			"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "ReadBytes", "ReadTime", "WriteBytes", "WriteTime", "QueuedWrites"},
+		"AWS/SWF": {"DecisionTaskScheduleToStartTime", "DecisionTaskStartToCloseTime", "DecisionTasksCompleted", "StartedDecisionTasksTimedOutOnClose", "WorkflowStartToCloseTime", "WorkflowsCanceled", "WorkflowsCompleted", "WorkflowsContinuedAsNew", "WorkflowsFailed", "WorkflowsTerminated", "WorkflowsTimedOut",
+			"ActivityTaskScheduleToCloseTime", "ActivityTaskScheduleToStartTime", "ActivityTaskStartToCloseTime", "ActivityTasksCanceled", "ActivityTasksCompleted", "ActivityTasksFailed", "ScheduledActivityTasksTimedOutOnClose", "ScheduledActivityTasksTimedOutOnStart", "StartedActivityTasksTimedOutOnClose", "StartedActivityTasksTimedOutOnHeartbeat"},
 		"AWS/WAF":        {"AllowedRequests", "BlockedRequests", "CountedRequests"},
 		"AWS/WAF":        {"AllowedRequests", "BlockedRequests", "CountedRequests"},
 		"AWS/WorkSpaces": {"Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"},
 		"AWS/WorkSpaces": {"Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"},
 	}
 	}
@@ -88,29 +90,31 @@ func init() {
 		"AWS/Billing":          {"ServiceName", "LinkedAccount", "Currency"},
 		"AWS/Billing":          {"ServiceName", "LinkedAccount", "Currency"},
 		"AWS/CloudFront":       {"DistributionId", "Region"},
 		"AWS/CloudFront":       {"DistributionId", "Region"},
 		"AWS/CloudSearch":      {},
 		"AWS/CloudSearch":      {},
-		"AWS/DynamoDB":         {"TableName", "GlobalSecondaryIndexName", "Operation"},
-		"AWS/ECS":              {"ClusterName", "ServiceName"},
-		"AWS/ElastiCache":      {"CacheClusterId", "CacheNodeId"},
+		"AWS/DynamoDB":         {"TableName", "GlobalSecondaryIndexName", "Operation", "StreamLabel"},
 		"AWS/EBS":              {"VolumeId"},
 		"AWS/EBS":              {"VolumeId"},
 		"AWS/EC2":              {"AutoScalingGroupName", "ImageId", "InstanceId", "InstanceType"},
 		"AWS/EC2":              {"AutoScalingGroupName", "ImageId", "InstanceId", "InstanceType"},
+		"AWS/EC2Spot":          {"AvailabilityZone", "FleetRequestId", "InstanceType"},
+		"AWS/ECS":              {"ClusterName", "ServiceName"},
+		"AWS/EFS":              {"FileSystemId"},
 		"AWS/ELB":              {"LoadBalancerName", "AvailabilityZone"},
 		"AWS/ELB":              {"LoadBalancerName", "AvailabilityZone"},
+		"AWS/ElastiCache":      {"CacheClusterId", "CacheNodeId"},
 		"AWS/ElasticBeanstalk": {"EnvironmentName", "InstanceId"},
 		"AWS/ElasticBeanstalk": {"EnvironmentName", "InstanceId"},
 		"AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"},
 		"AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"},
 		"AWS/ES":               {"ClientId", "DomainName"},
 		"AWS/ES":               {"ClientId", "DomainName"},
 		"AWS/Events":           {"RuleName"},
 		"AWS/Events":           {"RuleName"},
 		"AWS/Kinesis":          {"StreamName", "ShardID"},
 		"AWS/Kinesis":          {"StreamName", "ShardID"},
-		"AWS/Lambda":           {"FunctionName"},
+		"AWS/Lambda":           {"FunctionName", "Resource", "Version", "Alias"},
 		"AWS/Logs":             {"LogGroupName", "DestinationType", "FilterName"},
 		"AWS/Logs":             {"LogGroupName", "DestinationType", "FilterName"},
 		"AWS/ML":               {"MLModelId", "RequestMode"},
 		"AWS/ML":               {"MLModelId", "RequestMode"},
 		"AWS/OpsWorks":         {"StackId", "LayerId", "InstanceId"},
 		"AWS/OpsWorks":         {"StackId", "LayerId", "InstanceId"},
 		"AWS/Redshift":         {"NodeID", "ClusterIdentifier"},
 		"AWS/Redshift":         {"NodeID", "ClusterIdentifier"},
-		"AWS/RDS":              {"DBInstanceIdentifier", "DatabaseClass", "EngineName"},
+		"AWS/RDS":              {"DBInstanceIdentifier", "DBClusterIdentifier", "DatabaseClass", "EngineName"},
 		"AWS/Route53":          {"HealthCheckId"},
 		"AWS/Route53":          {"HealthCheckId"},
+		"AWS/S3":               {"BucketName", "StorageType"},
 		"AWS/SNS":              {"Application", "Platform", "TopicName"},
 		"AWS/SNS":              {"Application", "Platform", "TopicName"},
 		"AWS/SQS":              {"QueueName"},
 		"AWS/SQS":              {"QueueName"},
-		"AWS/S3":               {"BucketName", "StorageType"},
-		"AWS/SWF":              {"Domain", "WorkflowTypeName", "WorkflowTypeVersion", "ActivityTypeName", "ActivityTypeVersion"},
 		"AWS/StorageGateway":   {"GatewayId", "GatewayName", "VolumeId"},
 		"AWS/StorageGateway":   {"GatewayId", "GatewayName", "VolumeId"},
+		"AWS/SWF":              {"Domain", "WorkflowTypeName", "WorkflowTypeVersion", "ActivityTypeName", "ActivityTypeVersion"},
 		"AWS/WAF":              {"Rule", "WebACL"},
 		"AWS/WAF":              {"Rule", "WebACL"},
 		"AWS/WorkSpaces":       {"DirectoryId", "WorkspaceId"},
 		"AWS/WorkSpaces":       {"DirectoryId", "WorkspaceId"},
 	}
 	}

+ 1 - 0
pkg/api/login.go

@@ -29,6 +29,7 @@ func LoginView(c *middleware.Context) {
 	viewData.Settings["githubAuthEnabled"] = setting.OAuthService.GitHub
 	viewData.Settings["githubAuthEnabled"] = setting.OAuthService.GitHub
 	viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp
 	viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp
 	viewData.Settings["loginHint"] = setting.LoginHint
 	viewData.Settings["loginHint"] = setting.LoginHint
+	viewData.Settings["allowUserPassLogin"] = setting.AllowUserPassLogin
 
 
 	if !tryLoginUsingRememberCookie(c) {
 	if !tryLoginUsingRememberCookie(c) {
 		c.HTML(200, VIEW_INDEX, viewData)
 		c.HTML(200, VIEW_INDEX, viewData)

+ 11 - 0
pkg/cmd/grafana-cli/commands/command_line.go

@@ -16,6 +16,9 @@ type CommandLine interface {
 	GlobalString(name string) string
 	GlobalString(name string) string
 	FlagNames() (names []string)
 	FlagNames() (names []string)
 	Generic(name string) interface{}
 	Generic(name string) interface{}
+
+	PluginDirectory() string
+	RepoDirectory() string
 }
 }
 
 
 type contextCommandLine struct {
 type contextCommandLine struct {
@@ -33,3 +36,11 @@ func (c *contextCommandLine) ShowVersion() {
 func (c *contextCommandLine) Application() *cli.App {
 func (c *contextCommandLine) Application() *cli.App {
 	return c.App
 	return c.App
 }
 }
+
+func (c *contextCommandLine) PluginDirectory() string {
+	return c.GlobalString("pluginsDir")
+}
+
+func (c *contextCommandLine) RepoDirectory() string {
+	return c.GlobalString("repo")
+}

+ 8 - 0
pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go

@@ -93,3 +93,11 @@ func (fcli *FakeCommandLine) Args() cli.Args {
 func (fcli *FakeCommandLine) ShowVersion() {
 func (fcli *FakeCommandLine) ShowVersion() {
 	fcli.VersionShown = true
 	fcli.VersionShown = true
 }
 }
+
+func (fcli *FakeCommandLine) RepoDirectory() string {
+	return fcli.GlobalString("repo")
+}
+
+func (fcli *FakeCommandLine) PluginDirectory() string {
+	return fcli.GlobalString("pluginsDir")
+}

+ 4 - 4
pkg/cmd/grafana-cli/commands/install_command.go

@@ -25,7 +25,7 @@ func validateInput(c CommandLine, pluginFolder string) error {
 		return errors.New("please specify plugin to install")
 		return errors.New("please specify plugin to install")
 	}
 	}
 
 
-	pluginsDir := c.GlobalString("pluginsDir")
+	pluginsDir := c.PluginDirectory()
 	if pluginsDir == "" {
 	if pluginsDir == "" {
 		return errors.New("missing pluginsDir flag")
 		return errors.New("missing pluginsDir flag")
 	}
 	}
@@ -46,7 +46,7 @@ func validateInput(c CommandLine, pluginFolder string) error {
 }
 }
 
 
 func installCommand(c CommandLine) error {
 func installCommand(c CommandLine) error {
-	pluginFolder := c.GlobalString("pluginsDir")
+	pluginFolder := c.PluginDirectory()
 	if err := validateInput(c, pluginFolder); err != nil {
 	if err := validateInput(c, pluginFolder); err != nil {
 		return err
 		return err
 	}
 	}
@@ -58,8 +58,8 @@ func installCommand(c CommandLine) error {
 }
 }
 
 
 func InstallPlugin(pluginName, version string, c CommandLine) error {
 func InstallPlugin(pluginName, version string, c CommandLine) error {
-	plugin, err := s.GetPlugin(pluginName, c.GlobalString("repo"))
-	pluginFolder := c.GlobalString("pluginsDir")
+	plugin, err := s.GetPlugin(pluginName, c.RepoDirectory())
+	pluginFolder := c.PluginDirectory()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 1 - 1
pkg/cmd/grafana-cli/commands/listremote_command.go

@@ -6,7 +6,7 @@ import (
 )
 )
 
 
 func listremoteCommand(c CommandLine) error {
 func listremoteCommand(c CommandLine) error {
-	plugin, err := s.ListAllPlugins(c.GlobalString("repo"))
+	plugin, err := s.ListAllPlugins(c.RepoDirectory())
 
 
 	if err != nil {
 	if err != nil {
 		return err
 		return err

+ 1 - 1
pkg/cmd/grafana-cli/commands/ls_command.go

@@ -32,7 +32,7 @@ var validateLsCommand = func(pluginDir string) error {
 }
 }
 
 
 func lsCommand(c CommandLine) error {
 func lsCommand(c CommandLine) error {
-	pluginDir := c.GlobalString("pluginsDir")
+	pluginDir := c.PluginDirectory()
 	if err := validateLsCommand(pluginDir); err != nil {
 	if err := validateLsCommand(pluginDir); err != nil {
 		return err
 		return err
 	}
 	}

+ 10 - 8
pkg/cmd/grafana-cli/commands/remove_command.go

@@ -2,30 +2,32 @@ package commands
 
 
 import (
 import (
 	"errors"
 	"errors"
-
 	"fmt"
 	"fmt"
 	m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
 	m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models"
 	services "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
 	services "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
+	"strings"
 )
 )
 
 
 var getPluginss func(path string) []m.InstalledPlugin = services.GetLocalPlugins
 var getPluginss func(path string) []m.InstalledPlugin = services.GetLocalPlugins
 var removePlugin func(pluginPath, id string) error = services.RemoveInstalledPlugin
 var removePlugin func(pluginPath, id string) error = services.RemoveInstalledPlugin
 
 
 func removeCommand(c CommandLine) error {
 func removeCommand(c CommandLine) error {
-	pluginPath := c.GlobalString("pluginsDir")
-	localPlugins := getPluginss(pluginPath)
+	pluginPath := c.PluginDirectory()
 
 
 	plugin := c.Args().First()
 	plugin := c.Args().First()
 	if plugin == "" {
 	if plugin == "" {
 		return errors.New("Missing plugin parameter")
 		return errors.New("Missing plugin parameter")
 	}
 	}
 
 
-	for _, p := range localPlugins {
-		if p.Id == c.Args().First() {
-			removePlugin(pluginPath, p.Id)
-			return nil
+	err := removePlugin(pluginPath, plugin)
+
+	if err != nil {
+		if strings.Contains(err.Error(), "no such file or directory") {
+			return fmt.Errorf("Plugin does not exist")
 		}
 		}
+
+		return err
 	}
 	}
 
 
-	return fmt.Errorf("Could not find plugin named %s", c.Args().First())
+	return nil
 }
 }

+ 1 - 1
pkg/cmd/grafana-cli/commands/upgrade_all_command.go

@@ -28,7 +28,7 @@ func ShouldUpgrade(installed string, remote m.Plugin) bool {
 }
 }
 
 
 func upgradeAllCommand(c CommandLine) error {
 func upgradeAllCommand(c CommandLine) error {
-	pluginsDir := c.GlobalString("pluginsDir")
+	pluginsDir := c.PluginDirectory()
 
 
 	localPlugins := s.GetLocalPlugins(pluginsDir)
 	localPlugins := s.GetLocalPlugins(pluginsDir)
 
 

+ 2 - 2
pkg/cmd/grafana-cli/commands/upgrade_command.go

@@ -7,7 +7,7 @@ import (
 )
 )
 
 
 func upgradeCommand(c CommandLine) error {
 func upgradeCommand(c CommandLine) error {
-	pluginsDir := c.GlobalString("pluginsDir")
+	pluginsDir := c.PluginDirectory()
 	pluginName := c.Args().First()
 	pluginName := c.Args().First()
 
 
 	localPlugin, err := s.ReadPlugin(pluginsDir, pluginName)
 	localPlugin, err := s.ReadPlugin(pluginsDir, pluginName)
@@ -16,7 +16,7 @@ func upgradeCommand(c CommandLine) error {
 		return err
 		return err
 	}
 	}
 
 
-	v, err2 := s.GetPlugin(localPlugin.Id, c.GlobalString("repo"))
+	v, err2 := s.GetPlugin(localPlugin.Id, c.RepoDirectory())
 
 
 	if err2 != nil {
 	if err2 != nil {
 		return err2
 		return err2

+ 10 - 3
pkg/cmd/grafana-cli/services/services.go

@@ -75,9 +75,16 @@ func GetLocalPlugins(pluginDir string) []m.InstalledPlugin {
 	return result
 	return result
 }
 }
 
 
-func RemoveInstalledPlugin(pluginPath, id string) error {
-	logger.Infof("Removing plugin: %v\n", id)
-	return IoHelper.RemoveAll(path.Join(pluginPath, id))
+func RemoveInstalledPlugin(pluginPath, pluginName string) error {
+	logger.Infof("Removing plugin: %v\n", pluginName)
+	pluginDir := path.Join(pluginPath, pluginName)
+
+	_, err := IoHelper.Stat(pluginDir)
+	if err != nil {
+		return err
+	}
+
+	return IoHelper.RemoveAll(pluginDir)
 }
 }
 
 
 func GetPlugin(pluginId, repoUrl string) (m.Plugin, error) {
 func GetPlugin(pluginId, repoUrl string) (m.Plugin, error) {

+ 0 - 2
pkg/middleware/middleware_test.go

@@ -191,9 +191,7 @@ func TestMiddlewareContext(t *testing.T) {
 				}
 				}
 			})
 			})
 
 
-			var createUserCmd *m.CreateUserCommand
 			bus.AddHandler("test", func(cmd *m.CreateUserCommand) error {
 			bus.AddHandler("test", func(cmd *m.CreateUserCommand) error {
-				createUserCmd = cmd
 				cmd.Result = m.User{Id: 33}
 				cmd.Result = m.User{Id: 33}
 				return nil
 				return nil
 			})
 			})

+ 2 - 0
pkg/setting/setting.go

@@ -89,6 +89,7 @@ var (
 	VerifyEmailEnabled bool
 	VerifyEmailEnabled bool
 	LoginHint          string
 	LoginHint          string
 	DefaultTheme       string
 	DefaultTheme       string
+	AllowUserPassLogin bool
 
 
 	// Http auth
 	// Http auth
 	AdminUser     string
 	AdminUser     string
@@ -485,6 +486,7 @@ func NewConfigContext(args *CommandLineArgs) error {
 	VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false)
 	VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false)
 	LoginHint = users.Key("login_hint").String()
 	LoginHint = users.Key("login_hint").String()
 	DefaultTheme = users.Key("default_theme").String()
 	DefaultTheme = users.Key("default_theme").String()
+	AllowUserPassLogin = users.Key("allow_user_pass_login").MustBool(true)
 
 
 	// anonymous access
 	// anonymous access
 	AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false)
 	AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false)

+ 1 - 0
public/app/core/controllers/login_ctrl.js

@@ -18,6 +18,7 @@ function (angular, coreModule, config) {
     $scope.googleAuthEnabled = config.googleAuthEnabled;
     $scope.googleAuthEnabled = config.googleAuthEnabled;
     $scope.githubAuthEnabled = config.githubAuthEnabled;
     $scope.githubAuthEnabled = config.githubAuthEnabled;
     $scope.oauthEnabled = config.githubAuthEnabled || config.googleAuthEnabled;
     $scope.oauthEnabled = config.githubAuthEnabled || config.googleAuthEnabled;
+    $scope.allowUserPassLogin = config.allowUserPassLogin;
     $scope.disableUserSignUp = config.disableUserSignUp;
     $scope.disableUserSignUp = config.disableUserSignUp;
     $scope.loginHint     = config.loginHint;
     $scope.loginHint     = config.loginHint;
 
 

+ 0 - 4
public/app/core/services/alert_srv.ts

@@ -28,10 +28,6 @@ export class AlertSrv {
     }, this.$rootScope);
     }, this.$rootScope);
 
 
     appEvents.on('confirm-modal', this.showConfirmModal.bind(this));
     appEvents.on('confirm-modal', this.showConfirmModal.bind(this));
-
-    this.$rootScope.onAppEvent('confirm-modal', (e, data) => {
-      this.showConfirmModal(data);
-    }, this.$rootScope);
   }
   }
 
 
   set(title, text, severity, timeout) {
   set(title, text, severity, timeout) {

+ 1 - 1
public/app/core/services/backend_srv.ts

@@ -87,7 +87,7 @@ export class BackendSrv {
         });
         });
       }
       }
 
 
-      this.$timeout(this.requestErrorHandler.bind(this), 50);
+      this.$timeout(this.requestErrorHandler.bind(this, err), 50);
       throw err;
       throw err;
     });
     });
   };
   };

+ 6 - 0
public/app/core/utils/kbn.js

@@ -397,6 +397,9 @@ function($, _, moment) {
   kbn.valueFormats.rps  = kbn.formatBuilders.simpleCountUnit('rps');
   kbn.valueFormats.rps  = kbn.formatBuilders.simpleCountUnit('rps');
   kbn.valueFormats.wps  = kbn.formatBuilders.simpleCountUnit('wps');
   kbn.valueFormats.wps  = kbn.formatBuilders.simpleCountUnit('wps');
   kbn.valueFormats.iops = kbn.formatBuilders.simpleCountUnit('iops');
   kbn.valueFormats.iops = kbn.formatBuilders.simpleCountUnit('iops');
+  kbn.valueFormats.opm = kbn.formatBuilders.simpleCountUnit('opm');
+  kbn.valueFormats.rpm = kbn.formatBuilders.simpleCountUnit('rpm');
+  kbn.valueFormats.wpm = kbn.formatBuilders.simpleCountUnit('wpm');
 
 
   // Energy
   // Energy
   kbn.valueFormats.watt         = kbn.formatBuilders.decimalSIPrefix('W');
   kbn.valueFormats.watt         = kbn.formatBuilders.decimalSIPrefix('W');
@@ -664,6 +667,9 @@ function($, _, moment) {
           {text: 'reads/sec (rps)',     value: 'rps' },
           {text: 'reads/sec (rps)',     value: 'rps' },
           {text: 'writes/sec (wps)',    value: 'wps' },
           {text: 'writes/sec (wps)',    value: 'wps' },
           {text: 'I/O ops/sec (iops)',  value: 'iops'},
           {text: 'I/O ops/sec (iops)',  value: 'iops'},
+          {text: 'ops/min (opm)',       value: 'opm' },
+          {text: 'reads/min (rpm)',     value: 'rpm' },
+          {text: 'writes/min (wpm)',    value: 'wpm' },
         ]
         ]
       },
       },
       {
       {

+ 4 - 4
public/app/partials/login.html

@@ -17,7 +17,7 @@
 				</button>
 				</button>
 			</div>
 			</div>
 
 
-      <form name="loginForm" class="login-form gf-form-group">
+      <form name="loginForm" class="login-form gf-form-group" ng-show="allowUserPassLogin">
 				<div class="gf-form" ng-if="loginMode">
 				<div class="gf-form" ng-if="loginMode">
 					<span class="gf-form-label width-7">User</span>
 					<span class="gf-form-label width-7">User</span>
 					<input type="text" name="username" class="gf-form-input max-width-14" required ng-model='formModel.user' placeholder={{loginHint}}>
 					<input type="text" name="username" class="gf-form-input max-width-14" required ng-model='formModel.user' placeholder={{loginHint}}>
@@ -40,7 +40,7 @@
 			</form>
 			</form>
 
 
 			<div ng-if="loginMode">
 			<div ng-if="loginMode">
-				<div class="text-center login-divider" ng-if="oauthEnabled">
+				<div class="text-center login-divider" ng-show="oauthEnabled && allowUserPassLogin">
 					<div class="login-divider-line">
 					<div class="login-divider-line">
 						<span class="login-divider-text">
 						<span class="login-divider-text">
 							Or login with
 							Or login with
@@ -50,7 +50,7 @@
 
 
 				<div class="clearfix"></div>
 				<div class="clearfix"></div>
 
 
-				<div class="login-oauth text-center" ng-if="oauthEnabled">
+				<div class="login-oauth text-center" ng-show="oauthEnabled">
 					<a class="btn btn-large btn-google" href="login/google" target="_self" ng-if="googleAuthEnabled">
 					<a class="btn btn-large btn-google" href="login/google" target="_self" ng-if="googleAuthEnabled">
 						<i class="fa fa-google"></i>
 						<i class="fa fa-google"></i>
 						with Google
 						with Google
@@ -64,7 +64,7 @@
 
 
 			<div class="clearfix"></div>
 			<div class="clearfix"></div>
 
 
-			<div class="text-center password-recovery">
+			<div class="text-center password-recovery" ng-show="allowUserPassLogin">
 				<div class="text-center">
 				<div class="text-center">
 					<a href="user/password/send-reset-email">
 					<a href="user/password/send-reset-email">
 						Forgot your password?
 						Forgot your password?

+ 1 - 1
public/app/plugins/datasource/prometheus/datasource.ts

@@ -77,7 +77,7 @@ export function PrometheusDatasource(instanceSettings, $q, backendSrv, templateS
 
 
       var query: any = {};
       var query: any = {};
       query.expr = templateSrv.replace(target.expr, options.scopedVars, self.interpolateQueryExpr);
       query.expr = templateSrv.replace(target.expr, options.scopedVars, self.interpolateQueryExpr);
-      query.requestId = target.expr;
+      query.requestId = options.panelId + target.refId;
 
 
       var interval = target.interval || options.interval;
       var interval = target.interval || options.interval;
       var intervalFactor = target.intervalFactor || 1;
       var intervalFactor = target.intervalFactor || 1;

+ 1 - 1
public/app/plugins/panel/graph/series_overrides_ctrl.js

@@ -105,7 +105,7 @@ define([
     $scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']);
     $scope.addOverrideOption('Stack', 'stack', [true, false, 'A', 'B', 'C', 'D']);
     $scope.addOverrideOption('Color', 'color', ['change']);
     $scope.addOverrideOption('Color', 'color', ['change']);
     $scope.addOverrideOption('Y-axis', 'yaxis', [1, 2]);
     $scope.addOverrideOption('Y-axis', 'yaxis', [1, 2]);
-    $scope.addOverrideOption('Z-index', 'zindex', [-1,-2,-3,0,1,2,3]);
+    $scope.addOverrideOption('Z-index', 'zindex', [-3,-2,-1,0,1,2,3]);
     $scope.addOverrideOption('Transform', 'transform', ['negative-Y']);
     $scope.addOverrideOption('Transform', 'transform', ['negative-Y']);
     $scope.addOverrideOption('Legend', 'legend', [true, false]);
     $scope.addOverrideOption('Legend', 'legend', [true, false]);
     $scope.updateCurrentOverrides();
     $scope.updateCurrentOverrides();

+ 4 - 1
public/app/plugins/panel/singlestat/editor.html

@@ -16,7 +16,10 @@
 					Value
 					Value
 				</li>
 				</li>
 				<li>
 				<li>
-					<select class="input-small tight-form-input" ng-model="ctrl.panel.valueName" ng-options="f for f in ['min','max','avg', 'current', 'total']" ng-change="ctrl.render()"></select>
+					<select class="input-small tight-form-input"
+            ng-model="ctrl.panel.valueName"
+            ng-options="f for f in ctrl.valueNameOptions"
+            ng-change="ctrl.render()"></select>
 				</li>
 				</li>
 				<li class="tight-form-item">
 				<li class="tight-form-item">
 					Postfix
 					Postfix

+ 18 - 4
public/app/plugins/panel/singlestat/module.ts

@@ -19,6 +19,9 @@ class SingleStatCtrl extends MetricsPanelCtrl {
   fontSizes: any[];
   fontSizes: any[];
   unitFormats: any[];
   unitFormats: any[];
   invalidGaugeRange: boolean;
   invalidGaugeRange: boolean;
+  panel: any;
+  events: any;
+  valueNameOptions: any[] = ['min','max','avg', 'current', 'total', 'name'];
 
 
   // Set and populate defaults
   // Set and populate defaults
   panelDefaults = {
   panelDefaults = {
@@ -186,9 +189,13 @@ class SingleStatCtrl extends MetricsPanelCtrl {
       var lastPoint = _.last(this.series[0].datapoints);
       var lastPoint = _.last(this.series[0].datapoints);
       var lastValue = _.isArray(lastPoint) ? lastPoint[0] : null;
       var lastValue = _.isArray(lastPoint) ? lastPoint[0] : null;
 
 
-      if (_.isString(lastValue)) {
+      if (this.panel.valueName === 'name') {
         data.value = 0;
         data.value = 0;
-        data.valueFormated = lastValue;
+        data.valueRounded = 0;
+        data.valueFormated = this.series[0].alias;
+      } else if (_.isString(lastValue)) {
+        data.value = 0;
+        data.valueFormated = _.escape(lastValue);
         data.valueRounded = 0;
         data.valueRounded = 0;
       } else {
       } else {
         data.value = this.series[0].stats[this.panel.valueName];
         data.value = this.series[0].stats[this.panel.valueName];
@@ -199,6 +206,13 @@ class SingleStatCtrl extends MetricsPanelCtrl {
         data.valueFormated = formatFunc(data.value, decimalInfo.decimals, decimalInfo.scaledDecimals);
         data.valueFormated = formatFunc(data.value, decimalInfo.decimals, decimalInfo.scaledDecimals);
         data.valueRounded = kbn.roundValue(data.value, decimalInfo.decimals);
         data.valueRounded = kbn.roundValue(data.value, decimalInfo.decimals);
       }
       }
+
+      // Add $__name variable for using in prefix or postfix
+      data.scopedVars = {
+        __name: {
+          value: this.series[0].label
+        }
+      };
     }
     }
 
 
     // check value to text mappings if its enabled
     // check value to text mappings if its enabled
@@ -296,7 +310,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     }
     }
 
 
     function getSpan(className, fontSize, value)  {
     function getSpan(className, fontSize, value)  {
-      value = templateSrv.replace(value);
+      value = templateSrv.replace(value, data.scopedVars);
       return '<span class="' + className + '" style="font-size:' + fontSize + '">' +
       return '<span class="' + className + '" style="font-size:' + fontSize + '">' +
         value + '</span>';
         value + '</span>';
     }
     }
@@ -395,7 +409,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
             value: {
             value: {
               color: panel.colorValue ? getColorForValue(data, data.valueRounded) : null,
               color: panel.colorValue ? getColorForValue(data, data.valueRounded) : null,
               formatter: function() { return getValueText(); },
               formatter: function() { return getValueText(); },
-              font: { size: fontSize, family: 'Helvetica Neue", Helvetica, Arial, sans-serif' }
+              font: { size: fontSize, family: '"Helvetica Neue", Helvetica, Arial, sans-serif' }
             },
             },
             show: true
             show: true
           }
           }

+ 16 - 0
public/app/plugins/panel/singlestat/specs/singlestat-specs.ts

@@ -51,6 +51,22 @@ describe('SingleStatCtrl', function() {
     });
     });
   });
   });
 
 
+  singleStatScenario('showing serie name instead of value', function(ctx) {
+    ctx.setup(function() {
+      ctx.datapoints = [[10,1], [20,2]];
+      ctx.ctrl.panel.valueName = 'name';
+    });
+
+    it('Should use series avg as default main value', function() {
+      expect(ctx.data.value).to.be(0);
+      expect(ctx.data.valueRounded).to.be(0);
+    });
+
+    it('should set formated falue', function() {
+      expect(ctx.data.valueFormated).to.be('test.cpu1');
+    });
+  });
+
   singleStatScenario('MainValue should use same number for decimals as displayed when checking thresholds', function(ctx) {
   singleStatScenario('MainValue should use same number for decimals as displayed when checking thresholds', function(ctx) {
     ctx.setup(function() {
     ctx.setup(function() {
       ctx.datapoints = [[99.999,1], [99.99999,2]];
       ctx.datapoints = [[99.999,1], [99.99999,2]];

+ 7 - 0
public/sass/_old_responsive.scss

@@ -5,6 +5,7 @@
 
 
 // Media queries
 // Media queries
 // ---------------------
 // ---------------------
+
 @include media-breakpoint-down(sm) {
 @include media-breakpoint-down(sm) {
   div.panel {
   div.panel {
     width: 100% !important;
     width: 100% !important;
@@ -33,6 +34,12 @@
   }
   }
 }
 }
 
 
+@include media-breakpoint-down(xs) {
+  .page-dashboard .navbar-page-btn {
+    max-width: 150px;
+  }
+}
+
 // form styles
 // form styles
 @include media-breakpoint-up(md) {
 @include media-breakpoint-up(md) {
   .page-dashboard .navbar-page-btn {
   .page-dashboard .navbar-page-btn {

+ 5 - 0
public/sass/components/_gf-form.scss

@@ -102,6 +102,11 @@ $gf-form-margin: 0.25rem;
     display: none;
     display: none;
   }
   }
 
 
+  &.gf-input-small {
+    padding: $input-padding-y/3 $input-padding-x/3;
+    font-size: $font-size-xs;
+  }
+
   // Customize the `:focus` state to imitate native WebKit styles.
   // Customize the `:focus` state to imitate native WebKit styles.
   @include form-control-focus();
   @include form-control-focus();