Commit 69561104 by Torkel Ödegaard

Merge branch 'master' of github.com:grafana/grafana

parents cd0e1a89 f500dfd1
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
## Bug Fixes ## Bug Fixes
* **Dashboard(settings)**: Closing setting views using ESC key did not update url correctly, fixes [#8869](https://github.com/grafana/grafana/issues/8869)
* **Forms(TextArea)**: Bug fix for no scroll in text areas [#8797](https://github.com/grafana/grafana/issues/8797) * **Forms(TextArea)**: Bug fix for no scroll in text areas [#8797](https://github.com/grafana/grafana/issues/8797)
# 4.4.1 (2017-07-05) # 4.4.1 (2017-07-05)
......
...@@ -14,7 +14,7 @@ weight = 4 ...@@ -14,7 +14,7 @@ weight = 4
Grafana is very easy to install and run using the offical docker container. Grafana is very easy to install and run using the offical docker container.
$ docker run -i -p 3000:3000 grafana/grafana $ docker run -d -p 3000:3000 grafana/grafana
All Grafana configuration settings can be defined using environment All Grafana configuration settings can be defined using environment
variables, this is especially useful when using the above container. variables, this is especially useful when using the above container.
......
...@@ -39,6 +39,7 @@ type cwRequest struct { ...@@ -39,6 +39,7 @@ type cwRequest struct {
type datasourceInfo struct { type datasourceInfo struct {
Profile string Profile string
Region string Region string
AuthType string
AssumeRoleArn string AssumeRoleArn string
Namespace string Namespace string
...@@ -47,6 +48,7 @@ type datasourceInfo struct { ...@@ -47,6 +48,7 @@ type datasourceInfo struct {
} }
func (req *cwRequest) GetDatasourceInfo() *datasourceInfo { func (req *cwRequest) GetDatasourceInfo() *datasourceInfo {
authType := req.DataSource.JsonData.Get("authType").MustString()
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString() assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
accessKey := "" accessKey := ""
secretKey := "" secretKey := ""
...@@ -61,6 +63,7 @@ func (req *cwRequest) GetDatasourceInfo() *datasourceInfo { ...@@ -61,6 +63,7 @@ func (req *cwRequest) GetDatasourceInfo() *datasourceInfo {
} }
return &datasourceInfo{ return &datasourceInfo{
AuthType: authType,
AssumeRoleArn: assumeRoleArn, AssumeRoleArn: assumeRoleArn,
Region: req.Region, Region: req.Region,
Profile: req.DataSource.Database, Profile: req.DataSource.Database,
...@@ -110,7 +113,7 @@ func getCredentials(dsInfo *datasourceInfo) (*credentials.Credentials, error) { ...@@ -110,7 +113,7 @@ func getCredentials(dsInfo *datasourceInfo) (*credentials.Credentials, error) {
sessionToken := "" sessionToken := ""
var expiration *time.Time var expiration *time.Time
expiration = nil expiration = nil
if strings.Index(dsInfo.AssumeRoleArn, "arn:aws:iam:") == 0 { if dsInfo.AuthType == "arn" && strings.Index(dsInfo.AssumeRoleArn, "arn:aws:iam:") == 0 {
params := &sts.AssumeRoleInput{ params := &sts.AssumeRoleInput{
RoleArn: aws.String(dsInfo.AssumeRoleArn), RoleArn: aws.String(dsInfo.AssumeRoleArn),
RoleSessionName: aws.String("GrafanaSession"), RoleSessionName: aws.String("GrafanaSession"),
......
...@@ -42,7 +42,7 @@ func init() { ...@@ -42,7 +42,7 @@ func init() {
"AWS/EC2Spot": {"AvailableInstancePoolsCount", "BidsSubmittedForCapacity", "EligibleInstancePoolCount", "FulfilledCapacity", "MaxPercentCapacityAllocation", "PendingCapacity", "PercentCapacityAllocation", "TargetCapacity", "TerminatingCapacity"}, "AWS/EC2Spot": {"AvailableInstancePoolsCount", "BidsSubmittedForCapacity", "EligibleInstancePoolCount", "FulfilledCapacity", "MaxPercentCapacityAllocation", "PendingCapacity", "PercentCapacityAllocation", "TargetCapacity", "TerminatingCapacity"},
"AWS/ECS": {"CPUReservation", "MemoryReservation", "CPUUtilization", "MemoryUtilization"}, "AWS/ECS": {"CPUReservation", "MemoryReservation", "CPUUtilization", "MemoryUtilization"},
"AWS/EFS": {"BurstCreditBalance", "ClientConnections", "DataReadIOBytes", "DataWriteIOBytes", "MetadataIOBytes", "TotalIOBytes", "PermittedThroughput", "PercentIOLimit"}, "AWS/EFS": {"BurstCreditBalance", "ClientConnections", "DataReadIOBytes", "DataWriteIOBytes", "MetadataIOBytes", "TotalIOBytes", "PermittedThroughput", "PercentIOLimit"},
"AWS/ELB": {"HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount"}, "AWS/ELB": {"HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount", "EstimatedALBActiveConnectionCount", "EstimatedALBConsumedLCUs", "EstimatedALBNewConnectionCount", "EstimatedProcessedBytes"},
"AWS/ElastiCache": { "AWS/ElastiCache": {
"CPUUtilization", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut", "SwapUsage", "CPUUtilization", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut", "SwapUsage",
"BytesUsedForCacheItems", "BytesReadIntoMemcached", "BytesWrittenOutFromMemcached", "CasBadval", "CasHits", "CasMisses", "CmdFlush", "CmdGet", "CmdSet", "CurrConnections", "CurrItems", "DecrHits", "DecrMisses", "DeleteHits", "DeleteMisses", "Evictions", "GetHits", "GetMisses", "IncrHits", "IncrMisses", "Reclaimed", "BytesUsedForCacheItems", "BytesReadIntoMemcached", "BytesWrittenOutFromMemcached", "CasBadval", "CasHits", "CasMisses", "CmdFlush", "CmdGet", "CmdSet", "CurrConnections", "CurrItems", "DecrHits", "DecrMisses", "DeleteHits", "DeleteMisses", "Evictions", "GetHits", "GetMisses", "IncrHits", "IncrMisses", "Reclaimed",
......
...@@ -79,7 +79,7 @@ export class AlertTabCtrl { ...@@ -79,7 +79,7 @@ export class AlertTabCtrl {
getAlertHistory() { getAlertHistory() {
this.backendSrv.get(`/api/annotations?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}&limit=50`).then(res => { this.backendSrv.get(`/api/annotations?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}&limit=50`).then(res => {
this.alertHistory = _.map(res, ah => { this.alertHistory = _.map(res, ah => {
ah.time = moment(ah.time).format('MMM D, YYYY HH:mm:ss'); ah.time = this.dashboardSrv.getCurrent().formatDate(ah.time, 'MMM D, YYYY HH:mm:ss');
ah.stateModel = alertDef.getStateDisplayModel(ah.newState); ah.stateModel = alertDef.getStateDisplayModel(ah.newState);
ah.info = alertDef.getAlertAnnotationInfo(ah); ah.info = alertDef.getAlertAnnotationInfo(ah);
return ah; return ah;
......
...@@ -87,7 +87,7 @@ function addMathStrategy(selectParts, partModel) { ...@@ -87,7 +87,7 @@ function addMathStrategy(selectParts, partModel) {
return; return;
} }
// if next to last is math, replace it // if next to last is math, replace it
if (selectParts[partCount-2].def.type === 'math') { if (partCount > 1 && selectParts[partCount-2].def.type === 'math') {
selectParts[partCount-2] = partModel; selectParts[partCount-2] = partModel;
return; return;
} else if (selectParts[partCount-1].def.type === 'alias') { // if last is alias add it before } else if (selectParts[partCount-1].def.type === 'alias') { // if last is alias add it before
......
...@@ -236,6 +236,17 @@ describe('InfluxQuery', function() { ...@@ -236,6 +236,17 @@ describe('InfluxQuery', function() {
expect(query.target.select[0][2].type).to.be('math'); expect(query.target.select[0][2].type).to.be('math');
}); });
it('should add math when one only query part', function() {
var query = new InfluxQuery({
measurement: 'cpu',
select: [[{type: 'field', params: ['value']}]]
}, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(2);
expect(query.target.select[0][1].type).to.be('math');
});
describe('when render adhoc filters', function() { describe('when render adhoc filters', function() {
it('should generate correct query segment', function() { it('should generate correct query segment', function() {
var query = new InfluxQuery({measurement: 'cpu', }, templateSrv, {}); var query = new InfluxQuery({measurement: 'cpu', }, templateSrv, {});
......
...@@ -5,7 +5,7 @@ import queryPart from '../query_part'; ...@@ -5,7 +5,7 @@ import queryPart from '../query_part';
describe('InfluxQueryPart', () => { describe('InfluxQueryPart', () => {
describe('series with mesurement only', () => { describe('series with measurement only', () => {
it('should handle nested function parts', () => { it('should handle nested function parts', () => {
var part = queryPart.create({ var part = queryPart.create({
type: 'derivative', type: 'derivative',
...@@ -25,7 +25,7 @@ describe('InfluxQueryPart', () => { ...@@ -25,7 +25,7 @@ describe('InfluxQueryPart', () => {
expect(part.render('value')).to.be('spread(value)'); expect(part.render('value')).to.be('spread(value)');
}); });
it('should handle suffirx parts', () => { it('should handle suffix parts', () => {
var part = queryPart.create({ var part = queryPart.create({
type: 'math', type: 'math',
params: ['/ 100'], params: ['/ 100'],
......
...@@ -59,9 +59,13 @@ function (_) { ...@@ -59,9 +59,13 @@ function (_) {
return this.datasource._request('GET', url) return this.datasource._request('GET', url)
.then(function(result) { .then(function(result) {
return _.map(result.data.data, function(metric) { var _labels = _.map(result.data.data, function(metric) {
return metric[label];
});
return _.uniq(_labels).map(function(metric) {
return { return {
text: metric[label], text: metric,
expandable: true expandable: true
}; };
}); });
......
...@@ -104,7 +104,7 @@ class AlertListPanel extends PanelCtrl { ...@@ -104,7 +104,7 @@ class AlertListPanel extends PanelCtrl {
this.backendSrv.get(`/api/annotations`, params) this.backendSrv.get(`/api/annotations`, params)
.then(res => { .then(res => {
this.alertHistory = _.map(res, al => { this.alertHistory = _.map(res, al => {
al.time = moment(al.time).format('MMM D, YYYY HH:mm:ss'); al.time = this.dashboard.formatDate(al.time, 'MMM D, YYYY HH:mm:ss');
al.stateModel = alertDef.getStateDisplayModel(al.newState); al.stateModel = alertDef.getStateDisplayModel(al.newState);
al.info = alertDef.getAlertAnnotationInfo(al); al.info = alertDef.getAlertAnnotationInfo(al);
return al; return al;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment