diff --git a/CHANGELOG.md b/CHANGELOG.md index eaff2e0bbc8..e72d9f6d2f7 100644 --- a/CHANGELOG.md +++ b/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 * **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) * **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) -* **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) * **Datasource**: Pending data source requests are cancelled before new ones are issues (Graphite & Prometheus), closes [#5321](https://github.com/grafana/grafana/issues/5321) diff --git a/conf/defaults.ini b/conf/defaults.ini index c087fcf1ab1..5233fe89722 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -178,6 +178,9 @@ login_hint = email or username # Default UI theme ("dark" or "light") default_theme = dark +# Allow users to sign in using username and password +allow_user_pass_login = true + #################################### Anonymous Auth ########################## [auth.anonymous] # enable anonymous access diff --git a/docs/VERSION b/docs/VERSION index 4a36342fcab..fd2a01863fd 100644 --- a/docs/VERSION +++ b/docs/VERSION @@ -1 +1 @@ -3.0.0 +3.1.0 diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md index 6084b9b317d..92f11764aa4 100644 --- a/docs/sources/installation/debian.md +++ b/docs/sources/installation/debian.md @@ -10,7 +10,8 @@ page_keywords: grafana, installation, debian, ubuntu, guide 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 @@ -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 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 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. There is also a testing repository if you want beta or release 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 allows you to install signed packages. diff --git a/docs/sources/installation/rpm.md b/docs/sources/installation/rpm.md index 854ba91fcf7..0e423eb0af4 100644 --- a/docs/sources/installation/rpm.md +++ b/docs/sources/installation/rpm.md @@ -10,9 +10,10 @@ page_keywords: grafana, installation, centos, fedora, opensuse, redhat, guide 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. @@ -29,6 +30,23 @@ Or install manually using `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 Add the following to a new file at `/etc/yum.repos.d/grafana.repo` diff --git a/docs/sources/reference/export_import.md b/docs/sources/reference/export_import.md index 57a80a0b88a..0e830db959f 100644 --- a/docs/sources/reference/export_import.md +++ b/docs/sources/reference/export_import.md @@ -14,9 +14,17 @@ The export feature is accessed from the share menu. +### 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 -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. diff --git a/docs/sources/versions.html_fragment b/docs/sources/versions.html_fragment index 0d62ee1e461..df6dbd4db7f 100644 --- a/docs/sources/versions.html_fragment +++ b/docs/sources/versions.html_fragment @@ -1,3 +1,4 @@ +
  • Version v3.1
  • Version v3.0
  • Version v2.6
  • Version v2.5
  • diff --git a/package.json b/package.json index 9094cdf9172..94048488c3b 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "company": "Coding Instinct AB" }, "name": "grafana", - "version": "3.1.0", + "version": "3.2.0-pre1", "repository": { "type": "git", "url": "http://github.com/grafana/grafana.git" @@ -57,7 +57,7 @@ "systemjs": "0.19.24" }, "engines": { - "node": "0.4.x", + "node": "4.x", "npm": "2.14.x" }, "scripts": { diff --git a/packaging/publish/publish.sh b/packaging/publish/publish.sh index 892bfc178cc..2ab50095695 100755 --- a/packaging/publish/publish.sh +++ b/packaging/publish/publish.sh @@ -1,20 +1,20 @@ #! /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/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/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 diff --git a/pkg/api/cloudwatch/metrics.go b/pkg/api/cloudwatch/metrics.go index 54e60b781cb..3cf6ecd787b 100644 --- a/pkg/api/cloudwatch/metrics.go +++ b/pkg/api/cloudwatch/metrics.go @@ -32,8 +32,13 @@ func init() { "AWS/Billing": {"EstimatedCharges"}, "AWS/CloudFront": {"Requests", "BytesDownloaded", "BytesUploaded", "TotalErrorRate", "4xxErrorRate", "5xxErrorRate"}, "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": { "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", @@ -42,9 +47,6 @@ func init() { "BytesUsedForCache", "CacheHits", "CacheMisses", "CurrConnections", "Evictions", "HyperLogLogBasedCmds", "NewConnections", "Reclaimed", "ReplicationBytes", "ReplicationLag", "SaveInProgress", "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": { "EnvironmentHealth", "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/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/S3": {"BucketSizeBytes", "NumberOfObjects"}, "AWS/SNS": {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"}, "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", "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/WorkSpaces": {"Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"}, } @@ -88,29 +90,31 @@ func init() { "AWS/Billing": {"ServiceName", "LinkedAccount", "Currency"}, "AWS/CloudFront": {"DistributionId", "Region"}, "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/EC2": {"AutoScalingGroupName", "ImageId", "InstanceId", "InstanceType"}, + "AWS/EC2Spot": {"AvailabilityZone", "FleetRequestId", "InstanceType"}, + "AWS/ECS": {"ClusterName", "ServiceName"}, + "AWS/EFS": {"FileSystemId"}, "AWS/ELB": {"LoadBalancerName", "AvailabilityZone"}, + "AWS/ElastiCache": {"CacheClusterId", "CacheNodeId"}, "AWS/ElasticBeanstalk": {"EnvironmentName", "InstanceId"}, "AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"}, "AWS/ES": {"ClientId", "DomainName"}, "AWS/Events": {"RuleName"}, "AWS/Kinesis": {"StreamName", "ShardID"}, - "AWS/Lambda": {"FunctionName"}, + "AWS/Lambda": {"FunctionName", "Resource", "Version", "Alias"}, "AWS/Logs": {"LogGroupName", "DestinationType", "FilterName"}, "AWS/ML": {"MLModelId", "RequestMode"}, "AWS/OpsWorks": {"StackId", "LayerId", "InstanceId"}, "AWS/Redshift": {"NodeID", "ClusterIdentifier"}, - "AWS/RDS": {"DBInstanceIdentifier", "DatabaseClass", "EngineName"}, + "AWS/RDS": {"DBInstanceIdentifier", "DBClusterIdentifier", "DatabaseClass", "EngineName"}, "AWS/Route53": {"HealthCheckId"}, + "AWS/S3": {"BucketName", "StorageType"}, "AWS/SNS": {"Application", "Platform", "TopicName"}, "AWS/SQS": {"QueueName"}, - "AWS/S3": {"BucketName", "StorageType"}, - "AWS/SWF": {"Domain", "WorkflowTypeName", "WorkflowTypeVersion", "ActivityTypeName", "ActivityTypeVersion"}, "AWS/StorageGateway": {"GatewayId", "GatewayName", "VolumeId"}, + "AWS/SWF": {"Domain", "WorkflowTypeName", "WorkflowTypeVersion", "ActivityTypeName", "ActivityTypeVersion"}, "AWS/WAF": {"Rule", "WebACL"}, "AWS/WorkSpaces": {"DirectoryId", "WorkspaceId"}, } diff --git a/pkg/api/login.go b/pkg/api/login.go index 463fa8282a5..4f976f753a2 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -29,6 +29,7 @@ func LoginView(c *middleware.Context) { viewData.Settings["githubAuthEnabled"] = setting.OAuthService.GitHub viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp viewData.Settings["loginHint"] = setting.LoginHint + viewData.Settings["allowUserPassLogin"] = setting.AllowUserPassLogin if !tryLoginUsingRememberCookie(c) { c.HTML(200, VIEW_INDEX, viewData) diff --git a/pkg/cmd/grafana-cli/commands/command_line.go b/pkg/cmd/grafana-cli/commands/command_line.go index edbdc03d7c2..ce5d04c1bb5 100644 --- a/pkg/cmd/grafana-cli/commands/command_line.go +++ b/pkg/cmd/grafana-cli/commands/command_line.go @@ -16,6 +16,9 @@ type CommandLine interface { GlobalString(name string) string FlagNames() (names []string) Generic(name string) interface{} + + PluginDirectory() string + RepoDirectory() string } type contextCommandLine struct { @@ -33,3 +36,11 @@ func (c *contextCommandLine) ShowVersion() { func (c *contextCommandLine) Application() *cli.App { return c.App } + +func (c *contextCommandLine) PluginDirectory() string { + return c.GlobalString("pluginsDir") +} + +func (c *contextCommandLine) RepoDirectory() string { + return c.GlobalString("repo") +} diff --git a/pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go b/pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go index 4a070b5a192..8366e0feb15 100644 --- a/pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go +++ b/pkg/cmd/grafana-cli/commands/commandstest/fake_commandLine.go @@ -93,3 +93,11 @@ func (fcli *FakeCommandLine) Args() cli.Args { func (fcli *FakeCommandLine) ShowVersion() { fcli.VersionShown = true } + +func (fcli *FakeCommandLine) RepoDirectory() string { + return fcli.GlobalString("repo") +} + +func (fcli *FakeCommandLine) PluginDirectory() string { + return fcli.GlobalString("pluginsDir") +} diff --git a/pkg/cmd/grafana-cli/commands/install_command.go b/pkg/cmd/grafana-cli/commands/install_command.go index 4fe4525bb75..401606e5ec8 100644 --- a/pkg/cmd/grafana-cli/commands/install_command.go +++ b/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") } - pluginsDir := c.GlobalString("pluginsDir") + pluginsDir := c.PluginDirectory() if pluginsDir == "" { return errors.New("missing pluginsDir flag") } @@ -46,7 +46,7 @@ func validateInput(c CommandLine, pluginFolder string) error { } func installCommand(c CommandLine) error { - pluginFolder := c.GlobalString("pluginsDir") + pluginFolder := c.PluginDirectory() if err := validateInput(c, pluginFolder); err != nil { return err } @@ -58,8 +58,8 @@ func installCommand(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 { return err } diff --git a/pkg/cmd/grafana-cli/commands/listremote_command.go b/pkg/cmd/grafana-cli/commands/listremote_command.go index c4de82a985d..4798369def1 100644 --- a/pkg/cmd/grafana-cli/commands/listremote_command.go +++ b/pkg/cmd/grafana-cli/commands/listremote_command.go @@ -6,7 +6,7 @@ import ( ) func listremoteCommand(c CommandLine) error { - plugin, err := s.ListAllPlugins(c.GlobalString("repo")) + plugin, err := s.ListAllPlugins(c.RepoDirectory()) if err != nil { return err diff --git a/pkg/cmd/grafana-cli/commands/ls_command.go b/pkg/cmd/grafana-cli/commands/ls_command.go index 212188caf5a..7dcecb9d725 100644 --- a/pkg/cmd/grafana-cli/commands/ls_command.go +++ b/pkg/cmd/grafana-cli/commands/ls_command.go @@ -32,7 +32,7 @@ var validateLsCommand = func(pluginDir string) error { } func lsCommand(c CommandLine) error { - pluginDir := c.GlobalString("pluginsDir") + pluginDir := c.PluginDirectory() if err := validateLsCommand(pluginDir); err != nil { return err } diff --git a/pkg/cmd/grafana-cli/commands/remove_command.go b/pkg/cmd/grafana-cli/commands/remove_command.go index 9792ed9d095..d5ed73def05 100644 --- a/pkg/cmd/grafana-cli/commands/remove_command.go +++ b/pkg/cmd/grafana-cli/commands/remove_command.go @@ -2,30 +2,32 @@ package commands import ( "errors" - "fmt" m "github.com/grafana/grafana/pkg/cmd/grafana-cli/models" services "github.com/grafana/grafana/pkg/cmd/grafana-cli/services" + "strings" ) var getPluginss func(path string) []m.InstalledPlugin = services.GetLocalPlugins var removePlugin func(pluginPath, id string) error = services.RemoveInstalledPlugin func removeCommand(c CommandLine) error { - pluginPath := c.GlobalString("pluginsDir") - localPlugins := getPluginss(pluginPath) + pluginPath := c.PluginDirectory() plugin := c.Args().First() if plugin == "" { 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 } diff --git a/pkg/cmd/grafana-cli/commands/upgrade_all_command.go b/pkg/cmd/grafana-cli/commands/upgrade_all_command.go index 19e9ff45504..1a6df719053 100644 --- a/pkg/cmd/grafana-cli/commands/upgrade_all_command.go +++ b/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 { - pluginsDir := c.GlobalString("pluginsDir") + pluginsDir := c.PluginDirectory() localPlugins := s.GetLocalPlugins(pluginsDir) diff --git a/pkg/cmd/grafana-cli/commands/upgrade_command.go b/pkg/cmd/grafana-cli/commands/upgrade_command.go index 2a6f5bd0f37..355ccab3d1c 100644 --- a/pkg/cmd/grafana-cli/commands/upgrade_command.go +++ b/pkg/cmd/grafana-cli/commands/upgrade_command.go @@ -7,7 +7,7 @@ import ( ) func upgradeCommand(c CommandLine) error { - pluginsDir := c.GlobalString("pluginsDir") + pluginsDir := c.PluginDirectory() pluginName := c.Args().First() localPlugin, err := s.ReadPlugin(pluginsDir, pluginName) @@ -16,7 +16,7 @@ func upgradeCommand(c CommandLine) error { return err } - v, err2 := s.GetPlugin(localPlugin.Id, c.GlobalString("repo")) + v, err2 := s.GetPlugin(localPlugin.Id, c.RepoDirectory()) if err2 != nil { return err2 diff --git a/pkg/cmd/grafana-cli/services/services.go b/pkg/cmd/grafana-cli/services/services.go index 1c53619c071..c5c45460722 100644 --- a/pkg/cmd/grafana-cli/services/services.go +++ b/pkg/cmd/grafana-cli/services/services.go @@ -75,9 +75,16 @@ func GetLocalPlugins(pluginDir string) []m.InstalledPlugin { 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) { diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index cb37a809212..f8e4aa374e8 100644 --- a/pkg/middleware/middleware_test.go +++ b/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 { - createUserCmd = cmd cmd.Result = m.User{Id: 33} return nil }) diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 6c425505289..14dc7b88c55 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -89,6 +89,7 @@ var ( VerifyEmailEnabled bool LoginHint string DefaultTheme string + AllowUserPassLogin bool // Http auth AdminUser string @@ -485,6 +486,7 @@ func NewConfigContext(args *CommandLineArgs) error { VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false) LoginHint = users.Key("login_hint").String() DefaultTheme = users.Key("default_theme").String() + AllowUserPassLogin = users.Key("allow_user_pass_login").MustBool(true) // anonymous access AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false) diff --git a/public/app/core/controllers/login_ctrl.js b/public/app/core/controllers/login_ctrl.js index 45a47558ed7..8696d94f4f3 100644 --- a/public/app/core/controllers/login_ctrl.js +++ b/public/app/core/controllers/login_ctrl.js @@ -18,6 +18,7 @@ function (angular, coreModule, config) { $scope.googleAuthEnabled = config.googleAuthEnabled; $scope.githubAuthEnabled = config.githubAuthEnabled; $scope.oauthEnabled = config.githubAuthEnabled || config.googleAuthEnabled; + $scope.allowUserPassLogin = config.allowUserPassLogin; $scope.disableUserSignUp = config.disableUserSignUp; $scope.loginHint = config.loginHint; diff --git a/public/app/core/services/alert_srv.ts b/public/app/core/services/alert_srv.ts index 971743b7285..3003e59c74b 100644 --- a/public/app/core/services/alert_srv.ts +++ b/public/app/core/services/alert_srv.ts @@ -28,10 +28,6 @@ export class AlertSrv { }, this.$rootScope); 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) { diff --git a/public/app/core/services/backend_srv.ts b/public/app/core/services/backend_srv.ts index 412873f3677..17299f452a3 100644 --- a/public/app/core/services/backend_srv.ts +++ b/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; }); }; diff --git a/public/app/core/utils/kbn.js b/public/app/core/utils/kbn.js index 83f577b460d..1eecaae463e 100644 --- a/public/app/core/utils/kbn.js +++ b/public/app/core/utils/kbn.js @@ -397,6 +397,9 @@ function($, _, moment) { kbn.valueFormats.rps = kbn.formatBuilders.simpleCountUnit('rps'); kbn.valueFormats.wps = kbn.formatBuilders.simpleCountUnit('wps'); 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 kbn.valueFormats.watt = kbn.formatBuilders.decimalSIPrefix('W'); @@ -664,6 +667,9 @@ function($, _, moment) { {text: 'reads/sec (rps)', value: 'rps' }, {text: 'writes/sec (wps)', value: 'wps' }, {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' }, ] }, { diff --git a/public/app/partials/login.html b/public/app/partials/login.html index 8143ff35125..5bee63e6214 100644 --- a/public/app/partials/login.html +++ b/public/app/partials/login.html @@ -17,7 +17,7 @@ -
    +
    User @@ -40,7 +40,7 @@
    -