diff --git a/.floo b/.floo
new file mode 100644
index 00000000000..a8fb87025ec
--- /dev/null
+++ b/.floo
@@ -0,0 +1,4 @@
+{
+ "url": "https://floobits.com/raintank/grafana"
+}
+
diff --git a/.flooignore b/.flooignore
new file mode 100644
index 00000000000..b9bb5ef4fe2
--- /dev/null
+++ b/.flooignore
@@ -0,0 +1,13 @@
+#*
+*.o
+*.pyc
+*.pyo
+*~
+extern/
+node_modules/
+tmp/
+data/
+vendor/
+public_gen/
+dist/
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 930a91af1da..bf074487057 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,26 @@
-# 3.0.0 stable (unreleased)
+# 3.1.0
+### Enhancements
+* **Singlestat**: Add support for range to text mappings, closes [#1319](https://github.com/grafana/grafana/issues/1319)
+* **Graph**: Adds sort order options for graph tooltip, closes [#1189](https://github.com/grafana/grafana/issues/1189)
+* **Theme**: Add default theme to config file [#5011](https://github.com/grafana/grafana/pull/5011)
+
+# 3.0.3 Patch release (unreleased)
+* **Time picker**: Fixed issue timepicker and UTC when reading time from URL, fixes [#5078](https://github.com/grafana/grafana/issues/5078)
+* **CloudWatch**: Support for Multiple Account by AssumeRole, closes [#3522](https://github.com/grafana/grafana/issues/3522)
+
+# 3.0.2 Patch release (2016-05-16)
+
+* **Templating**: Fixed issue mixing row repeat and panel repeats, fixes [#4988](https://github.com/grafana/grafana/issues/4988)
+* **Templating**: Fixed issue detecting dependencies in nested variables, fixes [#4987](https://github.com/grafana/grafana/issues/4987), fixes [#4986](https://github.com/grafana/grafana/issues/4986)
+* **Graph**: Fixed broken PNG rendering in graph panel, fixes [#5025](https://github.com/grafana/grafana/issues/5025)
+* **Graph**: Fixed broken xaxis on graph panel, fixes [#5024](https://github.com/grafana/grafana/issues/5024)
+
+* **Influxdb**: Fixes crash when hiding middle serie, fixes [#5005](https://github.com/grafana/grafana/issues/5005)
+
+# 3.0.1 Stable (2016-05-11)
+
+### Bug fixes
* **Templating**: Fixed issue with new data source variable not persisting current selected value, fixes [#4934](https://github.com/grafana/grafana/issues/4934)
# 3.0.0-beta7 (2016-05-02)
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index b48d5189e94..a1bb492e5d2 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -124,6 +124,11 @@
"Comment": "v1.0.0",
"Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
},
+ {
+ "ImportPath": "github.com/aws/aws-sdk-go/service/sts",
+ "Comment": "v1.0.0",
+ "Rev": "abb928e07c4108683d6b4d0b6ca08fe6bc0eee5f"
+ },
{
"ImportPath": "github.com/bmizerany/assert",
"Comment": "release.r60-6-ge17e998",
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/api.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/api.go
new file mode 100644
index 00000000000..52755c9e061
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/api.go
@@ -0,0 +1,1127 @@
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
+
+// Package sts provides a client for AWS Security Token Service.
+package sts
+
+import (
+ "time"
+
+ "github.com/aws/aws-sdk-go/aws/awsutil"
+ "github.com/aws/aws-sdk-go/aws/request"
+)
+
+const opAssumeRole = "AssumeRole"
+
+// AssumeRoleRequest generates a request for the AssumeRole operation.
+func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) {
+ op := &request.Operation{
+ Name: opAssumeRole,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &AssumeRoleInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &AssumeRoleOutput{}
+ req.Data = output
+ return
+}
+
+// Returns a set of temporary security credentials (consisting of an access
+// key ID, a secret access key, and a security token) that you can use to access
+// AWS resources that you might not normally have access to. Typically, you
+// use AssumeRole for cross-account access or federation.
+//
+// Important: You cannot call AssumeRole by using AWS account credentials;
+// access will be denied. You must use IAM user credentials or temporary security
+// credentials to call AssumeRole.
+//
+// For cross-account access, imagine that you own multiple accounts and need
+// to access resources in each account. You could create long-term credentials
+// in each account to access those resources. However, managing all those credentials
+// and remembering which one can access which account can be time consuming.
+// Instead, you can create one set of long-term credentials in one account and
+// then use temporary security credentials to access all the other accounts
+// by assuming roles in those accounts. For more information about roles, see
+// IAM Roles (Delegation and Federation) (http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html)
+// in the Using IAM.
+//
+// For federation, you can, for example, grant single sign-on access to the
+// AWS Management Console. If you already have an identity and authentication
+// system in your corporate network, you don't have to recreate user identities
+// in AWS in order to grant those user identities access to AWS. Instead, after
+// a user has been authenticated, you call AssumeRole (and specify the role
+// with the appropriate permissions) to get temporary security credentials for
+// that user. With those temporary security credentials, you construct a sign-in
+// URL that users can use to access the console. For more information, see Common
+// Scenarios for Temporary Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html#sts-introduction)
+// in the Using IAM.
+//
+// The temporary security credentials are valid for the duration that you specified
+// when calling AssumeRole, which can be from 900 seconds (15 minutes) to 3600
+// seconds (1 hour). The default is 1 hour.
+//
+// Optionally, you can pass an IAM access policy to this operation. If you
+// choose not to pass a policy, the temporary security credentials that are
+// returned by the operation have the permissions that are defined in the access
+// policy of the role that is being assumed. If you pass a policy to this operation,
+// the temporary security credentials that are returned by the operation have
+// the permissions that are allowed by both the access policy of the role that
+// is being assumed, and the policy that you pass. This gives you a way to further
+// restrict the permissions for the resulting temporary security credentials.
+// You cannot use the passed policy to grant permissions that are in excess
+// of those allowed by the access policy of the role that is being assumed.
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the Using IAM.
+//
+// To assume a role, your AWS account must be trusted by the role. The trust
+// relationship is defined in the role's trust policy when the role is created.
+// You must also have a policy that allows you to call sts:AssumeRole.
+//
+// Using MFA with AssumeRole
+//
+// You can optionally include multi-factor authentication (MFA) information
+// when you call AssumeRole. This is useful for cross-account scenarios in which
+// you want to make sure that the user who is assuming the role has been authenticated
+// using an AWS MFA device. In that scenario, the trust policy of the role being
+// assumed includes a condition that tests for MFA authentication; if the caller
+// does not include valid MFA information, the request to assume the role is
+// denied. The condition in a trust policy that tests for MFA authentication
+// might look like the following example.
+//
+// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}}
+//
+// For more information, see Configuring MFA-Protected API Access (http://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html)
+// in the Using IAM guide.
+//
+// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode
+// parameters. The SerialNumber value identifies the user's hardware or virtual
+// MFA device. The TokenCode is the time-based one-time password (TOTP) that
+// the MFA devices produces.
+func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
+ req, out := c.AssumeRoleRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+const opAssumeRoleWithSAML = "AssumeRoleWithSAML"
+
+// AssumeRoleWithSAMLRequest generates a request for the AssumeRoleWithSAML operation.
+func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) {
+ op := &request.Operation{
+ Name: opAssumeRoleWithSAML,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &AssumeRoleWithSAMLInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &AssumeRoleWithSAMLOutput{}
+ req.Data = output
+ return
+}
+
+// Returns a set of temporary security credentials for users who have been authenticated
+// via a SAML authentication response. This operation provides a mechanism for
+// tying an enterprise identity store or directory to role-based AWS access
+// without user-specific credentials or configuration.
+//
+// The temporary security credentials returned by this operation consist of
+// an access key ID, a secret access key, and a security token. Applications
+// can use these temporary security credentials to sign calls to AWS services.
+// The credentials are valid for the duration that you specified when calling
+// AssumeRoleWithSAML, which can be up to 3600 seconds (1 hour) or until the
+// time specified in the SAML authentication response's SessionNotOnOrAfter
+// value, whichever is shorter.
+//
+// The maximum duration for a session is 1 hour, and the minimum duration is
+// 15 minutes, even if values outside this range are specified. Optionally,
+// you can pass an IAM access policy to this operation. If you choose not to
+// pass a policy, the temporary security credentials that are returned by the
+// operation have the permissions that are defined in the access policy of the
+// role that is being assumed. If you pass a policy to this operation, the temporary
+// security credentials that are returned by the operation have the permissions
+// that are allowed by both the access policy of the role that is being assumed,
+// and the policy that you pass. This gives you a way to further restrict the
+// permissions for the resulting temporary security credentials. You cannot
+// use the passed policy to grant permissions that are in excess of those allowed
+// by the access policy of the role that is being assumed. For more information,
+// see Permissions for AssumeRole, AssumeRoleWithSAML, and AssumeRoleWithWebIdentity
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the Using IAM.
+//
+// Before your application can call AssumeRoleWithSAML, you must configure
+// your SAML identity provider (IdP) to issue the claims required by AWS. Additionally,
+// you must use AWS Identity and Access Management (IAM) to create a SAML provider
+// entity in your AWS account that represents your identity provider, and create
+// an IAM role that specifies this SAML provider in its trust policy.
+//
+// Calling AssumeRoleWithSAML does not require the use of AWS security credentials.
+// The identity of the caller is validated by using keys in the metadata document
+// that is uploaded for the SAML provider entity for your identity provider.
+//
+// For more information, see the following resources:
+//
+// About SAML 2.0-based Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html)
+// in the Using IAM. Creating SAML Identity Providers (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html)
+// in the Using IAM. Configuring a Relying Party and Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html)
+// in the Using IAM. Creating a Role for SAML 2.0 Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html)
+// in the Using IAM.
+func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) {
+ req, out := c.AssumeRoleWithSAMLRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity"
+
+// AssumeRoleWithWebIdentityRequest generates a request for the AssumeRoleWithWebIdentity operation.
+func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) {
+ op := &request.Operation{
+ Name: opAssumeRoleWithWebIdentity,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &AssumeRoleWithWebIdentityInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &AssumeRoleWithWebIdentityOutput{}
+ req.Data = output
+ return
+}
+
+// Returns a set of temporary security credentials for users who have been authenticated
+// in a mobile or web application with a web identity provider, such as Amazon
+// Cognito, Login with Amazon, Facebook, Google, or any OpenID Connect-compatible
+// identity provider.
+//
+// For mobile applications, we recommend that you use Amazon Cognito. You
+// can use Amazon Cognito with the AWS SDK for iOS (http://aws.amazon.com/sdkforios/)
+// and the AWS SDK for Android (http://aws.amazon.com/sdkforandroid/) to uniquely
+// identify a user and supply the user with a consistent identity throughout
+// the lifetime of an application.
+//
+// To learn more about Amazon Cognito, see Amazon Cognito Overview (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840)
+// in the AWS SDK for Android Developer Guide guide and Amazon Cognito Overview
+// (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664)
+// in the AWS SDK for iOS Developer Guide.
+//
+// Calling AssumeRoleWithWebIdentity does not require the use of AWS security
+// credentials. Therefore, you can distribute an application (for example, on
+// mobile devices) that requests temporary security credentials without including
+// long-term AWS credentials in the application, and without deploying server-based
+// proxy services that use long-term AWS credentials. Instead, the identity
+// of the caller is validated by using a token from the web identity provider.
+//
+// The temporary security credentials returned by this API consist of an access
+// key ID, a secret access key, and a security token. Applications can use these
+// temporary security credentials to sign calls to AWS service APIs. The credentials
+// are valid for the duration that you specified when calling AssumeRoleWithWebIdentity,
+// which can be from 900 seconds (15 minutes) to 3600 seconds (1 hour). By default,
+// the temporary security credentials are valid for 1 hour.
+//
+// Optionally, you can pass an IAM access policy to this operation. If you
+// choose not to pass a policy, the temporary security credentials that are
+// returned by the operation have the permissions that are defined in the access
+// policy of the role that is being assumed. If you pass a policy to this operation,
+// the temporary security credentials that are returned by the operation have
+// the permissions that are allowed by both the access policy of the role that
+// is being assumed, and the policy that you pass. This gives you a way to further
+// restrict the permissions for the resulting temporary security credentials.
+// You cannot use the passed policy to grant permissions that are in excess
+// of those allowed by the access policy of the role that is being assumed.
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+// in the Using IAM.
+//
+// Before your application can call AssumeRoleWithWebIdentity, you must have
+// an identity token from a supported identity provider and create a role that
+// the application can assume. The role that your application assumes must trust
+// the identity provider that is associated with the identity token. In other
+// words, the identity provider must be specified in the role's trust policy.
+//
+// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity
+// API, see the following resources:
+//
+// Using Web Identity Federation APIs for Mobile Apps (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual)
+// and Federation Through a Web-based Identity Provider (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
+// Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html).
+// This interactive website lets you walk through the process of authenticating
+// via Login with Amazon, Facebook, or Google, getting temporary security credentials,
+// and then using those credentials to make a request to AWS. AWS SDK for
+// iOS (http://aws.amazon.com/sdkforios/) and AWS SDK for Android (http://aws.amazon.com/sdkforandroid/).
+// These toolkits contain sample apps that show how to invoke the identity providers,
+// and then how to use the information from these providers to get and use temporary
+// security credentials. Web Identity Federation with Mobile Applications
+// (http://aws.amazon.com/articles/4617974389850313). This article discusses
+// web identity federation and shows an example of how to use web identity federation
+// to get access to content in Amazon S3.
+func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) {
+ req, out := c.AssumeRoleWithWebIdentityRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage"
+
+// DecodeAuthorizationMessageRequest generates a request for the DecodeAuthorizationMessage operation.
+func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) {
+ op := &request.Operation{
+ Name: opDecodeAuthorizationMessage,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &DecodeAuthorizationMessageInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &DecodeAuthorizationMessageOutput{}
+ req.Data = output
+ return
+}
+
+// Decodes additional information about the authorization status of a request
+// from an encoded message returned in response to an AWS request.
+//
+// For example, if a user is not authorized to perform an action that he or
+// she has requested, the request returns a Client.UnauthorizedOperation response
+// (an HTTP 403 response). Some AWS actions additionally return an encoded message
+// that can provide details about this authorization failure.
+//
+// Only certain AWS actions return an encoded authorization message. The documentation
+// for an individual action indicates whether that action returns an encoded
+// message in addition to returning an HTTP code. The message is encoded because
+// the details of the authorization status can constitute privileged information
+// that the user who requested the action should not see. To decode an authorization
+// status message, a user must be granted permissions via an IAM policy to request
+// the DecodeAuthorizationMessage (sts:DecodeAuthorizationMessage) action.
+//
+// The decoded message includes the following type of information:
+//
+// Whether the request was denied due to an explicit deny or due to the absence
+// of an explicit allow. For more information, see Determining Whether a Request
+// is Allowed or Denied (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)
+// in the Using IAM. The principal who made the request. The requested action.
+// The requested resource. The values of condition keys in the context of the
+// user's request.
+func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
+ req, out := c.DecodeAuthorizationMessageRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+const opGetFederationToken = "GetFederationToken"
+
+// GetFederationTokenRequest generates a request for the GetFederationToken operation.
+func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) {
+ op := &request.Operation{
+ Name: opGetFederationToken,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &GetFederationTokenInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &GetFederationTokenOutput{}
+ req.Data = output
+ return
+}
+
+// Returns a set of temporary security credentials (consisting of an access
+// key ID, a secret access key, and a security token) for a federated user.
+// A typical use is in a proxy application that gets temporary security credentials
+// on behalf of distributed applications inside a corporate network. Because
+// you must call the GetFederationToken action using the long-term security
+// credentials of an IAM user, this call is appropriate in contexts where those
+// credentials can be safely stored, usually in a server-based application.
+//
+// If you are creating a mobile-based or browser-based app that can authenticate
+// users using a web identity provider like Login with Amazon, Facebook, Google,
+// or an OpenID Connect-compatible identity provider, we recommend that you
+// use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity.
+// For more information, see Federation Through a Web-based Identity Provider
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity).
+//
+// The GetFederationToken action must be called by using the long-term AWS
+// security credentials of an IAM user. You can also call GetFederationToken
+// using the security credentials of an AWS account (root), but this is not
+// recommended. Instead, we recommend that you create an IAM user for the purpose
+// of the proxy application and then attach a policy to the IAM user that limits
+// federated users to only the actions and resources they need access to. For
+// more information, see IAM Best Practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
+// in the Using IAM.
+//
+// The temporary security credentials that are obtained by using the long-term
+// credentials of an IAM user are valid for the specified duration, between
+// 900 seconds (15 minutes) and 129600 seconds (36 hours). Temporary credentials
+// that are obtained by using AWS account (root) credentials have a maximum
+// duration of 3600 seconds (1 hour)
+//
+// Permissions
+//
+// The permissions for the temporary security credentials returned by GetFederationToken
+// are determined by a combination of the following:
+//
+// The policy or policies that are attached to the IAM user whose credentials
+// are used to call GetFederationToken. The policy that is passed as a parameter
+// in the call. The passed policy is attached to the temporary security credentials
+// that result from the GetFederationToken API call--that is, to the federated
+// user. When the federated user makes an AWS request, AWS evaluates the policy
+// attached to the federated user in combination with the policy or policies
+// attached to the IAM user whose credentials were used to call GetFederationToken.
+// AWS allows the federated user's request only when both the federated user
+// and the IAM user are explicitly allowed to perform the requested action.
+// The passed policy cannot grant more permissions than those that are defined
+// in the IAM user policy.
+//
+// A typical use case is that the permissions of the IAM user whose credentials
+// are used to call GetFederationToken are designed to allow access to all the
+// actions and resources that any federated user will need. Then, for individual
+// users, you pass a policy to the operation that scopes down the permissions
+// to a level that's appropriate to that individual user, using a policy that
+// allows only a subset of permissions that are granted to the IAM user.
+//
+// If you do not pass a policy, the resulting temporary security credentials
+// have no effective permissions. The only exception is when the temporary security
+// credentials are used to access a resource that has a resource-based policy
+// that specifically allows the federated user to access the resource.
+//
+// For more information about how permissions work, see Permissions for GetFederationToken
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html).
+// For information about using GetFederationToken to create temporary security
+// credentials, see GetFederationToken—Federation Through a Custom Identity
+// Broker (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken).
+func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) {
+ req, out := c.GetFederationTokenRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+const opGetSessionToken = "GetSessionToken"
+
+// GetSessionTokenRequest generates a request for the GetSessionToken operation.
+func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) {
+ op := &request.Operation{
+ Name: opGetSessionToken,
+ HTTPMethod: "POST",
+ HTTPPath: "/",
+ }
+
+ if input == nil {
+ input = &GetSessionTokenInput{}
+ }
+
+ req = c.newRequest(op, input, output)
+ output = &GetSessionTokenOutput{}
+ req.Data = output
+ return
+}
+
+// Returns a set of temporary credentials for an AWS account or IAM user. The
+// credentials consist of an access key ID, a secret access key, and a security
+// token. Typically, you use GetSessionToken if you want to use MFA to protect
+// programmatic calls to specific AWS APIs like Amazon EC2 StopInstances. MFA-enabled
+// IAM users would need to call GetSessionToken and submit an MFA code that
+// is associated with their MFA device. Using the temporary security credentials
+// that are returned from the call, IAM users can then make programmatic calls
+// to APIs that require MFA authentication. If you do not supply a correct MFA
+// code, then the API returns an access denied error.
+//
+// The GetSessionToken action must be called by using the long-term AWS security
+// credentials of the AWS account or an IAM user. Credentials that are created
+// by IAM users are valid for the duration that you specify, between 900 seconds
+// (15 minutes) and 129600 seconds (36 hours); credentials that are created
+// by using account credentials have a maximum duration of 3600 seconds (1 hour).
+//
+// We recommend that you do not call GetSessionToken with root account credentials.
+// Instead, follow our best practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users)
+// by creating one or more IAM users, giving them the necessary permissions,
+// and using IAM users for everyday interaction with AWS.
+//
+// The permissions associated with the temporary security credentials returned
+// by GetSessionToken are based on the permissions associated with account or
+// IAM user whose credentials are used to call the action. If GetSessionToken
+// is called using root account credentials, the temporary credentials have
+// root account permissions. Similarly, if GetSessionToken is called using the
+// credentials of an IAM user, the temporary credentials have the same permissions
+// as the IAM user.
+//
+// For more information about using GetSessionToken to create temporary credentials,
+// go to Temporary Credentials for Users in Untrusted Environments (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken)
+// in the Using IAM.
+func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) {
+ req, out := c.GetSessionTokenRequest(input)
+ err := req.Send()
+ return out, err
+}
+
+type AssumeRoleInput struct {
+ // The duration, in seconds, of the role session. The value can range from 900
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set
+ // to 3600 seconds.
+ DurationSeconds *int64 `min:"900" type:"integer"`
+
+ // A unique identifier that is used by third parties when assuming roles in
+ // their customers' accounts. For each role that the third party can assume,
+ // they should instruct their customers to ensure the role's trust policy checks
+ // for the external ID that the third party generated. Each time the third party
+ // assumes the role, they should pass the customer's external ID. The external
+ // ID is useful in order to help third parties bind a role to the customer who
+ // created it. For more information about the external ID, see How to Use an
+ // External ID When Granting Access to Your AWS Resources to a Third Party (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html)
+ // in the Using IAM.
+ ExternalId *string `min:"2" type:"string"`
+
+ // An IAM policy in JSON format.
+ //
+ // This parameter is optional. If you pass a policy, the temporary security
+ // credentials that are returned by the operation have the permissions that
+ // are allowed by both (the intersection of) the access policy of the role that
+ // is being assumed, and the policy that you pass. This gives you a way to further
+ // restrict the permissions for the resulting temporary security credentials.
+ // You cannot use the passed policy to grant permissions that are in excess
+ // of those allowed by the access policy of the role that is being assumed.
+ // For more information, see Permissions for AssumeRole, AssumeRoleWithSAML,
+ // and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+ // in the Using IAM.
+ //
+ // The policy plain text must be 2048 bytes or shorter. However, an internal
+ // conversion compresses it into a packed binary format with a separate limit.
+ // The PackedPolicySize response element indicates by percentage how close to
+ // the upper size limit the policy is, with 100% equaling the maximum allowed
+ // size.
+ Policy *string `min:"1" type:"string"`
+
+ // The Amazon Resource Name (ARN) of the role to assume.
+ RoleArn *string `min:"20" type:"string" required:"true"`
+
+ // An identifier for the assumed role session.
+ //
+ // Use the role session name to uniquely identity a session when the same role
+ // is assumed by different principals or for different reasons. In cross-account
+ // scenarios, the role session name is visible to, and can be logged by the
+ // account that owns the role. The role session name is also used in the ARN
+ // of the assumed role principal. This means that subsequent cross-account API
+ // requests using the temporary security credentials will expose the role session
+ // name to the external account in their CloudTrail logs.
+ RoleSessionName *string `min:"2" type:"string" required:"true"`
+
+ // The identification number of the MFA device that is associated with the user
+ // who is making the AssumeRole call. Specify this value if the trust policy
+ // of the role being assumed includes a condition that requires MFA authentication.
+ // The value is either the serial number for a hardware device (such as GAHT12345678)
+ // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
+ SerialNumber *string `min:"9" type:"string"`
+
+ // The value provided by the MFA device, if the trust policy of the role being
+ // assumed requires MFA (that is, if the policy includes a condition that tests
+ // for MFA). If the role being assumed requires MFA and if the TokenCode value
+ // is missing or expired, the AssumeRole call returns an "access denied" error.
+ TokenCode *string `min:"6" type:"string"`
+
+ metadataAssumeRoleInput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleInput) GoString() string {
+ return s.String()
+}
+
+// Contains the response to a successful AssumeRole request, including temporary
+// AWS credentials that can be used to make AWS requests.
+type AssumeRoleOutput struct {
+ // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
+ // that you can use to refer to the resulting temporary security credentials.
+ // For example, you can reference these credentials as a principal in a resource-based
+ // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
+ // that you specified when you called AssumeRole.
+ AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+ // The temporary security credentials, which include an access key ID, a secret
+ // access key, and a security (or session) token.
+ Credentials *Credentials `type:"structure"`
+
+ // A percentage value that indicates the size of the policy in packed form.
+ // The service rejects any policy with a packed size greater than 100 percent,
+ // which means the policy exceeded the allowed space.
+ PackedPolicySize *int64 `type:"integer"`
+
+ metadataAssumeRoleOutput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleOutput) GoString() string {
+ return s.String()
+}
+
+type AssumeRoleWithSAMLInput struct {
+ // The duration, in seconds, of the role session. The value can range from 900
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set
+ // to 3600 seconds. An expiration can also be specified in the SAML authentication
+ // response's SessionNotOnOrAfter value. The actual expiration time is whichever
+ // value is shorter.
+ //
+ // The maximum duration for a session is 1 hour, and the minimum duration is
+ // 15 minutes, even if values outside this range are specified.
+ DurationSeconds *int64 `min:"900" type:"integer"`
+
+ // An IAM policy in JSON format.
+ //
+ // The policy parameter is optional. If you pass a policy, the temporary security
+ // credentials that are returned by the operation have the permissions that
+ // are allowed by both the access policy of the role that is being assumed,
+ // and the policy that you pass. This gives you a way to further restrict the
+ // permissions for the resulting temporary security credentials. You cannot
+ // use the passed policy to grant permissions that are in excess of those allowed
+ // by the access policy of the role that is being assumed. For more information,
+ // Permissions for AssumeRole, AssumeRoleWithSAML, and AssumeRoleWithWebIdentity
+ // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+ // in the Using IAM.
+ //
+ // The policy plain text must be 2048 bytes or shorter. However, an internal
+ // conversion compresses it into a packed binary format with a separate limit.
+ // The PackedPolicySize response element indicates by percentage how close to
+ // the upper size limit the policy is, with 100% equaling the maximum allowed
+ // size.
+ Policy *string `min:"1" type:"string"`
+
+ // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes
+ // the IdP.
+ PrincipalArn *string `min:"20" type:"string" required:"true"`
+
+ // The Amazon Resource Name (ARN) of the role that the caller is assuming.
+ RoleArn *string `min:"20" type:"string" required:"true"`
+
+ // The base-64 encoded SAML authentication response provided by the IdP.
+ //
+ // For more information, see Configuring a Relying Party and Adding Claims
+ // (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html)
+ // in the Using IAM guide.
+ SAMLAssertion *string `min:"4" type:"string" required:"true"`
+
+ metadataAssumeRoleWithSAMLInput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleWithSAMLInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithSAMLInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithSAMLInput) GoString() string {
+ return s.String()
+}
+
+// Contains the response to a successful AssumeRoleWithSAML request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type AssumeRoleWithSAMLOutput struct {
+ // The identifiers for the temporary security credentials that the operation
+ // returns.
+ AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+ // The value of the Recipient attribute of the SubjectConfirmationData element
+ // of the SAML assertion.
+ Audience *string `type:"string"`
+
+ // AWS credentials for API authentication.
+ Credentials *Credentials `type:"structure"`
+
+ // The value of the Issuer element of the SAML assertion.
+ Issuer *string `type:"string"`
+
+ // A hash value based on the concatenation of the Issuer response value, the
+ // AWS account ID, and the friendly name (the last part of the ARN) of the SAML
+ // provider in IAM. The combination of NameQualifier and Subject can be used
+ // to uniquely identify a federated user.
+ //
+ // The following pseudocode shows how the hash value is calculated:
+ //
+ // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP"
+ // ) )
+ NameQualifier *string `type:"string"`
+
+ // A percentage value that indicates the size of the policy in packed form.
+ // The service rejects any policy with a packed size greater than 100 percent,
+ // which means the policy exceeded the allowed space.
+ PackedPolicySize *int64 `type:"integer"`
+
+ // The value of the NameID element in the Subject element of the SAML assertion.
+ Subject *string `type:"string"`
+
+ // The format of the name ID, as defined by the Format attribute in the NameID
+ // element of the SAML assertion. Typical examples of the format are transient
+ // or persistent.
+ //
+ // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format,
+ // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ // is returned as transient. If the format includes any other prefix, the format
+ // is returned with no modifications.
+ SubjectType *string `type:"string"`
+
+ metadataAssumeRoleWithSAMLOutput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleWithSAMLOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithSAMLOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithSAMLOutput) GoString() string {
+ return s.String()
+}
+
+type AssumeRoleWithWebIdentityInput struct {
+ // The duration, in seconds, of the role session. The value can range from 900
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set
+ // to 3600 seconds.
+ DurationSeconds *int64 `min:"900" type:"integer"`
+
+ // An IAM policy in JSON format.
+ //
+ // The policy parameter is optional. If you pass a policy, the temporary security
+ // credentials that are returned by the operation have the permissions that
+ // are allowed by both the access policy of the role that is being assumed,
+ // and the policy that you pass. This gives you a way to further restrict the
+ // permissions for the resulting temporary security credentials. You cannot
+ // use the passed policy to grant permissions that are in excess of those allowed
+ // by the access policy of the role that is being assumed. For more information,
+ // see Permissions for AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html)
+ // in the Using IAM.
+ //
+ // The policy plain text must be 2048 bytes or shorter. However, an internal
+ // conversion compresses it into a packed binary format with a separate limit.
+ // The PackedPolicySize response element indicates by percentage how close to
+ // the upper size limit the policy is, with 100% equaling the maximum allowed
+ // size.
+ Policy *string `min:"1" type:"string"`
+
+ // The fully qualified host component of the domain name of the identity provider.
+ //
+ // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com
+ // and graph.facebook.com are the only supported identity providers for OAuth
+ // 2.0 access tokens. Do not include URL schemes and port numbers.
+ //
+ // Do not specify this value for OpenID Connect ID tokens.
+ ProviderId *string `min:"4" type:"string"`
+
+ // The Amazon Resource Name (ARN) of the role that the caller is assuming.
+ RoleArn *string `min:"20" type:"string" required:"true"`
+
+ // An identifier for the assumed role session. Typically, you pass the name
+ // or identifier that is associated with the user who is using your application.
+ // That way, the temporary security credentials that your application will use
+ // are associated with that user. This session name is included as part of the
+ // ARN and assumed role ID in the AssumedRoleUser response element.
+ RoleSessionName *string `min:"2" type:"string" required:"true"`
+
+ // The OAuth 2.0 access token or OpenID Connect ID token that is provided by
+ // the identity provider. Your application must get this token by authenticating
+ // the user who is using your application with a web identity provider before
+ // the application makes an AssumeRoleWithWebIdentity call.
+ WebIdentityToken *string `min:"4" type:"string" required:"true"`
+
+ metadataAssumeRoleWithWebIdentityInput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleWithWebIdentityInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithWebIdentityInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithWebIdentityInput) GoString() string {
+ return s.String()
+}
+
+// Contains the response to a successful AssumeRoleWithWebIdentity request,
+// including temporary AWS credentials that can be used to make AWS requests.
+type AssumeRoleWithWebIdentityOutput struct {
+ // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
+ // that you can use to refer to the resulting temporary security credentials.
+ // For example, you can reference these credentials as a principal in a resource-based
+ // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName
+ // that you specified when you called AssumeRole.
+ AssumedRoleUser *AssumedRoleUser `type:"structure"`
+
+ // The intended audience (also known as client ID) of the web identity token.
+ // This is traditionally the client identifier issued to the application that
+ // requested the web identity token.
+ Audience *string `type:"string"`
+
+ // The temporary security credentials, which include an access key ID, a secret
+ // access key, and a security token.
+ Credentials *Credentials `type:"structure"`
+
+ // A percentage value that indicates the size of the policy in packed form.
+ // The service rejects any policy with a packed size greater than 100 percent,
+ // which means the policy exceeded the allowed space.
+ PackedPolicySize *int64 `type:"integer"`
+
+ // The issuing authority of the web identity token presented. For OpenID Connect
+ // ID Tokens this contains the value of the iss field. For OAuth 2.0 access
+ // tokens, this contains the value of the ProviderId parameter that was passed
+ // in the AssumeRoleWithWebIdentity request.
+ Provider *string `type:"string"`
+
+ // The unique user identifier that is returned by the identity provider. This
+ // identifier is associated with the WebIdentityToken that was submitted with
+ // the AssumeRoleWithWebIdentity call. The identifier is typically unique to
+ // the user and the application that acquired the WebIdentityToken (pairwise
+ // identifier). For OpenID Connect ID tokens, this field contains the value
+ // returned by the identity provider as the token's sub (Subject) claim.
+ SubjectFromWebIdentityToken *string `min:"6" type:"string"`
+
+ metadataAssumeRoleWithWebIdentityOutput `json:"-" xml:"-"`
+}
+
+type metadataAssumeRoleWithWebIdentityOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumeRoleWithWebIdentityOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumeRoleWithWebIdentityOutput) GoString() string {
+ return s.String()
+}
+
+// The identifiers for the temporary security credentials that the operation
+// returns.
+type AssumedRoleUser struct {
+ // The ARN of the temporary security credentials that are returned from the
+ // AssumeRole action. For more information about ARNs and how to use them in
+ // policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
+ // in Using IAM.
+ Arn *string `min:"20" type:"string" required:"true"`
+
+ // A unique identifier that contains the role ID and the role session name of
+ // the role that is being assumed. The role ID is generated by AWS when the
+ // role is created.
+ AssumedRoleId *string `min:"2" type:"string" required:"true"`
+
+ metadataAssumedRoleUser `json:"-" xml:"-"`
+}
+
+type metadataAssumedRoleUser struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s AssumedRoleUser) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s AssumedRoleUser) GoString() string {
+ return s.String()
+}
+
+// AWS credentials for API authentication.
+type Credentials struct {
+ // The access key ID that identifies the temporary security credentials.
+ AccessKeyId *string `min:"16" type:"string" required:"true"`
+
+ // The date on which the current credentials expire.
+ Expiration *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"`
+
+ // The secret access key that can be used to sign requests.
+ SecretAccessKey *string `type:"string" required:"true"`
+
+ // The token that users must pass to the service API to use the temporary credentials.
+ SessionToken *string `type:"string" required:"true"`
+
+ metadataCredentials `json:"-" xml:"-"`
+}
+
+type metadataCredentials struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s Credentials) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s Credentials) GoString() string {
+ return s.String()
+}
+
+type DecodeAuthorizationMessageInput struct {
+ // The encoded message that was returned with the response.
+ EncodedMessage *string `min:"1" type:"string" required:"true"`
+
+ metadataDecodeAuthorizationMessageInput `json:"-" xml:"-"`
+}
+
+type metadataDecodeAuthorizationMessageInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s DecodeAuthorizationMessageInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DecodeAuthorizationMessageInput) GoString() string {
+ return s.String()
+}
+
+// A document that contains additional information about the authorization status
+// of a request from an encoded message that is returned in response to an AWS
+// request.
+type DecodeAuthorizationMessageOutput struct {
+ // An XML document that contains the decoded message. For more information,
+ // see DecodeAuthorizationMessage.
+ DecodedMessage *string `type:"string"`
+
+ metadataDecodeAuthorizationMessageOutput `json:"-" xml:"-"`
+}
+
+type metadataDecodeAuthorizationMessageOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s DecodeAuthorizationMessageOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s DecodeAuthorizationMessageOutput) GoString() string {
+ return s.String()
+}
+
+// Identifiers for the federated user that is associated with the credentials.
+type FederatedUser struct {
+ // The ARN that specifies the federated user that is associated with the credentials.
+ // For more information about ARNs and how to use them in policies, see IAM
+ // Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html)
+ // in Using IAM.
+ Arn *string `min:"20" type:"string" required:"true"`
+
+ // The string that identifies the federated user associated with the credentials,
+ // similar to the unique ID of an IAM user.
+ FederatedUserId *string `min:"2" type:"string" required:"true"`
+
+ metadataFederatedUser `json:"-" xml:"-"`
+}
+
+type metadataFederatedUser struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s FederatedUser) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s FederatedUser) GoString() string {
+ return s.String()
+}
+
+type GetFederationTokenInput struct {
+ // The duration, in seconds, that the session should last. Acceptable durations
+ // for federation sessions range from 900 seconds (15 minutes) to 129600 seconds
+ // (36 hours), with 43200 seconds (12 hours) as the default. Sessions obtained
+ // using AWS account (root) credentials are restricted to a maximum of 3600
+ // seconds (one hour). If the specified duration is longer than one hour, the
+ // session obtained by using AWS account (root) credentials defaults to one
+ // hour.
+ DurationSeconds *int64 `min:"900" type:"integer"`
+
+ // The name of the federated user. The name is used as an identifier for the
+ // temporary security credentials (such as Bob). For example, you can reference
+ // the federated user name in a resource-based policy, such as in an Amazon
+ // S3 bucket policy.
+ Name *string `min:"2" type:"string" required:"true"`
+
+ // An IAM policy in JSON format that is passed with the GetFederationToken call
+ // and evaluated along with the policy or policies that are attached to the
+ // IAM user whose credentials are used to call GetFederationToken. The passed
+ // policy is used to scope down the permissions that are available to the IAM
+ // user, by allowing only a subset of the permissions that are granted to the
+ // IAM user. The passed policy cannot grant more permissions than those granted
+ // to the IAM user. The final permissions for the federated user are the most
+ // restrictive set based on the intersection of the passed policy and the IAM
+ // user policy.
+ //
+ // If you do not pass a policy, the resulting temporary security credentials
+ // have no effective permissions. The only exception is when the temporary security
+ // credentials are used to access a resource that has a resource-based policy
+ // that specifically allows the federated user to access the resource.
+ //
+ // The policy plain text must be 2048 bytes or shorter. However, an internal
+ // conversion compresses it into a packed binary format with a separate limit.
+ // The PackedPolicySize response element indicates by percentage how close to
+ // the upper size limit the policy is, with 100% equaling the maximum allowed
+ // size. For more information about how permissions work, see Permissions for
+ // GetFederationToken (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html).
+ Policy *string `min:"1" type:"string"`
+
+ metadataGetFederationTokenInput `json:"-" xml:"-"`
+}
+
+type metadataGetFederationTokenInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetFederationTokenInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetFederationTokenInput) GoString() string {
+ return s.String()
+}
+
+// Contains the response to a successful GetFederationToken request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type GetFederationTokenOutput struct {
+ // Credentials for the service API authentication.
+ Credentials *Credentials `type:"structure"`
+
+ // Identifiers for the federated user associated with the credentials (such
+ // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You
+ // can use the federated user's ARN in your resource-based policies, such as
+ // an Amazon S3 bucket policy.
+ FederatedUser *FederatedUser `type:"structure"`
+
+ // A percentage value indicating the size of the policy in packed form. The
+ // service rejects policies for which the packed size is greater than 100 percent
+ // of the allowed value.
+ PackedPolicySize *int64 `type:"integer"`
+
+ metadataGetFederationTokenOutput `json:"-" xml:"-"`
+}
+
+type metadataGetFederationTokenOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetFederationTokenOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetFederationTokenOutput) GoString() string {
+ return s.String()
+}
+
+type GetSessionTokenInput struct {
+ // The duration, in seconds, that the credentials should remain valid. Acceptable
+ // durations for IAM user sessions range from 900 seconds (15 minutes) to 129600
+ // seconds (36 hours), with 43200 seconds (12 hours) as the default. Sessions
+ // for AWS account owners are restricted to a maximum of 3600 seconds (one hour).
+ // If the duration is longer than one hour, the session for AWS account owners
+ // defaults to one hour.
+ DurationSeconds *int64 `min:"900" type:"integer"`
+
+ // The identification number of the MFA device that is associated with the IAM
+ // user who is making the GetSessionToken call. Specify this value if the IAM
+ // user has a policy that requires MFA authentication. The value is either the
+ // serial number for a hardware device (such as GAHT12345678) or an Amazon Resource
+ // Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
+ // You can find the device for an IAM user by going to the AWS Management Console
+ // and viewing the user's security credentials.
+ SerialNumber *string `min:"9" type:"string"`
+
+ // The value provided by the MFA device, if MFA is required. If any policy requires
+ // the IAM user to submit an MFA code, specify this value. If MFA authentication
+ // is required, and the user does not provide a code when requesting a set of
+ // temporary security credentials, the user will receive an "access denied"
+ // response when requesting resources that require MFA authentication.
+ TokenCode *string `min:"6" type:"string"`
+
+ metadataGetSessionTokenInput `json:"-" xml:"-"`
+}
+
+type metadataGetSessionTokenInput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetSessionTokenInput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetSessionTokenInput) GoString() string {
+ return s.String()
+}
+
+// Contains the response to a successful GetSessionToken request, including
+// temporary AWS credentials that can be used to make AWS requests.
+type GetSessionTokenOutput struct {
+ // The session credentials for API authentication.
+ Credentials *Credentials `type:"structure"`
+
+ metadataGetSessionTokenOutput `json:"-" xml:"-"`
+}
+
+type metadataGetSessionTokenOutput struct {
+ SDKShapeTraits bool `type:"structure"`
+}
+
+// String returns the string representation
+func (s GetSessionTokenOutput) String() string {
+ return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation
+func (s GetSessionTokenOutput) GoString() string {
+ return s.String()
+}
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations.go
new file mode 100644
index 00000000000..4010cc7fa14
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations.go
@@ -0,0 +1,12 @@
+package sts
+
+import "github.com/aws/aws-sdk-go/aws/request"
+
+func init() {
+ initRequest = func(r *request.Request) {
+ switch r.Operation.Name {
+ case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity:
+ r.Handlers.Sign.Clear() // these operations are unsigned
+ }
+ }
+}
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations_test.go
new file mode 100644
index 00000000000..6f870d35e27
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/customizations_test.go
@@ -0,0 +1,39 @@
+package sts_test
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/awstesting/unit"
+ "github.com/aws/aws-sdk-go/service/sts"
+)
+
+var svc = sts.New(unit.Session, &aws.Config{
+ Region: aws.String("mock-region"),
+})
+
+func TestUnsignedRequest_AssumeRoleWithSAML(t *testing.T) {
+ req, _ := svc.AssumeRoleWithSAMLRequest(&sts.AssumeRoleWithSAMLInput{
+ PrincipalArn: aws.String("ARN01234567890123456789"),
+ RoleArn: aws.String("ARN01234567890123456789"),
+ SAMLAssertion: aws.String("ASSERT"),
+ })
+
+ err := req.Sign()
+ assert.NoError(t, err)
+ assert.Equal(t, "", req.HTTPRequest.Header.Get("Authorization"))
+}
+
+func TestUnsignedRequest_AssumeRoleWithWebIdentity(t *testing.T) {
+ req, _ := svc.AssumeRoleWithWebIdentityRequest(&sts.AssumeRoleWithWebIdentityInput{
+ RoleArn: aws.String("ARN01234567890123456789"),
+ RoleSessionName: aws.String("SESSION"),
+ WebIdentityToken: aws.String("TOKEN"),
+ })
+
+ err := req.Sign()
+ assert.NoError(t, err)
+ assert.Equal(t, "", req.HTTPRequest.Header.Get("Authorization"))
+}
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/examples_test.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/examples_test.go
new file mode 100644
index 00000000000..083bcbd6877
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/examples_test.go
@@ -0,0 +1,149 @@
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
+
+package sts_test
+
+import (
+ "bytes"
+ "fmt"
+ "time"
+
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/session"
+ "github.com/aws/aws-sdk-go/service/sts"
+)
+
+var _ time.Duration
+var _ bytes.Buffer
+
+func ExampleSTS_AssumeRole() {
+ svc := sts.New(session.New())
+
+ params := &sts.AssumeRoleInput{
+ RoleArn: aws.String("arnType"), // Required
+ RoleSessionName: aws.String("roleSessionNameType"), // Required
+ DurationSeconds: aws.Int64(1),
+ ExternalId: aws.String("externalIdType"),
+ Policy: aws.String("sessionPolicyDocumentType"),
+ SerialNumber: aws.String("serialNumberType"),
+ TokenCode: aws.String("tokenCodeType"),
+ }
+ resp, err := svc.AssumeRole(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
+
+func ExampleSTS_AssumeRoleWithSAML() {
+ svc := sts.New(session.New())
+
+ params := &sts.AssumeRoleWithSAMLInput{
+ PrincipalArn: aws.String("arnType"), // Required
+ RoleArn: aws.String("arnType"), // Required
+ SAMLAssertion: aws.String("SAMLAssertionType"), // Required
+ DurationSeconds: aws.Int64(1),
+ Policy: aws.String("sessionPolicyDocumentType"),
+ }
+ resp, err := svc.AssumeRoleWithSAML(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
+
+func ExampleSTS_AssumeRoleWithWebIdentity() {
+ svc := sts.New(session.New())
+
+ params := &sts.AssumeRoleWithWebIdentityInput{
+ RoleArn: aws.String("arnType"), // Required
+ RoleSessionName: aws.String("roleSessionNameType"), // Required
+ WebIdentityToken: aws.String("clientTokenType"), // Required
+ DurationSeconds: aws.Int64(1),
+ Policy: aws.String("sessionPolicyDocumentType"),
+ ProviderId: aws.String("urlType"),
+ }
+ resp, err := svc.AssumeRoleWithWebIdentity(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
+
+func ExampleSTS_DecodeAuthorizationMessage() {
+ svc := sts.New(session.New())
+
+ params := &sts.DecodeAuthorizationMessageInput{
+ EncodedMessage: aws.String("encodedMessageType"), // Required
+ }
+ resp, err := svc.DecodeAuthorizationMessage(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
+
+func ExampleSTS_GetFederationToken() {
+ svc := sts.New(session.New())
+
+ params := &sts.GetFederationTokenInput{
+ Name: aws.String("userNameType"), // Required
+ DurationSeconds: aws.Int64(1),
+ Policy: aws.String("sessionPolicyDocumentType"),
+ }
+ resp, err := svc.GetFederationToken(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
+
+func ExampleSTS_GetSessionToken() {
+ svc := sts.New(session.New())
+
+ params := &sts.GetSessionTokenInput{
+ DurationSeconds: aws.Int64(1),
+ SerialNumber: aws.String("serialNumberType"),
+ TokenCode: aws.String("tokenCodeType"),
+ }
+ resp, err := svc.GetSessionToken(params)
+
+ if err != nil {
+ // Print the error, cast err to awserr.Error to get the Code and
+ // Message from an error.
+ fmt.Println(err.Error())
+ return
+ }
+
+ // Pretty-print the response data.
+ fmt.Println(resp)
+}
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/service.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/service.go
new file mode 100644
index 00000000000..33f49001fa1
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/service.go
@@ -0,0 +1,130 @@
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
+
+package sts
+
+import (
+ "github.com/aws/aws-sdk-go/aws"
+ "github.com/aws/aws-sdk-go/aws/client"
+ "github.com/aws/aws-sdk-go/aws/client/metadata"
+ "github.com/aws/aws-sdk-go/aws/request"
+ "github.com/aws/aws-sdk-go/private/protocol/query"
+ "github.com/aws/aws-sdk-go/private/signer/v4"
+)
+
+// The AWS Security Token Service (STS) is a web service that enables you to
+// request temporary, limited-privilege credentials for AWS Identity and Access
+// Management (IAM) users or for users that you authenticate (federated users).
+// This guide provides descriptions of the STS API. For more detailed information
+// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
+//
+// As an alternative to using the API, you can use one of the AWS SDKs, which
+// consist of libraries and sample code for various programming languages and
+// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient
+// way to create programmatic access to STS. For example, the SDKs take care
+// of cryptographically signing requests, managing errors, and retrying requests
+// automatically. For information about the AWS SDKs, including how to download
+// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/).
+// For information about setting up signatures and authorization through the
+// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html"
+// target="_blank) in the AWS General Reference. For general information about
+// the Query API, go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html"
+// target="_blank) in Using IAM. For information about using security tokens
+// with other AWS products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
+// in the Using IAM.
+//
+// If you're new to AWS and need additional technical information about a specific
+// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/
+// (http://aws.amazon.com/documentation/" target="_blank).
+//
+// Endpoints
+//
+// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com
+// that maps to the US East (N. Virginia) region. Additional regions are available,
+// but must first be activated in the AWS Management Console before you can
+// use a different region's endpoint. For more information about activating
+// a region for STS see Activating STS in a New Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
+// in the Using IAM.
+//
+// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region)
+// in the AWS General Reference.
+//
+// Recording API requests
+//
+// STS supports AWS CloudTrail, which is a service that records AWS calls for
+// your AWS account and delivers log files to an Amazon S3 bucket. By using
+// information collected by CloudTrail, you can determine what requests were
+// successfully made to STS, who made the request, when it was made, and so
+// on. To learn more about CloudTrail, including how to turn it on and find
+// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
+//The service client's operations are safe to be used concurrently.
+// It is not safe to mutate any of the client's properties though.
+type STS struct {
+ *client.Client
+}
+
+// Used for custom client initialization logic
+var initClient func(*client.Client)
+
+// Used for custom request initialization logic
+var initRequest func(*request.Request)
+
+// A ServiceName is the name of the service the client will make API calls to.
+const ServiceName = "sts"
+
+// New creates a new instance of the STS client with a session.
+// If additional configuration is needed for the client instance use the optional
+// aws.Config parameter to add your extra config.
+//
+// Example:
+// // Create a STS client from just a session.
+// svc := sts.New(mySession)
+//
+// // Create a STS client with additional configuration
+// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS {
+ c := p.ClientConfig(ServiceName, cfgs...)
+ return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
+}
+
+// newClient creates, initializes and returns a new service client instance.
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *STS {
+ svc := &STS{
+ Client: client.New(
+ cfg,
+ metadata.ClientInfo{
+ ServiceName: ServiceName,
+ SigningRegion: signingRegion,
+ Endpoint: endpoint,
+ APIVersion: "2011-06-15",
+ },
+ handlers,
+ ),
+ }
+
+ // Handlers
+ svc.Handlers.Sign.PushBack(v4.Sign)
+ svc.Handlers.Build.PushBack(query.Build)
+ svc.Handlers.Unmarshal.PushBack(query.Unmarshal)
+ svc.Handlers.UnmarshalMeta.PushBack(query.UnmarshalMeta)
+ svc.Handlers.UnmarshalError.PushBack(query.UnmarshalError)
+
+ // Run custom client initialization if present
+ if initClient != nil {
+ initClient(svc.Client)
+ }
+
+ return svc
+}
+
+// newRequest creates a new request for a STS operation and runs any
+// custom request initialization.
+func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request {
+ req := c.NewRequest(op, params, data)
+
+ // Run custom request initialization if present
+ if initRequest != nil {
+ initRequest(req)
+ }
+
+ return req
+}
diff --git a/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
new file mode 100644
index 00000000000..09dae0c9dc3
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
@@ -0,0 +1,38 @@
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
+
+// Package stsiface provides an interface for the AWS Security Token Service.
+package stsiface
+
+import (
+ "github.com/aws/aws-sdk-go/aws/request"
+ "github.com/aws/aws-sdk-go/service/sts"
+)
+
+// STSAPI is the interface type for sts.STS.
+type STSAPI interface {
+ AssumeRoleRequest(*sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput)
+
+ AssumeRole(*sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
+
+ AssumeRoleWithSAMLRequest(*sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput)
+
+ AssumeRoleWithSAML(*sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error)
+
+ AssumeRoleWithWebIdentityRequest(*sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput)
+
+ AssumeRoleWithWebIdentity(*sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error)
+
+ DecodeAuthorizationMessageRequest(*sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput)
+
+ DecodeAuthorizationMessage(*sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
+
+ GetFederationTokenRequest(*sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput)
+
+ GetFederationToken(*sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error)
+
+ GetSessionTokenRequest(*sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput)
+
+ GetSessionToken(*sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error)
+}
+
+var _ STSAPI = (*sts.STS)(nil)
diff --git a/README.md b/README.md
index e678e48a14d..6dbfc5388c2 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Graphite, Elasticsearch, OpenTSDB, Prometheus and InfluxDB.
- [What's New in Grafana 2.0](http://docs.grafana.org/guides/whats-new-in-v2/)
- [What's New in Grafana 2.1](http://docs.grafana.org/guides/whats-new-in-v2-1/)
- [What's New in Grafana 2.5](http://docs.grafana.org/guides/whats-new-in-v2-5/)
+- [What's New in Grafana 3.0](http://docs.grafana.org/guides/whats-new-in-v3/)
## Features
### Graphite Target Editor
@@ -78,7 +79,7 @@ the latest master builds [here](http://grafana.org/download/builds)
### Dependencies
- Go 1.5
-- NodeJS v0.12.0
+- NodeJS v4+
- [Godep](https://github.com/tools/godep)
### Get Code
@@ -109,7 +110,7 @@ go run build.go build
### Building frontend assets
-To build less to css for the frontend you will need a recent version of of **node (v0.12.0)**,
+To build less to css for the frontend you will need a recent version of of **node (v4+)**,
npm (v2.5.0) and grunt (v0.4.5). Run the following:
```bash
diff --git a/build.go b/build.go
index e1fc3599aa8..4347c486063 100644
--- a/build.go
+++ b/build.go
@@ -132,12 +132,10 @@ func readVersionFromPackageJson() {
if len(parts) > 1 {
linuxPackageVersion = parts[0]
linuxPackageIteration = parts[1]
- if linuxPackageIteration != "" {
- // add timestamp to iteration
- linuxPackageIteration = fmt.Sprintf("%s%v", linuxPackageIteration, time.Now().Unix())
- }
- log.Println(fmt.Sprintf("Iteration %v", linuxPackageIteration))
}
+
+ // add timestamp to iteration
+ linuxPackageIteration = fmt.Sprintf("%d%s", time.Now().Unix(), linuxPackageIteration)
}
type linuxPackageOptions struct {
diff --git a/conf/defaults.ini b/conf/defaults.ini
index f78287619a3..0a4b61fbe78 100644
--- a/conf/defaults.ini
+++ b/conf/defaults.ini
@@ -172,6 +172,9 @@ verify_email_enabled = false
# Background text for the user field on the login page
login_hint = email or username
+# Default UI theme ("dark" or "light")
+default_theme = dark
+
#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
diff --git a/conf/sample.ini b/conf/sample.ini
index 6a26589d40d..7f358b07199 100644
--- a/conf/sample.ini
+++ b/conf/sample.ini
@@ -155,6 +155,9 @@ check_for_updates = true
# Background text for the user field on the login page
;login_hint = email or username
+# Default UI theme ("dark" or "light")
+;default_theme = dark
+
#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
diff --git a/docker/blocks/graphite/fig b/docker/blocks/graphite/fig
index 84da45341e1..60acb8c1131 100644
--- a/docker/blocks/graphite/fig
+++ b/docker/blocks/graphite/fig
@@ -8,3 +8,10 @@ graphite:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
+fake-graphite-data:
+ image: grafana/fake-data-gen
+ net: bridge
+ environment:
+ FD_DATASOURCE: graphite
+ FD_PORT: 2003
+
diff --git a/docker/blocks/influxdb/fig b/docker/blocks/influxdb/fig
index c537a74b003..bdb4a274634 100644
--- a/docker/blocks/influxdb/fig
+++ b/docker/blocks/influxdb/fig
@@ -4,3 +4,11 @@ influxdb:
- "2004:2004"
- "8083:8083"
- "8086:8086"
+
+fake-influxdb-data:
+ image: grafana/fake-data-gen
+ net: bridge
+ environment:
+ FD_DATASOURCE: influxdb
+ FD_PORT: 8086
+
diff --git a/docker/blocks/opentsdb/fig b/docker/blocks/opentsdb/fig
index 34bbf4b854c..c346475e9a3 100644
--- a/docker/blocks/opentsdb/fig
+++ b/docker/blocks/opentsdb/fig
@@ -2,4 +2,10 @@ opentsdb:
image: opower/opentsdb:latest
ports:
- "4242:4242"
-
+
+fake-opentsdb-data:
+ image: grafana/fake-data-gen
+ net: bridge
+ environment:
+ FD_DATASOURCE: opentsdb
+
diff --git a/docker/blocks/prometheus/fig b/docker/blocks/prometheus/fig
index 0880902c9fd..ecfcf395d26 100644
--- a/docker/blocks/prometheus/fig
+++ b/docker/blocks/prometheus/fig
@@ -1,6 +1,16 @@
prometheus:
build: blocks/prometheus
+ net: bridge
ports:
- "9090:9090"
volumes:
- /var/docker/prometheus:/prometheus-data
+
+fake-prometheus-data:
+ image: grafana/fake-data-gen
+ net: bridge
+ ports:
+ - "9091:9091"
+ environment:
+ FD_DATASOURCE: prom
+
diff --git a/docs/sources/datasources/cloudwatch.md b/docs/sources/datasources/cloudwatch.md
index c69d3579784..a3b6a3ba61f 100644
--- a/docs/sources/datasources/cloudwatch.md
+++ b/docs/sources/datasources/cloudwatch.md
@@ -26,6 +26,8 @@ Name | The data source name, important that this is the same as in Grafana v1.x
Default | Default data source means that it will be pre-selected for new panels.
Credentials profile name | Specify the name of the profile to use (if you use `~/aws/credentials` file), leave blank for default. This option was introduced in Grafana 2.5.1
Default Region | Used in query editor to set region (can be changed on per query basis)
+Custom Metrics namespace | Specify the CloudWatch namespace of Custom metrics
+Assume Role Arn | Specify the ARN of the role to assume
## Authentication
diff --git a/docs/sources/datasources/opentsdb.md b/docs/sources/datasources/opentsdb.md
index 28d90c19b00..6ef930c0cc0 100644
--- a/docs/sources/datasources/opentsdb.md
+++ b/docs/sources/datasources/opentsdb.md
@@ -7,10 +7,10 @@ page_keywords: grafana, opentsdb, documentation
# OpenTSDB Guide
The newest release of Grafana adds additional functionality when using an OpenTSDB Data source.
-
+
-1. Open the side menu by clicking the the Grafana icon in the top header.
-2. In the side menu under the `Dashboards` link you should find a link named `Data Sources`.
+1. Open the side menu by clicking the the Grafana icon in the top header.
+2. In the side menu under the `Dashboards` link you should find a link named `Data Sources`.
> NOTE: If this link is missing in the side menu it means that your current user does not have the `Admin` role for the current organization.
diff --git a/docs/sources/guides/whats-new-in-v3.md b/docs/sources/guides/whats-new-in-v3.md
index eb1030f8f31..051691e0384 100644
--- a/docs/sources/guides/whats-new-in-v3.md
+++ b/docs/sources/guides/whats-new-in-v3.md
@@ -39,12 +39,13 @@ entire experience right within Grafana.
-A preview of [Grafana.net](http://grafana.net) is launching along with this release. We
-think it’s the perfect compliment to Grafana.
+[Grafana.net](https://grafana.net)Â offers a central repository where the community can come together to discover, create and
+share plugins (data sources, panels, apps) and dashboards.
-Grafana.net currently offers a central repository where the community
-can come together to discover and share plugins (Data Sources, Panels,
-Apps) and Dashboards for Grafana 3.0 and above.
+We are also working on a hosted Graphite-compatible data source that will be optimized for use with Grafana.
+It’ll be easy to combine your existing data source(s) with this OpenSaaS option. Finally, Grafana.net can
+also be a hub to manage all your Grafana instances. You’ll be able to monitor their health and availability,
+perform dashboard backups, and more.
We are also working on a hosted Graphite-compatible Data Source that
will be optimized for use with Grafana. It’ll be easy to combine your
@@ -65,7 +66,6 @@ Grafana 3.0 comes with a new command line tool called grafana-cli. You
can easily install plugins from Grafana.net with it. For
example:
-
```
grafana-cli install grafana-pie-chart-panel
```
@@ -188,6 +188,33 @@ you can still install manually from [Grafana.net](http://grafana.net)
* KairosDB: This data source has also no longer shipped with Grafana,
you can install it manually from [Grafana.net](http://grafana.net)
+## Plugin showcase
+
+Discovering and installing plugins is very quick and easy with Grafana 3.0 and [Grafana.net](https://grafana.net). Here
+are a couple that I incurage you try!
+
+#### [Clock Panel](https://grafana.net/plugins/grafana-clock-panel)
+Support's both current time and count down mode.
+
+
+#### [Pie Chart Panel](https://grafana.net/plugins/grafana-piechart-panel)
+A simple pie chart panel is now available as an external plugin.
+
+
+#### [WorldPing App](https://grafana.net/plugins/raintank-worldping-app)
+This is full blown Grafana App that adds new panels, data sources and pages to give
+feature rich global performance monitoring directly from your on-prem Grafana.
+
+
+
+#### [Zabbix App](https://grafana.net/plugins/alexanderzobnin-zabbix-app)
+This app contains the already very pouplar Zabbix data source plugin, 2 dashboards and a triggers panel. It is
+created and maintained by [Alexander Zobnin](https://github.com/alexanderzobnin/grafana-zabbix).
+
+
+
+Checkout the full list of plugins on [Grafana.net](https://grafana.net/plugins)
+
## CHANGELOG
For a detailed list and link to github issues for everything included
diff --git a/docs/sources/http_api/overview.md b/docs/sources/http_api/overview.md
index 8e7e2d60ad3..7f5a3ecfac8 100644
--- a/docs/sources/http_api/overview.md
+++ b/docs/sources/http_api/overview.md
@@ -18,4 +18,5 @@ dashboards, creating users and updating data sources.
* [User API](/http_api/user/)
* [Admin API](/http_api/admin/)
* [Snapshot API](/http_api/snapshot/)
+* [Preferences API](/http_api/preferences/)
* [Other API](/http_api/other/)
diff --git a/docs/sources/http_api/preferences.md b/docs/sources/http_api/preferences.md
new file mode 100644
index 00000000000..6bb00ed8132
--- /dev/null
+++ b/docs/sources/http_api/preferences.md
@@ -0,0 +1,100 @@
+----
+page_title: Preferences API
+page_description: Grafana Preferences API Reference
+page_keywords: grafana, preferences, http, api, documentation
+---
+
+# User and Org Preferences API
+
+Keys:
+
+- **theme** - One of: ``light``, ``dark``, or an empty string for the default theme
+- **homeDashboardId** - The numerical ``:id`` of a favorited dashboard, default: ``0``
+- **timezone** - One of: ``utc``, ``browser``, or an empty string for the default
+
+Omitting a key will cause the current value to be replaced with the
+system default value.
+
+## Get Current User Prefs
+
+`GET /api/user/preferences`
+
+**Example Request**:
+
+ GET /api/user/preferences HTTP/1.1
+ Accept: application/json
+ Content-Type: application/json
+ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+**Example Response**:
+
+ HTTP/1.1 200
+ Content-Type: application/json
+
+ {"theme":"","homeDashboardId":0,"timezone":""}
+
+## Update Current User Prefs
+
+`PUT /api/user/preferences`
+
+**Example Request**:
+
+ PUT /api/user/preferences HTTP/1.1
+ Accept: application/json
+ Content-Type: application/json
+ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+ {
+ "theme": "",
+ "homeDashboardId":0,
+ "timezone":"utc"
+ }
+
+**Example Response**:
+
+ HTTP/1.1 200
+ Content-Type: text/plain; charset=utf-8
+
+ {"message":"Preferences updated"}
+
+## Get Current Org Prefs
+
+`GET /api/org/preferences`
+
+**Example Request**:
+
+ GET /api/org/preferences HTTP/1.1
+ Accept: application/json
+ Content-Type: application/json
+ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+**Example Response**:
+
+ HTTP/1.1 200
+ Content-Type: application/json
+
+ {"theme":"","homeDashboardId":0,"timezone":""}
+
+## Update Current Org Prefs
+
+`PUT /api/org/preferences`
+
+**Example Request**:
+
+ PUT /api/org/preferences HTTP/1.1
+ Accept: application/json
+ Content-Type: application/json
+ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+ {
+ "theme": "",
+ "homeDashboardId":0,
+ "timezone":"utc"
+ }
+
+**Example Response**:
+
+ HTTP/1.1 200
+ Content-Type: text/plain; charset=utf-8
+
+ {"message":"Preferences updated"}
diff --git a/docs/sources/installation/debian.md b/docs/sources/installation/debian.md
index cac6a7c92b8..1b3957fa684 100644
--- a/docs/sources/installation/debian.md
+++ b/docs/sources/installation/debian.md
@@ -10,20 +10,13 @@ page_keywords: grafana, installation, debian, ubuntu, guide
Description | Download
------------ | -------------
-Stable .deb for Debian-based Linux | [grafana_2.6.0_amd64.deb](https://grafanarel.s3.amazonaws.com/builds/grafana_2.6.0_amd64.deb)
-Beta .deb for Debian-based Linux | [grafana_3.0.0-beta71462173753_amd64.deb](https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.0-beta71462173753_amd64.deb)
+Stable .deb for Debian-based Linux | [grafana_3.0.2-1463383025_amd64.deb](https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.2-1463383025_amd64.deb)
## Install Stable
- $ wget https://grafanarel.s3.amazonaws.com/builds/grafana_2.6.0_amd64.deb
+ $ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.2-1463383025_amd64.deb
$ sudo apt-get install -y adduser libfontconfig
- $ sudo dpkg -i grafana_2.6.0_amd64.deb
-
-## Install 3.0 Beta
-
- $ wget https://grafanarel.s3.amazonaws.com/builds/grafana_3.0.0-beta71462173753_amd64.deb
- $ sudo apt-get install -y adduser libfontconfig
- $ sudo dpkg -i grafana_3.0.0-beta71462173753_amd64.deb
+ $ sudo dpkg -i grafana_3.0.2-1463383025_amd64.deb
## APT Repository
diff --git a/docs/sources/installation/mac.md b/docs/sources/installation/mac.md
index 7246033b640..e65c2823666 100644
--- a/docs/sources/installation/mac.md
+++ b/docs/sources/installation/mac.md
@@ -6,8 +6,33 @@ page_keywords: grafana, installation, mac, osx, guide
# Installing on Mac
-There is currently no binary build for Mac, but Grafana will happily build on Mac. Read the [build from
-source](/project/building_from_source) page for instructions on how to
-build it yourself.
+Installation can be done using [homebrew](http://brew.sh/)
+
+Install latest stable:
+
+```
+brew install grafana/grafana/grafana
+```
+
+To start grafana look at the command printed after the homebrew install completes.
+
+You can also add the grafana as tap.
+
+```
+brew tap grafana/grafana
+brew install grafana
+```
+
+Install latest unstable from master:
+
+```
+brew install --HEAD grafana/grafana/grafana
+```
+
+To upgrade use the reinstall command
+
+```
+brew reinstall --HEAD grafana/grafana/grafana
+```
diff --git a/docs/sources/installation/rpm.md b/docs/sources/installation/rpm.md
index 744cafe93db..af3ae7f8288 100644
--- a/docs/sources/installation/rpm.md
+++ b/docs/sources/installation/rpm.md
@@ -10,43 +10,24 @@ page_keywords: grafana, installation, centos, fedora, opensuse, redhat, guide
Description | Download
------------ | -------------
-Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [grafana-2.6.0-1.x86_64.rpm](https://grafanarel.s3.amazonaws.com/builds/grafana-2.6.0-1.x86_64.rpm)
-Beta .RPM for CentOS / Fedor / OpenSuse / Redhat Linux | [grafana-3.0.0-beta71462173753.x86_64.rpm](https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.0-beta71462173753.x86_64.rpm)
+Stable .RPM for CentOS / Fedora / OpenSuse / Redhat Linux | [grafana-3.0.2-1463383025.x86_64.rpm](https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.2-1463383025.x86_64.rpm)
## Install Stable Release from package file
You can install Grafana using Yum directly.
- $ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-2.6.0-1.x86_64.rpm
+ $ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.2-1463383025.x86_64.rpm
Or install manually using `rpm`.
#### On CentOS / Fedora / Redhat:
$ sudo yum install initscripts fontconfig
- $ sudo rpm -Uvh grafana-2.6.0-1.x86_64.rpm
+ $ sudo rpm -Uvh grafana-3.0.2-1463383025.x86_64.rpm
#### On OpenSuse:
- $ sudo rpm -i --nodeps grafana-2.6.0-1.x86_64.rpm
-
-## Install Beta Release from package file
-
-You can install Grafana using Yum directly.
-
- $ sudo yum install https://grafanarel.s3.amazonaws.com/builds/grafana-3.0.0-beta71462173753.x86_64.rpm
-
-Or install manually using `rpm`.
-
-#### On CentOS / Fedora / Redhat:
-
- $ sudo yum install initscripts fontconfig
- $ sudo rpm -Uvh grafana-3.0.0-beta71462173753.x86_64.rpm
-
-#### On OpenSuse:
-
- $ sudo rpm -i --nodeps grafana-3.0.0-beta71462173753.x86_64.rpm
-
+ $ sudo rpm -i --nodeps grafana-3.0.2-1463383025.x86_64.rpm
## Install via YUM Repository
diff --git a/docs/sources/installation/windows.md b/docs/sources/installation/windows.md
index 1d6c5fc76cd..baa13d0350c 100644
--- a/docs/sources/installation/windows.md
+++ b/docs/sources/installation/windows.md
@@ -10,7 +10,7 @@ page_keywords: grafana, installation, windows guide
Description | Download
------------ | -------------
-Stable Zip package for Windows | [grafana.2.6.0.windows-x64.zip](https://grafanarel.s3.amazonaws.com/winbuilds/dist/grafana-2.5.0.windows-x64.zip)
+Stable Zip package for Windows | [grafana.3.0.2.windows-x64.zip](https://grafanarel.s3.amazonaws.com/winbuilds/dist/grafana-3.0.2.windows-x64.zip)
## Configure
diff --git a/karma.conf.js b/karma.conf.js
index c803dda5eae..cdcea23a90b 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -26,7 +26,7 @@ module.exports = function(config) {
browsers: ['PhantomJS'],
captureTimeout: 20000,
singleRun: true,
- autoWatchBatchDelay: 10000,
+ autoWatchBatchDelay: 1000,
browserNoActivityTimeout: 60000,
});
diff --git a/latest.json b/latest.json
index 8ddb446ec44..443a440a529 100644
--- a/latest.json
+++ b/latest.json
@@ -1,4 +1,4 @@
{
- "stable": "2.6.0",
- "testing": "3.0.0-beta7"
+ "stable": "3.0.2",
+ "testing": "3.0.2"
}
diff --git a/package.json b/package.json
index 8b9ec906ed9..9dbff96c2b8 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"company": "Coding Instinct AB"
},
"name": "grafana",
- "version": "3.0.0-beta7",
+ "version": "3.1.0",
"repository": {
"type": "git",
"url": "http://github.com/grafana/grafana.git"
@@ -13,7 +13,7 @@
"zone.js": "^0.6.6",
"autoprefixer": "^6.3.3",
"es6-promise": "^3.0.2",
- "es6-shim": "^0.35.0",
+ "es6-shim": "^0.35.1",
"expect.js": "~0.2.0",
"glob": "~3.2.7",
"grunt": "~0.4.0",
diff --git a/packaging/publish/publish.sh b/packaging/publish/publish.sh
index 79303707231..79da73d441a 100755
--- a/packaging/publish/publish.sh
+++ b/packaging/publish/publish.sh
@@ -1,7 +1,7 @@
#! /usr/bin/env bash
-deb_ver=3.0.0-beta51460725904
-rpm_ver=3.0.0-beta51460725904
+deb_ver=3.0.1
+rpm_ver=3.0.1-1
#rpm_ver=3.0.0-1
@@ -16,7 +16,7 @@ rpm_ver=3.0.0-beta51460725904
#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/testing/el/7 grafana-${rpm_ver}.x86_64.rpm
-# package_cloud push grafana/stable/el/7 grafana-${version}-1.x86_64.rpm
-# package_cloud push grafana/stable/el/6 grafana-${version}-1.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/cloudwatch.go b/pkg/api/cloudwatch/cloudwatch.go
index 88d22800d65..5b4449b5c02 100644
--- a/pkg/api/cloudwatch/cloudwatch.go
+++ b/pkg/api/cloudwatch/cloudwatch.go
@@ -4,6 +4,8 @@ import (
"encoding/json"
"errors"
"io/ioutil"
+ "strings"
+ "sync"
"time"
"github.com/aws/aws-sdk-go/aws"
@@ -14,6 +16,8 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/cloudwatch"
"github.com/aws/aws-sdk-go/service/ec2"
+ "github.com/aws/aws-sdk-go/service/sts"
+ "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
)
@@ -44,31 +48,96 @@ func init() {
}
}
-var awsCredentials map[string]*credentials.Credentials = make(map[string]*credentials.Credentials)
+type cache struct {
+ credential *credentials.Credentials
+ expiration *time.Time
+}
-func getCredentials(profile string) *credentials.Credentials {
- if _, ok := awsCredentials[profile]; ok {
- return awsCredentials[profile]
+var awsCredentialCache map[string]cache = make(map[string]cache)
+var credentialCacheLock sync.RWMutex
+
+func getCredentials(profile string, region string, assumeRoleArn string) *credentials.Credentials {
+ credentialCacheLock.RLock()
+ if _, ok := awsCredentialCache[profile]; ok {
+ if awsCredentialCache[profile].expiration != nil &&
+ (*awsCredentialCache[profile].expiration).After(time.Now().UTC()) {
+ result := awsCredentialCache[profile].credential
+ credentialCacheLock.RUnlock()
+ return result
+ }
+ }
+ credentialCacheLock.RUnlock()
+
+ accessKeyId := ""
+ secretAccessKey := ""
+ sessionToken := ""
+ var expiration *time.Time
+ expiration = nil
+ if strings.Index(assumeRoleArn, "arn:aws:iam:") == 0 {
+ params := &sts.AssumeRoleInput{
+ RoleArn: aws.String(assumeRoleArn),
+ RoleSessionName: aws.String("GrafanaSession"),
+ DurationSeconds: aws.Int64(900),
+ }
+
+ stsSess := session.New()
+ stsCreds := credentials.NewChainCredentials(
+ []credentials.Provider{
+ &credentials.EnvProvider{},
+ &credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
+ &ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(stsSess), ExpiryWindow: 5 * time.Minute},
+ })
+ stsConfig := &aws.Config{
+ Region: aws.String(region),
+ Credentials: stsCreds,
+ }
+ svc := sts.New(session.New(stsConfig), stsConfig)
+ resp, err := svc.AssumeRole(params)
+ if err != nil {
+ // ignore
+ log.Error(3, "CloudWatch: Failed to assume role", err)
+ }
+ if resp.Credentials != nil {
+ accessKeyId = *resp.Credentials.AccessKeyId
+ secretAccessKey = *resp.Credentials.SecretAccessKey
+ sessionToken = *resp.Credentials.SessionToken
+ expiration = resp.Credentials.Expiration
+ }
}
sess := session.New()
creds := credentials.NewChainCredentials(
[]credentials.Provider{
+ &credentials.StaticProvider{Value: credentials.Value{
+ AccessKeyID: accessKeyId,
+ SecretAccessKey: secretAccessKey,
+ SessionToken: sessionToken,
+ }},
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: profile},
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
})
- awsCredentials[profile] = creds
+ credentialCacheLock.Lock()
+ awsCredentialCache[profile] = cache{
+ credential: creds,
+ expiration: expiration,
+ }
+ credentialCacheLock.Unlock()
return creds
}
-func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
+func getAwsConfig(req *cwRequest) *aws.Config {
+ assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
cfg := &aws.Config{
Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
+ Credentials: getCredentials(req.DataSource.Database, req.Region, assumeRoleArn),
}
+ return cfg
+}
+func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
+ cfg := getAwsConfig(req)
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
@@ -104,11 +173,7 @@ func handleGetMetricStatistics(req *cwRequest, c *middleware.Context) {
}
func handleListMetrics(req *cwRequest, c *middleware.Context) {
- cfg := &aws.Config{
- Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
- }
-
+ cfg := getAwsConfig(req)
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
@@ -144,11 +209,7 @@ func handleListMetrics(req *cwRequest, c *middleware.Context) {
}
func handleDescribeAlarms(req *cwRequest, c *middleware.Context) {
- cfg := &aws.Config{
- Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
- }
-
+ cfg := getAwsConfig(req)
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
@@ -187,11 +248,7 @@ func handleDescribeAlarms(req *cwRequest, c *middleware.Context) {
}
func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
- cfg := &aws.Config{
- Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
- }
-
+ cfg := getAwsConfig(req)
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
@@ -227,11 +284,7 @@ func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
}
func handleDescribeAlarmHistory(req *cwRequest, c *middleware.Context) {
- cfg := &aws.Config{
- Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
- }
-
+ cfg := getAwsConfig(req)
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
@@ -263,11 +316,7 @@ func handleDescribeAlarmHistory(req *cwRequest, c *middleware.Context) {
}
func handleDescribeInstances(req *cwRequest, c *middleware.Context) {
- cfg := &aws.Config{
- Region: aws.String(req.Region),
- Credentials: getCredentials(req.DataSource.Database),
- }
-
+ cfg := getAwsConfig(req)
svc := ec2.New(session.New(cfg), cfg)
reqParam := &struct {
diff --git a/pkg/api/cloudwatch/metrics.go b/pkg/api/cloudwatch/metrics.go
index 7717ca27099..5bd318ea3c9 100644
--- a/pkg/api/cloudwatch/metrics.go
+++ b/pkg/api/cloudwatch/metrics.go
@@ -166,7 +166,8 @@ func handleGetMetrics(req *cwRequest, c *middleware.Context) {
}
} else {
var err error
- if namespaceMetrics, err = getMetricsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, getAllMetrics); err != nil {
+ assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
+ if namespaceMetrics, err = getMetricsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
}
@@ -199,7 +200,8 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
}
} else {
var err error
- if dimensionValues, err = getDimensionsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, getAllMetrics); err != nil {
+ assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
+ if dimensionValues, err = getDimensionsForCustomMetrics(req.Region, reqParam.Parameters.Namespace, req.DataSource.Database, assumeRoleArn, getAllMetrics); err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
}
@@ -214,10 +216,10 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
c.JSON(200, result)
}
-func getAllMetrics(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
+func getAllMetrics(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
cfg := &aws.Config{
Region: aws.String(region),
- Credentials: getCredentials(database),
+ Credentials: getCredentials(database, region, assumeRoleArn),
}
svc := cloudwatch.New(session.New(cfg), cfg)
@@ -244,8 +246,8 @@ func getAllMetrics(region string, namespace string, database string) (cloudwatch
var metricsCacheLock sync.Mutex
-func getMetricsForCustomMetrics(region string, namespace string, database string, getAllMetrics func(string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
- result, err := getAllMetrics(region, namespace, database)
+func getMetricsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
+ result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
if err != nil {
return []string{}, err
}
@@ -282,8 +284,8 @@ func getMetricsForCustomMetrics(region string, namespace string, database string
var dimensionsCacheLock sync.Mutex
-func getDimensionsForCustomMetrics(region string, namespace string, database string, getAllMetrics func(string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
- result, err := getAllMetrics(region, namespace, database)
+func getDimensionsForCustomMetrics(region string, namespace string, database string, assumeRoleArn string, getAllMetrics func(string, string, string, string) (cloudwatch.ListMetricsOutput, error)) ([]string, error) {
+ result, err := getAllMetrics(region, namespace, database, assumeRoleArn)
if err != nil {
return []string{}, err
}
diff --git a/pkg/api/cloudwatch/metrics_test.go b/pkg/api/cloudwatch/metrics_test.go
index ec39452e116..6dd68037613 100644
--- a/pkg/api/cloudwatch/metrics_test.go
+++ b/pkg/api/cloudwatch/metrics_test.go
@@ -14,7 +14,8 @@ func TestCloudWatchMetrics(t *testing.T) {
region := "us-east-1"
namespace := "Foo"
database := "default"
- f := func(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
+ assumeRoleArn := ""
+ f := func(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
return cloudwatch.ListMetricsOutput{
Metrics: []*cloudwatch.Metric{
{
@@ -28,7 +29,7 @@ func TestCloudWatchMetrics(t *testing.T) {
},
}, nil
}
- metrics, _ := getMetricsForCustomMetrics(region, namespace, database, f)
+ metrics, _ := getMetricsForCustomMetrics(region, namespace, database, assumeRoleArn, f)
Convey("Should contain Test_MetricName", func() {
So(metrics, ShouldContain, "Test_MetricName")
@@ -39,7 +40,8 @@ func TestCloudWatchMetrics(t *testing.T) {
region := "us-east-1"
namespace := "Foo"
database := "default"
- f := func(region string, namespace string, database string) (cloudwatch.ListMetricsOutput, error) {
+ assumeRoleArn := ""
+ f := func(region string, namespace string, database string, assumeRoleArn string) (cloudwatch.ListMetricsOutput, error) {
return cloudwatch.ListMetricsOutput{
Metrics: []*cloudwatch.Metric{
{
@@ -53,7 +55,7 @@ func TestCloudWatchMetrics(t *testing.T) {
},
}, nil
}
- dimensionKeys, _ := getDimensionsForCustomMetrics(region, namespace, database, f)
+ dimensionKeys, _ := getDimensionsForCustomMetrics(region, namespace, database, assumeRoleArn, f)
Convey("Should contain Test_DimensionName", func() {
So(dimensionKeys, ShouldContain, "Test_DimensionName")
diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go
index dd84f7827eb..9fcd5e567fb 100644
--- a/pkg/api/frontendsettings.go
+++ b/pkg/api/frontendsettings.go
@@ -142,6 +142,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
"buildstamp": setting.BuildStamp,
"latestVersion": plugins.GrafanaLatestVersion,
"hasUpdate": plugins.GrafanaHasUpdate,
+ "env": setting.Env,
},
}
diff --git a/pkg/cmd/grafana-cli/commands/upgrade_command.go b/pkg/cmd/grafana-cli/commands/upgrade_command.go
index b9ca834be6d..e788b3bdfaa 100644
--- a/pkg/cmd/grafana-cli/commands/upgrade_command.go
+++ b/pkg/cmd/grafana-cli/commands/upgrade_command.go
@@ -1,6 +1,8 @@
package commands
import (
+ "github.com/fatih/color"
+ "github.com/grafana/grafana/pkg/cmd/grafana-cli/log"
s "github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
)
@@ -14,20 +16,17 @@ func upgradeCommand(c CommandLine) error {
return err
}
- remotePlugins, err2 := s.ListAllPlugins(c.GlobalString("repo"))
+ v, err2 := s.GetPlugin(localPlugin.Id, c.GlobalString("repo"))
if err2 != nil {
return err2
}
- for _, v := range remotePlugins.Plugins {
- if localPlugin.Id == v.Id {
- if ShouldUpgrade(localPlugin.Info.Version, v) {
- s.RemoveInstalledPlugin(pluginsDir, pluginName)
- return InstallPlugin(localPlugin.Id, "", c)
- }
- }
+ if ShouldUpgrade(localPlugin.Info.Version, v) {
+ s.RemoveInstalledPlugin(pluginsDir, pluginName)
+ return InstallPlugin(localPlugin.Id, "", c)
}
+ log.Infof("%s %s is up to date \n", color.GreenString("âś”"), localPlugin.Id)
return nil
}
diff --git a/pkg/cmd/grafana-cli/services/services.go b/pkg/cmd/grafana-cli/services/services.go
index f0ad460842d..2332511ed89 100644
--- a/pkg/cmd/grafana-cli/services/services.go
+++ b/pkg/cmd/grafana-cli/services/services.go
@@ -44,7 +44,7 @@ func ReadPlugin(pluginDir, pluginName string) (m.InstalledPlugin, error) {
}
if res.Id == "" {
- return m.InstalledPlugin{}, errors.New("could not read find plugin " + pluginName)
+ return m.InstalledPlugin{}, errors.New("could not find plugin " + pluginName + " in " + pluginDir)
}
return res, nil
@@ -69,13 +69,21 @@ func RemoveInstalledPlugin(pluginPath, id string) error {
}
func GetPlugin(pluginId, repoUrl string) (m.Plugin, error) {
- resp, _ := ListAllPlugins(repoUrl)
+ fullUrl := repoUrl + "/repo/" + pluginId
- for _, i := range resp.Plugins {
- if i.Id == pluginId {
- return i, nil
- }
+ res, err := goreq.Request{Uri: fullUrl, MaxRedirects: 3}.Do()
+ if err != nil {
+ return m.Plugin{}, err
+ }
+ if res.StatusCode != 200 {
+ return m.Plugin{}, fmt.Errorf("Could not access %s statuscode %v", fullUrl, res.StatusCode)
}
- return m.Plugin{}, errors.New("could not find plugin named \"" + pluginId + "\"")
+ var resp m.Plugin
+ err = res.Body.FromJsonTo(&resp)
+ if err != nil {
+ return m.Plugin{}, errors.New("Could not load plugin data")
+ }
+
+ return resp, nil
}
diff --git a/pkg/plugins/queries.go b/pkg/plugins/queries.go
index b930c9575a3..5ae1825a88f 100644
--- a/pkg/plugins/queries.go
+++ b/pkg/plugins/queries.go
@@ -24,7 +24,16 @@ func GetPluginSettings(orgId int64) (map[string]*m.PluginSettingInfoDTO, error)
}
// default to enabled true
- opt := &m.PluginSettingInfoDTO{Enabled: true}
+ opt := &m.PluginSettingInfoDTO{
+ PluginId: pluginDef.Id,
+ OrgId: orgId,
+ Enabled: true,
+ }
+
+ // apps are disabled by default
+ if pluginDef.Type == PluginTypeApp {
+ opt.Enabled = false
+ }
// if it's included in app check app settings
if pluginDef.IncludedInAppId != "" {
diff --git a/pkg/plugins/update_checker.go b/pkg/plugins/update_checker.go
index 36169434096..ed43398357e 100644
--- a/pkg/plugins/update_checker.go
+++ b/pkg/plugins/update_checker.go
@@ -91,14 +91,14 @@ func checkForUpdates() {
resp2, err := client.Get("https://raw.githubusercontent.com/grafana/grafana/master/latest.json")
if err != nil {
- log.Trace("Failed to get lates.json repo from github: %v", err.Error())
+ log.Trace("Failed to get latest.json repo from github: %v", err.Error())
return
}
defer resp2.Body.Close()
body, err = ioutil.ReadAll(resp2.Body)
if err != nil {
- log.Trace("Update check failed, reading response from github.net, %v", err.Error())
+ log.Trace("Update check failed, reading response from github.com, %v", err.Error())
return
}
diff --git a/pkg/services/sqlstore/preferences.go b/pkg/services/sqlstore/preferences.go
index d120c485ed3..65609a9c57c 100644
--- a/pkg/services/sqlstore/preferences.go
+++ b/pkg/services/sqlstore/preferences.go
@@ -5,6 +5,8 @@ import (
"github.com/grafana/grafana/pkg/bus"
m "github.com/grafana/grafana/pkg/models"
+
+ "github.com/grafana/grafana/pkg/setting"
)
func init() {
@@ -26,7 +28,7 @@ func GetPreferencesWithDefaults(query *m.GetPreferencesWithDefaultsQuery) error
}
res := &m.Preferences{
- Theme: "dark",
+ Theme: setting.DefaultTheme,
Timezone: "browser",
HomeDashboardId: 0,
}
diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go
index 2d1bad945eb..413fb2fc9a0 100644
--- a/pkg/setting/setting.go
+++ b/pkg/setting/setting.go
@@ -88,6 +88,7 @@ var (
AutoAssignOrgRole string
VerifyEmailEnabled bool
LoginHint string
+ DefaultTheme string
// Http auth
AdminUser string
@@ -454,6 +455,7 @@ func NewConfigContext(args *CommandLineArgs) error {
AutoAssignOrgRole = users.Key("auto_assign_org_role").In("Editor", []string{"Editor", "Admin", "Read Only Editor", "Viewer"})
VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false)
LoginHint = users.Key("login_hint").String()
+ DefaultTheme = users.Key("default_theme").String()
// anonymous access
AnonymousEnabled = Cfg.Section("auth.anonymous").Key("enabled").MustBool(false)
@@ -526,6 +528,17 @@ var logLevels = map[string]int{
"Critical": 5,
}
+func getLogLevel(key string, defaultName string) (string, int) {
+ levelName := Cfg.Section(key).Key("level").In(defaultName, []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
+
+ level, ok := logLevels[levelName]
+ if !ok {
+ log.Fatal(4, "Unknown log level: %s", levelName)
+ }
+
+ return levelName, level
+}
+
func initLogging(args *CommandLineArgs) {
//close any existing log handlers.
log.Close()
@@ -533,8 +546,12 @@ func initLogging(args *CommandLineArgs) {
LogModes = strings.Split(Cfg.Section("log").Key("mode").MustString("console"), ",")
LogsPath = makeAbsolute(Cfg.Section("paths").Key("logs").String(), HomePath)
+ defaultLevelName, _ := getLogLevel("log", "Info")
+
LogConfigs = make([]util.DynMap, len(LogModes))
+
for i, mode := range LogModes {
+
mode = strings.TrimSpace(mode)
sec, err := Cfg.GetSection("log." + mode)
if err != nil {
@@ -542,12 +559,7 @@ func initLogging(args *CommandLineArgs) {
}
// Log level.
- levelName := Cfg.Section("log."+mode).Key("level").In("Trace",
- []string{"Trace", "Debug", "Info", "Warn", "Error", "Critical"})
- level, ok := logLevels[levelName]
- if !ok {
- log.Fatal(4, "Unknown log level: %s", levelName)
- }
+ _, level := getLogLevel("log."+mode, defaultLevelName)
// Generate log configuration.
switch mode {
diff --git a/public/app/app.ts b/public/app/app.ts
index 3434814d3b6..6de7181f5a1 100644
--- a/public/app/app.ts
+++ b/public/app/app.ts
@@ -42,7 +42,9 @@ export class GrafanaApp {
app.constant('grafanaVersion', "@grafanaVersion@");
app.config(($locationProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) => {
- //$compileProvider.debugInfoEnabled(false);
+ if (config.buildInfo.env !== 'development') {
+ $compileProvider.debugInfoEnabled(false);
+ }
this.registerFunctions.controller = $controllerProvider.register;
this.registerFunctions.directive = $compileProvider.directive;
diff --git a/public/app/core/utils/datemath.ts b/public/app/core/utils/datemath.ts
index b66325c71a8..467d3750c9a 100644
--- a/public/app/core/utils/datemath.ts
+++ b/public/app/core/utils/datemath.ts
@@ -28,7 +28,7 @@ export function parse(text, roundUp?) {
mathString = text.substring(index + 2);
}
// We're going to just require ISO8601 timestamps, k?
- time = moment(parseString);
+ time = moment(parseString, moment.ISO_8601);
}
if (!mathString.length) {
diff --git a/public/app/core/utils/kbn.js b/public/app/core/utils/kbn.js
index 11a544d2708..9d714c34fb3 100644
--- a/public/app/core/utils/kbn.js
+++ b/public/app/core/utils/kbn.js
@@ -396,6 +396,7 @@ function($, _) {
kbn.valueFormats.ev = kbn.formatBuilders.decimalSIPrefix('eV');
kbn.valueFormats.amp = kbn.formatBuilders.decimalSIPrefix('A');
kbn.valueFormats.volt = kbn.formatBuilders.decimalSIPrefix('V');
+ kbn.valueFormats.dBm = kbn.formatBuilders.decimalSIPrefix('dBm');
// Temperature
kbn.valueFormats.celsius = kbn.formatBuilders.fixedUnit('°C');
@@ -677,6 +678,7 @@ function($, _) {
{text: 'electron volt (eV)', value: 'ev' },
{text: 'Ampere (A)', value: 'amp' },
{text: 'Volt (V)', value: 'volt' },
+ {text: 'Decibel-milliwatt (dBm)', value: 'dBm' },
]
},
{
diff --git a/public/app/features/annotations/annotations_srv.js b/public/app/features/annotations/annotations_srv.js
index b0022135ef5..a693dd602c8 100644
--- a/public/app/features/annotations/annotations_srv.js
+++ b/public/app/features/annotations/annotations_srv.js
@@ -55,10 +55,11 @@ define([
}, this);
});
- promiseCached = $q.all(promises)
- .then(function() {
- return list;
- });
+ promiseCached = $q.all(promises).then(function() {
+ return list;
+ }).catch(function(err) {
+ $rootScope.appEvent('alert-error', ['Annotations failed', (err.message || err)]);
+ });
return promiseCached;
};
diff --git a/public/app/features/dashboard/dashboardSrv.js b/public/app/features/dashboard/dashboardSrv.js
index 2e1cd1acbf0..a4ae7b31468 100644
--- a/public/app/features/dashboard/dashboardSrv.js
+++ b/public/app/features/dashboard/dashboardSrv.js
@@ -65,7 +65,7 @@ function (angular, $, _, moment) {
// cleans meta data and other non peristent state
p.getSaveModelClone = function() {
- var copy = angular.copy(this);
+ var copy = $.extend(true, {}, this);
delete copy.meta;
return copy;
};
diff --git a/public/app/features/dashboard/dynamicDashboardSrv.js b/public/app/features/dashboard/dynamicDashboardSrv.js
index 9e369733f45..f131b47b557 100644
--- a/public/app/features/dashboard/dynamicDashboardSrv.js
+++ b/public/app/features/dashboard/dynamicDashboardSrv.js
@@ -52,6 +52,8 @@ function (angular, _) {
else if (panel.repeatPanelId && panel.repeatIteration !== this.iteration) {
row.panels = _.without(row.panels, panel);
j = j - 1;
+ } else if (row.repeat || row.repeatRowId) {
+ continue;
} else if (!_.isEmpty(panel.scopedVars) && panel.repeatIteration !== this.iteration) {
panel.scopedVars = {};
}
@@ -118,7 +120,6 @@ function (angular, _) {
panel = copy.panels[i];
panel.scopedVars = {};
panel.scopedVars[variable.name] = option;
- panel.repeatIteration = this.iteration;
}
}, this);
};
diff --git a/public/app/features/dashboard/timeSrv.js b/public/app/features/dashboard/timeSrv.js
index 13f5ad07bab..cd52155ff5f 100644
--- a/public/app/features/dashboard/timeSrv.js
+++ b/public/app/features/dashboard/timeSrv.js
@@ -50,7 +50,7 @@ define([
if (!isNaN(value)) {
var epoch = parseInt(value);
- return moment(epoch);
+ return moment.utc(epoch);
}
return null;
diff --git a/public/app/features/panel/metrics_ds_selector.ts b/public/app/features/panel/metrics_ds_selector.ts
index b281c43048b..c0e1b776062 100644
--- a/public/app/features/panel/metrics_ds_selector.ts
+++ b/public/app/features/panel/metrics_ds_selector.ts
@@ -10,7 +10,7 @@ var template = `