Commit 69561104 by Torkel Ödegaard

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

parents cd0e1a89 f500dfd1
......@@ -8,6 +8,7 @@
## 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)
# 4.4.1 (2017-07-05)
......
......@@ -14,7 +14,7 @@ weight = 4
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
variables, this is especially useful when using the above container.
......
......@@ -39,6 +39,7 @@ type cwRequest struct {
type datasourceInfo struct {
Profile string
Region string
AuthType string
AssumeRoleArn string
Namespace string
......@@ -47,6 +48,7 @@ type datasourceInfo struct {
}
func (req *cwRequest) GetDatasourceInfo() *datasourceInfo {
authType := req.DataSource.JsonData.Get("authType").MustString()
assumeRoleArn := req.DataSource.JsonData.Get("assumeRoleArn").MustString()
accessKey := ""
secretKey := ""
......@@ -61,6 +63,7 @@ func (req *cwRequest) GetDatasourceInfo() *datasourceInfo {
}
return &datasourceInfo{
AuthType: authType,
AssumeRoleArn: assumeRoleArn,
Region: req.Region,
Profile: req.DataSource.Database,
......@@ -110,7 +113,7 @@ func getCredentials(dsInfo *datasourceInfo) (*credentials.Credentials, error) {
sessionToken := ""
var expiration *time.Time
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{
RoleArn: aws.String(dsInfo.AssumeRoleArn),
RoleSessionName: aws.String("GrafanaSession"),
......
......@@ -42,7 +42,7 @@ func init() {
"AWS/EC2Spot": {"AvailableInstancePoolsCount", "BidsSubmittedForCapacity", "EligibleInstancePoolCount", "FulfilledCapacity", "MaxPercentCapacityAllocation", "PendingCapacity", "PercentCapacityAllocation", "TargetCapacity", "TerminatingCapacity"},
"AWS/ECS": {"CPUReservation", "MemoryReservation", "CPUUtilization", "MemoryUtilization"},
"AWS/EFS": {"BurstCreditBalance", "ClientConnections", "DataReadIOBytes", "DataWriteIOBytes", "MetadataIOBytes", "TotalIOBytes", "PermittedThroughput", "PercentIOLimit"},
"AWS/ELB": {"HealthyHostCount", "UnHealthyHostCount", "RequestCount", "Latency", "HTTPCode_ELB_4XX", "HTTPCode_ELB_5XX", "HTTPCode_Backend_2XX", "HTTPCode_Backend_3XX", "HTTPCode_Backend_4XX", "HTTPCode_Backend_5XX", "BackendConnectionErrors", "SurgeQueueLength", "SpilloverCount"},
"AWS/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": {
"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",
......
......@@ -79,7 +79,7 @@ export class AlertTabCtrl {
getAlertHistory() {
this.backendSrv.get(`/api/annotations?dashboardId=${this.panelCtrl.dashboard.id}&panelId=${this.panel.id}&limit=50`).then(res => {
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.info = alertDef.getAlertAnnotationInfo(ah);
return ah;
......
......@@ -87,7 +87,7 @@ function addMathStrategy(selectParts, partModel) {
return;
}
// 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;
return;
} else if (selectParts[partCount-1].def.type === 'alias') { // if last is alias add it before
......
......@@ -236,6 +236,17 @@ describe('InfluxQuery', function() {
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() {
it('should generate correct query segment', function() {
var query = new InfluxQuery({measurement: 'cpu', }, templateSrv, {});
......
......@@ -5,7 +5,7 @@ import queryPart from '../query_part';
describe('InfluxQueryPart', () => {
describe('series with mesurement only', () => {
describe('series with measurement only', () => {
it('should handle nested function parts', () => {
var part = queryPart.create({
type: 'derivative',
......@@ -25,7 +25,7 @@ describe('InfluxQueryPart', () => {
expect(part.render('value')).to.be('spread(value)');
});
it('should handle suffirx parts', () => {
it('should handle suffix parts', () => {
var part = queryPart.create({
type: 'math',
params: ['/ 100'],
......
......@@ -59,9 +59,13 @@ function (_) {
return this.datasource._request('GET', url)
.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 {
text: metric[label],
text: metric,
expandable: true
};
});
......
......@@ -104,7 +104,7 @@ class AlertListPanel extends PanelCtrl {
this.backendSrv.get(`/api/annotations`, params)
.then(res => {
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.info = alertDef.getAlertAnnotationInfo(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