Просмотр исходного кода

Merge branch 'master' into cloudwatch

Torkel Ödegaard 10 лет назад
Родитель
Сommit
3ed63d09d9

+ 1 - 0
CHANGELOG.md

@@ -24,6 +24,7 @@ it allows you to add queries of differnet data source types & instances to the s
 - [Issue #2563](https://github.com/grafana/grafana/issues/2563). Annotations: Fixed issue when html sanitizer failes for title to annotation body, now fallbacks to html escaping title and text
 - [Issue #2563](https://github.com/grafana/grafana/issues/2563). Annotations: Fixed issue when html sanitizer failes for title to annotation body, now fallbacks to html escaping title and text
 - [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another atempt at fixing #2534 (Init multi value template var used in repeat panel from url)
 - [Issue #2564](https://github.com/grafana/grafana/issues/2564). Templating: Another atempt at fixing #2534 (Init multi value template var used in repeat panel from url)
 - [Issue #2620](https://github.com/grafana/grafana/issues/2620). Graph: multi series tooltip did no highlight correct point when stacking was enabled and series were of different resolution
 - [Issue #2620](https://github.com/grafana/grafana/issues/2620). Graph: multi series tooltip did no highlight correct point when stacking was enabled and series were of different resolution
+- [Issue #2636](https://github.com/grafana/grafana/issues/2636). InfluxDB: Do no show template vars in dropdown for tag keys and group by keys
 
 
 **Breaking Changes**
 **Breaking Changes**
 - Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that
 - Notice to makers/users of custom data sources, there is a minor breaking change in 2.2 that

+ 0 - 1
docs/mkdocs.yml

@@ -49,7 +49,6 @@ pages:
 - ['reference/graph.md', 'Reference', 'Graph Panel']
 - ['reference/graph.md', 'Reference', 'Graph Panel']
 - ['reference/singlestat.md', 'Reference', 'Singlestat Panel']
 - ['reference/singlestat.md', 'Reference', 'Singlestat Panel']
 - ['reference/dashlist.md', 'Reference', 'Dashboard List Panel']
 - ['reference/dashlist.md', 'Reference', 'Dashboard List Panel']
-- ['reference/text.md', 'Reference', 'Text Panel']
 - ['reference/sharing.md', 'Reference', 'Sharing']
 - ['reference/sharing.md', 'Reference', 'Sharing']
 - ['reference/annotations.md', 'Reference', 'Annotations']
 - ['reference/annotations.md', 'Reference', 'Annotations']
 - ['reference/timerange.md', 'Reference', 'Time Range Controls']
 - ['reference/timerange.md', 'Reference', 'Time Range Controls']

+ 1 - 1
docs/sources/datasources/influxdb.md

@@ -51,7 +51,7 @@ the tag key and select `--remove tag filter--`.
 
 
 ### Regex matching
 ### Regex matching
 You can type in regex patterns for metric names or tag filter values, be sure to wrap the regex pattern in forward slashes (`/`). Grafana
 You can type in regex patterns for metric names or tag filter values, be sure to wrap the regex pattern in forward slashes (`/`). Grafana
-will automaticallay adjust the filter tag condition to use the InfluxDB regex match condition operator (`=~`).
+will automatically adjust the filter tag condition to use the InfluxDB regex match condition operator (`=~`).
 
 
 ### Editor group by
 ### Editor group by
 To group by a tag click the plus icon after the `GROUP BY ($interval)` text. Pick a tag from the dropdown that appears.
 To group by a tag click the plus icon after the `GROUP BY ($interval)` text. Pick a tag from the dropdown that appears.

+ 5 - 4
pkg/api/org_invite.go

@@ -154,10 +154,11 @@ func CompleteInvite(c *middleware.Context, completeInvite dtos.CompleteInviteFor
 	}
 	}
 
 
 	cmd := m.CreateUserCommand{
 	cmd := m.CreateUserCommand{
-		Email:    completeInvite.Email,
-		Name:     completeInvite.Name,
-		Login:    completeInvite.Username,
-		Password: completeInvite.Password,
+		Email:        completeInvite.Email,
+		Name:         completeInvite.Name,
+		Login:        completeInvite.Username,
+		Password:     completeInvite.Password,
+		SkipOrgSetup: true,
 	}
 	}
 
 
 	if err := bus.Dispatch(&cmd); err != nil {
 	if err := bus.Dispatch(&cmd); err != nil {

+ 3 - 0
pkg/api/signup.go

@@ -65,6 +65,7 @@ func SignUpStep2(c *middleware.Context, form dtos.SignUpStep2Form) Response {
 		OrgName:  form.OrgName,
 		OrgName:  form.OrgName,
 	}
 	}
 
 
+	// verify email
 	if setting.VerifyEmailEnabled {
 	if setting.VerifyEmailEnabled {
 		if ok, rsp := verifyUserSignUpEmail(form.Email, form.Code); !ok {
 		if ok, rsp := verifyUserSignUpEmail(form.Email, form.Code); !ok {
 			return rsp
 			return rsp
@@ -72,11 +73,13 @@ func SignUpStep2(c *middleware.Context, form dtos.SignUpStep2Form) Response {
 		createUserCmd.EmailVerified = true
 		createUserCmd.EmailVerified = true
 	}
 	}
 
 
+	// check if user exists
 	existing := m.GetUserByLoginQuery{LoginOrEmail: form.Email}
 	existing := m.GetUserByLoginQuery{LoginOrEmail: form.Email}
 	if err := bus.Dispatch(&existing); err == nil {
 	if err := bus.Dispatch(&existing); err == nil {
 		return ApiError(401, "User with same email address already exists", nil)
 		return ApiError(401, "User with same email address already exists", nil)
 	}
 	}
 
 
+	// dispatch create command
 	if err := bus.Dispatch(&createUserCmd); err != nil {
 	if err := bus.Dispatch(&createUserCmd); err != nil {
 		return ApiError(500, "Failed to create user", err)
 		return ApiError(500, "Failed to create user", err)
 	}
 	}

+ 1 - 0
pkg/models/user.go

@@ -52,6 +52,7 @@ type CreateUserCommand struct {
 	Password      string
 	Password      string
 	EmailVerified bool
 	EmailVerified bool
 	IsAdmin       bool
 	IsAdmin       bool
+	SkipOrgSetup  bool
 
 
 	Result User
 	Result User
 }
 }

+ 1 - 1
pkg/services/notifications/notifications.go

@@ -153,7 +153,7 @@ func signUpCompletedHandler(evt *events.SignUpCompleted) error {
 
 
 	return sendEmailCommandHandler(&m.SendEmailCommand{
 	return sendEmailCommandHandler(&m.SendEmailCommand{
 		To:       []string{evt.Email},
 		To:       []string{evt.Email},
-		Template: tmplSignUpStarted,
+		Template: tmplWelcomeOnSignUp,
 		Data: map[string]interface{}{
 		Data: map[string]interface{}{
 			"Name": evt.Name,
 			"Name": evt.Name,
 		},
 		},

+ 24 - 17
pkg/services/sqlstore/user.go

@@ -30,6 +30,10 @@ func init() {
 }
 }
 
 
 func getOrgIdForNewUser(cmd *m.CreateUserCommand, sess *session) (int64, error) {
 func getOrgIdForNewUser(cmd *m.CreateUserCommand, sess *session) (int64, error) {
+	if cmd.SkipOrgSetup {
+		return -1, nil
+	}
+
 	var org m.Org
 	var org m.Org
 
 
 	if setting.AutoAssignOrg {
 	if setting.AutoAssignOrg {
@@ -103,23 +107,6 @@ func CreateUser(cmd *m.CreateUserCommand) error {
 			return err
 			return err
 		}
 		}
 
 
-		// create org user link
-		orgUser := m.OrgUser{
-			OrgId:   orgId,
-			UserId:  user.Id,
-			Role:    m.ROLE_ADMIN,
-			Created: time.Now(),
-			Updated: time.Now(),
-		}
-
-		if setting.AutoAssignOrg && !user.IsAdmin {
-			orgUser.Role = m.RoleType(setting.AutoAssignOrgRole)
-		}
-
-		if _, err = sess.Insert(&orgUser); err != nil {
-			return err
-		}
-
 		sess.publishAfterCommit(&events.UserCreated{
 		sess.publishAfterCommit(&events.UserCreated{
 			Timestamp: user.Created,
 			Timestamp: user.Created,
 			Id:        user.Id,
 			Id:        user.Id,
@@ -129,6 +116,26 @@ func CreateUser(cmd *m.CreateUserCommand) error {
 		})
 		})
 
 
 		cmd.Result = user
 		cmd.Result = user
+
+		// create org user link
+		if !cmd.SkipOrgSetup {
+			orgUser := m.OrgUser{
+				OrgId:   orgId,
+				UserId:  user.Id,
+				Role:    m.ROLE_ADMIN,
+				Created: time.Now(),
+				Updated: time.Now(),
+			}
+
+			if setting.AutoAssignOrg && !user.IsAdmin {
+				orgUser.Role = m.RoleType(setting.AutoAssignOrgRole)
+			}
+
+			if _, err = sess.Insert(&orgUser); err != nil {
+				return err
+			}
+		}
+
 		return nil
 		return nil
 	})
 	})
 }
 }

+ 1 - 1
public/app/features/dashboard/partials/import.html

@@ -1,6 +1,6 @@
 <topnav icon="fa fa-th-large" title="Dashboards" subnav="true">
 <topnav icon="fa fa-th-large" title="Dashboards" subnav="true">
 	<ul class="nav">
 	<ul class="nav">
-		<li class="active"><a href="import">Import</a></li>
+		<li class="active"><a href="import/dashboard">Import</a></li>
 	</ul>
 	</ul>
 </topnav>
 </topnav>
 
 

+ 1 - 1
public/app/features/templating/partials/editor.html

@@ -200,7 +200,7 @@
 								Multi format
 								Multi format
 							</li>
 							</li>
 							<li ng-show="current.multi">
 							<li ng-show="current.multi">
-								<select class="input-small tight-form-input last" ng-model="current.multiFormat" ng-change="runQuery()" ng-options="f for f in ['glob', 'regex values']"></select>
+								<select class="input-medium tight-form-input last" ng-model="current.multiFormat" ng-change="runQuery()" ng-options="f for f in ['glob', 'regex values']"></select>
 							</li>
 							</li>
 						</ul>
 						</ul>
 						<div class="clearfix"></div>
 						<div class="clearfix"></div>

+ 1 - 1
public/app/plugins/datasource/influxdb/queryBuilder.js

@@ -102,7 +102,7 @@ function (_) {
       if (i > 0) {
       if (i > 0) {
         query += ', ';
         query += ', ';
       }
       }
-      query += field.func + '(' + field.name + ')';
+      query += field.func + '("' + field.name + '")';
     }
     }
 
 
     var measurement = target.measurement;
     var measurement = target.measurement;

+ 38 - 30
public/app/plugins/datasource/influxdb/queryCtrl.js

@@ -119,8 +119,7 @@ function (angular, _, InfluxQueryBuilder) {
     $scope.getMeasurements = function () {
     $scope.getMeasurements = function () {
       var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS');
       var query = $scope.queryBuilder.buildExploreQuery('MEASUREMENTS');
       return $scope.datasource.metricFindQuery(query)
       return $scope.datasource.metricFindQuery(query)
-      .then($scope.transformToSegments)
-      .then($scope.addTemplateVariableSegments)
+      .then($scope.transformToSegments(true))
       .then(null, $scope.handleQueryError);
       .then(null, $scope.handleQueryError);
     };
     };
 
 
@@ -129,42 +128,46 @@ function (angular, _, InfluxQueryBuilder) {
       return [];
       return [];
     };
     };
 
 
-    $scope.transformToSegments = function(results) {
-      return _.map(results, function(segment) {
-        return new MetricSegment({ value: segment.text, expandable: segment.expandable });
-      });
-    };
+    $scope.transformToSegments = function(addTemplateVars) {
+      return function(results) {
+        var segments = _.map(results, function(segment) {
+          return new MetricSegment({ value: segment.text, expandable: segment.expandable });
+        });
 
 
-    $scope.addTemplateVariableSegments = function(segments) {
-      _.each(templateSrv.variables, function(variable) {
-        segments.unshift(new MetricSegment({ type: 'template', value: '/$' + variable.name + '/', expandable: true }));
-      });
-      return segments;
+        if (addTemplateVars) {
+          _.each(templateSrv.variables, function(variable) {
+            segments.unshift(new MetricSegment({ type: 'template', value: '/$' + variable.name + '/', expandable: true }));
+          });
+        }
+
+        return segments;
+      };
     };
     };
 
 
     $scope.getTagsOrValues = function(segment, index) {
     $scope.getTagsOrValues = function(segment, index) {
-      var query;
+      if (segment.type === 'condition') {
+        return $q.when([new MetricSegment('AND'), new MetricSegment('OR')]);
+      }
+      if (segment.type === 'operator') {
+        var nextValue = $scope.tagSegments[index+1].value;
+        if (/^\/.*\/$/.test(nextValue)) {
+          return $q.when(MetricSegment.newOperators(['=~', '!~']));
+        } else {
+          return $q.when(MetricSegment.newOperators(['=', '<>', '<', '>']));
+        }
+      }
 
 
+      var query, addTemplateVars;
       if (segment.type === 'key' || segment.type === 'plus-button') {
       if (segment.type === 'key' || segment.type === 'plus-button') {
         query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
         query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
+        addTemplateVars = false;
       } else if (segment.type === 'value')  {
       } else if (segment.type === 'value')  {
         query = $scope.queryBuilder.buildExploreQuery('TAG_VALUES', $scope.tagSegments[index-2].value);
         query = $scope.queryBuilder.buildExploreQuery('TAG_VALUES', $scope.tagSegments[index-2].value);
-      } else if (segment.type === 'condition') {
-        return $q.when([new MetricSegment('AND'), new MetricSegment('OR')]);
-      } else if (segment.type === 'operator' && /^(?!\/.*\/$)/.test($scope.tagSegments[index+1].value)) {
-        return $q.when([MetricSegment.newOperator('='), MetricSegment.newOperator('<>'),
-                        MetricSegment.newOperator('<'), MetricSegment.newOperator('>')]);
-
-      } else if (segment.type === 'operator' && /^\/.*\/$/.test($scope.tagSegments[index+1].value)) {
-        return $q.when([MetricSegment.newOperator('=~'), MetricSegment.newOperator('!~')]);
-      }
-      else  {
-        return $q.when([]);
+        addTemplateVars = true;
       }
       }
 
 
       return $scope.datasource.metricFindQuery(query)
       return $scope.datasource.metricFindQuery(query)
-      .then($scope.transformToSegments)
-      .then($scope.addTemplateVariableSegments)
+      .then($scope.transformToSegments(addTemplateVars))
       .then(function(results) {
       .then(function(results) {
         if (segment.type === 'key') {
         if (segment.type === 'key') {
           results.splice(0, 0, angular.copy($scope.removeTagFilterSegment));
           results.splice(0, 0, angular.copy($scope.removeTagFilterSegment));
@@ -177,8 +180,8 @@ function (angular, _, InfluxQueryBuilder) {
     $scope.getFieldSegments = function() {
     $scope.getFieldSegments = function() {
       var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
       var fieldsQuery = $scope.queryBuilder.buildExploreQuery('FIELDS');
       return $scope.datasource.metricFindQuery(fieldsQuery)
       return $scope.datasource.metricFindQuery(fieldsQuery)
-        .then($scope.transformToSegments)
-        .then(null, $scope.handleQueryError);
+      .then($scope.transformToSegments(false))
+      .then(null, $scope.handleQueryError);
     };
     };
 
 
     $scope.addField = function() {
     $scope.addField = function() {
@@ -197,8 +200,7 @@ function (angular, _, InfluxQueryBuilder) {
       var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
       var query = $scope.queryBuilder.buildExploreQuery('TAG_KEYS');
 
 
       return $scope.datasource.metricFindQuery(query)
       return $scope.datasource.metricFindQuery(query)
-      .then($scope.transformToSegments)
-      .then($scope.addTemplateVariableSegments)
+      .then($scope.transformToSegments(false))
       .then(function(results) {
       .then(function(results) {
         if (segment.type !== 'plus-button') {
         if (segment.type !== 'plus-button') {
           results.splice(0, 0, angular.copy($scope.removeGroupBySegment));
           results.splice(0, 0, angular.copy($scope.removeGroupBySegment));
@@ -322,6 +324,12 @@ function (angular, _, InfluxQueryBuilder) {
       return new MetricSegment({value: op, type: 'operator', cssClass: 'query-segment-operator' });
       return new MetricSegment({value: op, type: 'operator', cssClass: 'query-segment-operator' });
     };
     };
 
 
+    MetricSegment.newOperators = function(ops) {
+      return _.map(ops, function(op) {
+        return new MetricSegment({value: op, type: 'operator', cssClass: 'query-segment-operator' });
+      });
+    };
+
     MetricSegment.newPlusButton = function() {
     MetricSegment.newPlusButton = function() {
       return new MetricSegment({fake: true, html: '<i class="fa fa-plus "></i>', type: 'plus-button' });
       return new MetricSegment({fake: true, html: '<i class="fa fa-plus "></i>', type: 'plus-button' });
     };
     };

+ 6 - 10
public/app/plugins/datasource/kairosdb/datasource.js

@@ -10,7 +10,7 @@ function (angular, _, kbn) {
 
 
   var module = angular.module('grafana.services');
   var module = angular.module('grafana.services');
 
 
-  module.factory('KairosDBDatasource', function($q, $http, templateSrv) {
+  module.factory('KairosDBDatasource', function($q, backendSrv, templateSrv) {
 
 
     function KairosDBDatasource(datasource) {
     function KairosDBDatasource(datasource) {
       this.type = datasource.type;
       this.type = datasource.type;
@@ -51,10 +51,6 @@ function (angular, _, kbn) {
       return this.performTimeSeriesQuery(queries, start, end).then(handleKairosDBQueryResponseAlias, handleQueryError);
       return this.performTimeSeriesQuery(queries, start, end).then(handleKairosDBQueryResponseAlias, handleQueryError);
     };
     };
 
 
-    ///////////////////////////////////////////////////////////////////////
-    /// Query methods
-    ///////////////////////////////////////////////////////////////////////
-
     KairosDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) {
     KairosDBDatasource.prototype.performTimeSeriesQuery = function(queries, start, end) {
       var reqBody = {
       var reqBody = {
         metrics: queries,
         metrics: queries,
@@ -70,7 +66,7 @@ function (angular, _, kbn) {
         data: reqBody
         data: reqBody
       };
       };
 
 
-      return $http(options);
+      return backendSrv.datasourceRequest(options);
     };
     };
 
 
     /**
     /**
@@ -83,7 +79,7 @@ function (angular, _, kbn) {
         method: 'GET'
         method: 'GET'
       };
       };
 
 
-      return $http(options).then(function(response) {
+      return backendSrv.datasourceRequest(options).then(function(response) {
         if (!response.data) {
         if (!response.data) {
           return $q.when([]);
           return $q.when([]);
         }
         }
@@ -110,7 +106,7 @@ function (angular, _, kbn) {
         }
         }
       };
       };
 
 
-      return $http(options).then(function(result) {
+      return backendSrv.datasourceRequest(options).then(function(result) {
         if (!result.data) {
         if (!result.data) {
           return $q.when([]);
           return $q.when([]);
         }
         }
@@ -139,7 +135,7 @@ function (angular, _, kbn) {
         }
         }
       };
       };
 
 
-      return $http(options).then(function(result) {
+      return backendSrv.datasourceRequest(options).then(function(result) {
         if (!result.data) {
         if (!result.data) {
           return $q.when([]);
           return $q.when([]);
         }
         }
@@ -158,7 +154,7 @@ function (angular, _, kbn) {
         }
         }
       };
       };
 
 
-      return $http(options).then(function(response) {
+      return backendSrv.datasourceRequest(options).then(function(response) {
         if (!response.data) {
         if (!response.data) {
           return [];
           return [];
         }
         }

+ 7 - 7
public/test/specs/influx09-querybuilder-specs.js

@@ -13,7 +13,7 @@ define([
       var query = builder.build();
       var query = builder.build();
 
 
       it('should generate correct query', function() {
       it('should generate correct query', function() {
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
       });
       });
 
 
     });
     });
@@ -27,14 +27,14 @@ define([
       var query = builder.build();
       var query = builder.build();
 
 
       it('should generate correct query', function() {
       it('should generate correct query', function() {
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE "hostname" = \'server1\' AND $timeFilter'
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND $timeFilter'
                             + ' GROUP BY time($interval)');
                             + ' GROUP BY time($interval)');
       });
       });
 
 
       it('should switch regex operator with tag value is regex', function() {
       it('should switch regex operator with tag value is regex', function() {
         var builder = new InfluxQueryBuilder({measurement: 'cpu', tags: [{key: 'app', value: '/e.*/'}]});
         var builder = new InfluxQueryBuilder({measurement: 'cpu', tags: [{key: 'app', value: '/e.*/'}]});
         var query = builder.build();
         var query = builder.build();
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "app" =~ /e.*/ AND $timeFilter GROUP BY time($interval)');
       });
       });
     });
     });
 
 
@@ -48,7 +48,7 @@ define([
       var query = builder.build();
       var query = builder.build();
 
 
       it('should generate correct query', function() {
       it('should generate correct query', function() {
-        expect(query).to.be('SELECT sum(tx_in), mean(tx_out) FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
+        expect(query).to.be('SELECT sum("tx_in"), mean("tx_out") FROM "cpu" WHERE $timeFilter GROUP BY time($interval)');
       });
       });
     });
     });
 
 
@@ -61,7 +61,7 @@ define([
       var query = builder.build();
       var query = builder.build();
 
 
       it('should generate correct query', function() {
       it('should generate correct query', function() {
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' AND "app" = \'email\' AND ' +
                             '$timeFilter GROUP BY time($interval)');
                             '$timeFilter GROUP BY time($interval)');
       });
       });
     });
     });
@@ -75,7 +75,7 @@ define([
       var query = builder.build();
       var query = builder.build();
 
 
       it('should generate correct query', function() {
       it('should generate correct query', function() {
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE "hostname" = \'server1\' OR "hostname" = \'server2\' AND ' +
                             '$timeFilter GROUP BY time($interval)');
                             '$timeFilter GROUP BY time($interval)');
       });
       });
     });
     });
@@ -89,7 +89,7 @@ define([
         });
         });
 
 
         var query = builder.build();
         var query = builder.build();
-        expect(query).to.be('SELECT mean(value) FROM "cpu" WHERE $timeFilter ' +
+        expect(query).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter ' +
           'GROUP BY time($interval), "host"');
           'GROUP BY time($interval), "host"');
       });
       });
     });
     });