Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
8f167c47
Commit
8f167c47
authored
Apr 12, 2019
by
Mitsuhiro Tanda
Committed by
Torkel Ödegaard
Apr 12, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
CloudWatch: Fix template variable expand bug (#16405)
CloudWatch: Fix template variable issues
parent
d7d20a5b
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
242 additions
and
23 deletions
+242
-23
public/app/plugins/datasource/cloudwatch/datasource.ts
+12
-12
public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts
+217
-11
public/app/plugins/datasource/cloudwatch/types.ts
+13
-0
No files found.
public/app/plugins/datasource/cloudwatch/datasource.ts
View file @
8f167c47
...
@@ -2,10 +2,11 @@ import angular from 'angular';
...
@@ -2,10 +2,11 @@ import angular from 'angular';
import
_
from
'lodash'
;
import
_
from
'lodash'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
kbn
from
'app/core/utils/kbn'
;
import
kbn
from
'app/core/utils/kbn'
;
import
*
as
templatingVariable
from
'app/features/templating/variable'
;
import
{
CloudWatchQuery
}
from
'./types'
;
import
{
DataSourceApi
}
from
'@grafana/ui/src/types'
;
// import * as moment from 'moment';
// import * as moment from 'moment';
export
default
class
CloudWatchDatasource
{
export
default
class
CloudWatchDatasource
implements
DataSourceApi
<
CloudWatchQuery
>
{
type
:
any
;
type
:
any
;
name
:
any
;
name
:
any
;
proxyUrl
:
any
;
proxyUrl
:
any
;
...
@@ -448,20 +449,19 @@ export default class CloudWatchDatasource {
...
@@ -448,20 +449,19 @@ export default class CloudWatchDatasource {
// Datasource and template srv logic uber-complected. This should be cleaned up.
// Datasource and template srv logic uber-complected. This should be cleaned up.
return
_
.
chain
(
targets
)
return
_
.
chain
(
targets
)
.
map
(
target
=>
{
.
map
(
target
=>
{
if
(
target
.
id
&&
target
.
id
.
length
>
0
&&
target
.
expression
&&
target
.
expression
.
length
>
0
)
{
return
[
target
];
}
const
variableIndex
=
_
.
keyBy
(
templateSrv
.
variables
,
'name'
);
const
dimensionKey
=
_
.
findKey
(
target
.
dimensions
,
v
=>
{
const
dimensionKey
=
_
.
findKey
(
target
.
dimensions
,
v
=>
{
return
templateSrv
.
variableExists
(
v
)
&&
!
_
.
has
(
scopedVars
,
templateSrv
.
getVariableName
(
v
));
const
variableName
=
templateSrv
.
getVariableName
(
v
);
return
templateSrv
.
variableExists
(
v
)
&&
!
_
.
has
(
scopedVars
,
variableName
)
&&
variableIndex
[
variableName
].
multi
;
});
});
if
(
dimensionKey
)
{
if
(
dimensionKey
)
{
const
multiVariable
=
_
.
find
(
templateSrv
.
variables
,
variable
=>
{
const
multiVariable
=
variableIndex
[
templateSrv
.
getVariableName
(
target
.
dimensions
[
dimensionKey
])];
return
(
return
this
.
getExpandedVariables
(
target
,
dimensionKey
,
multiVariable
,
templateSrv
);
templatingVariable
.
containsVariable
(
target
.
dimensions
[
dimensionKey
],
variable
.
name
)
&&
variable
.
multi
);
});
const
variable
=
_
.
find
(
templateSrv
.
variables
,
variable
=>
{
return
templatingVariable
.
containsVariable
(
target
.
dimensions
[
dimensionKey
],
variable
.
name
);
});
return
this
.
getExpandedVariables
(
target
,
dimensionKey
,
multiVariable
||
variable
,
templateSrv
);
}
else
{
}
else
{
return
[
target
];
return
[
target
];
}
}
...
...
public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts
View file @
8f167c47
import
'../datasource'
;
import
'../datasource'
;
import
CloudWatchDatasource
from
'../datasource'
;
import
CloudWatchDatasource
from
'../datasource'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
*
as
dateMath
from
'app/core/utils/datemath'
;
import
{
TemplateSrv
}
from
'app/features/templating/template_srv'
;
import
{
CustomVariable
}
from
'app/features/templating/all'
;
import
_
from
'lodash'
;
import
_
from
'lodash'
;
import
{
CloudWatchQuery
}
from
'../types'
;
describe
(
'CloudWatchDatasource'
,
()
=>
{
describe
(
'CloudWatchDatasource'
,
()
=>
{
const
instanceSettings
=
{
const
instanceSettings
=
{
jsonData
:
{
defaultRegion
:
'us-east-1'
,
access
:
'proxy'
},
jsonData
:
{
defaultRegion
:
'us-east-1'
,
access
:
'proxy'
},
};
};
const
templateSrv
=
{
const
templateSrv
=
new
TemplateSrv
();
data
:
{},
templateSettings
:
{
interpolate
:
/
\[\[([\s\S]
+
?)\]\]
/g
},
replace
:
text
=>
_
.
template
(
text
,
templateSrv
.
templateSettings
)(
templateSrv
.
data
),
variableExists
:
()
=>
false
,
};
const
timeSrv
=
{
const
timeSrv
=
{
time
:
{
from
:
'now-1h'
,
to
:
'now'
},
time
:
{
from
:
'now-1h'
,
to
:
'now'
},
...
@@ -35,7 +33,7 @@ describe('CloudWatchDatasource', () => {
...
@@ -35,7 +33,7 @@ describe('CloudWatchDatasource', () => {
});
});
describe
(
'When performing CloudWatch query'
,
()
=>
{
describe
(
'When performing CloudWatch query'
,
()
=>
{
let
requestParams
;
let
requestParams
:
{
queries
:
CloudWatchQuery
[]
}
;
const
query
=
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
...
@@ -95,9 +93,18 @@ describe('CloudWatchDatasource', () => {
...
@@ -95,9 +93,18 @@ describe('CloudWatchDatasource', () => {
});
});
it
(
'should generate the correct query with interval variable'
,
done
=>
{
it
(
'should generate the correct query with interval variable'
,
done
=>
{
ctx
.
templateSrv
.
data
=
{
templateSrv
.
init
([
period
:
'10m'
,
new
CustomVariable
(
};
{
name
:
'period'
,
current
:
{
value
:
'10m'
,
},
multi
:
false
,
},
{}
),
]);
const
query
=
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
...
@@ -167,7 +174,7 @@ describe('CloudWatchDatasource', () => {
...
@@ -167,7 +174,7 @@ describe('CloudWatchDatasource', () => {
expect
(
ctx
.
ds
.
getActualRegion
(
'some-fake-region-1'
)).
toBe
(
'some-fake-region-1'
);
expect
(
ctx
.
ds
.
getActualRegion
(
'some-fake-region-1'
)).
toBe
(
'some-fake-region-1'
);
});
});
let
requestParams
;
let
requestParams
:
{
queries
:
CloudWatchQuery
[]
}
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
ctx
.
ds
.
performTimeSeriesQuery
=
jest
.
fn
(
request
=>
{
ctx
.
ds
.
performTimeSeriesQuery
=
jest
.
fn
(
request
=>
{
requestParams
=
request
;
requestParams
=
request
;
...
@@ -257,6 +264,205 @@ describe('CloudWatchDatasource', () => {
...
@@ -257,6 +264,205 @@ describe('CloudWatchDatasource', () => {
});
});
});
});
describe
(
'When performing CloudWatch query with template variables'
,
()
=>
{
let
requestParams
:
{
queries
:
CloudWatchQuery
[]
};
beforeEach
(()
=>
{
templateSrv
.
init
([
new
CustomVariable
(
{
name
:
'var1'
,
current
:
{
value
:
'var1-foo'
,
},
multi
:
false
,
},
{}
),
new
CustomVariable
(
{
name
:
'var2'
,
current
:
{
value
:
'var2-foo'
,
},
multi
:
false
,
},
{}
),
new
CustomVariable
(
{
name
:
'var3'
,
options
:
[
{
selected
:
true
,
value
:
'var3-foo'
},
{
selected
:
false
,
value
:
'var3-bar'
},
{
selected
:
true
,
value
:
'var3-baz'
},
],
current
:
{
value
:
[
'var3-foo'
,
'var3-baz'
],
},
multi
:
true
,
},
{}
),
]);
ctx
.
backendSrv
.
datasourceRequest
=
jest
.
fn
(
params
=>
{
requestParams
=
params
.
data
;
return
Promise
.
resolve
({
data
:
{}
});
});
});
it
(
'should generate the correct query for single template variable'
,
done
=>
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
rangeRaw
:
{
from
:
1483228800
,
to
:
1483232400
},
targets
:
[
{
refId
:
'A'
,
region
:
'us-east-1'
,
namespace
:
'TestNamespace'
,
metricName
:
'TestMetricName'
,
dimensions
:
{
dim2
:
'[[var2]]'
,
},
statistics
:
[
'Average'
],
period
:
300
,
},
],
};
ctx
.
ds
.
query
(
query
).
then
(()
=>
{
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
done
();
});
});
it
(
'should generate the correct query for multilple template variables'
,
done
=>
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
rangeRaw
:
{
from
:
1483228800
,
to
:
1483232400
},
targets
:
[
{
refId
:
'A'
,
region
:
'us-east-1'
,
namespace
:
'TestNamespace'
,
metricName
:
'TestMetricName'
,
dimensions
:
{
dim1
:
'[[var1]]'
,
dim2
:
'[[var2]]'
,
dim3
:
'[[var3]]'
,
},
statistics
:
[
'Average'
],
period
:
300
,
},
],
scopedVars
:
{
var1
:
{
selected
:
true
,
value
:
'var1-foo'
},
var2
:
{
selected
:
true
,
value
:
'var2-foo'
},
},
};
ctx
.
ds
.
query
(
query
).
then
(()
=>
{
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim3'
]).
toBe
(
'var3-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim3'
]).
toBe
(
'var3-baz'
);
done
();
});
});
it
(
'should generate the correct query for multilple template variables, lack scopedVars'
,
done
=>
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
rangeRaw
:
{
from
:
1483228800
,
to
:
1483232400
},
targets
:
[
{
refId
:
'A'
,
region
:
'us-east-1'
,
namespace
:
'TestNamespace'
,
metricName
:
'TestMetricName'
,
dimensions
:
{
dim1
:
'[[var1]]'
,
dim2
:
'[[var2]]'
,
dim3
:
'[[var3]]'
,
},
statistics
:
[
'Average'
],
period
:
300
,
},
],
scopedVars
:
{
var1
:
{
selected
:
true
,
value
:
'var1-foo'
},
},
};
ctx
.
ds
.
query
(
query
).
then
(()
=>
{
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim3'
]).
toBe
(
'var3-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim3'
]).
toBe
(
'var3-baz'
);
done
();
});
});
it
(
'should generate the correct query for multilple template variables with expression'
,
done
=>
{
const
query
=
{
range
:
{
from
:
'now-1h'
,
to
:
'now'
},
rangeRaw
:
{
from
:
1483228800
,
to
:
1483232400
},
targets
:
[
{
refId
:
'A'
,
id
:
'id1'
,
region
:
'us-east-1'
,
namespace
:
'TestNamespace'
,
metricName
:
'TestMetricName'
,
dimensions
:
{
dim1
:
'[[var1]]'
,
dim2
:
'[[var2]]'
,
dim3
:
'[[var3]]'
,
},
statistics
:
[
'Average'
],
period
:
300
,
expression
:
''
,
},
{
refId
:
'B'
,
id
:
'id2'
,
expression
:
'METRICS("id1") * 2'
,
dimensions
:
{
// garbage data for fail test
dim1
:
'[[var1]]'
,
dim2
:
'[[var2]]'
,
dim3
:
'[[var3]]'
,
},
statistics
:
[],
// dummy
},
],
scopedVars
:
{
var1
:
{
selected
:
true
,
value
:
'var1-foo'
},
var2
:
{
selected
:
true
,
value
:
'var2-foo'
},
},
};
ctx
.
ds
.
query
(
query
).
then
(()
=>
{
expect
(
requestParams
.
queries
.
length
).
toBe
(
3
);
expect
(
requestParams
.
queries
[
0
].
id
).
toMatch
(
/^id1.*/
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
0
].
dimensions
[
'dim3'
]).
toBe
(
'var3-foo'
);
expect
(
requestParams
.
queries
[
1
].
id
).
toMatch
(
/^id1.*/
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim1'
]).
toBe
(
'var1-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim2'
]).
toBe
(
'var2-foo'
);
expect
(
requestParams
.
queries
[
1
].
dimensions
[
'dim3'
]).
toBe
(
'var3-baz'
);
expect
(
requestParams
.
queries
[
2
].
id
).
toMatch
(
/^id2.*/
);
expect
(
requestParams
.
queries
[
2
].
expression
).
toBe
(
'METRICS("id1") * 2'
);
done
();
});
});
});
function
describeMetricFindQuery
(
query
,
func
)
{
function
describeMetricFindQuery
(
query
,
func
)
{
describe
(
'metricFindQuery '
+
query
,
()
=>
{
describe
(
'metricFindQuery '
+
query
,
()
=>
{
const
scenario
:
any
=
{};
const
scenario
:
any
=
{};
...
...
public/app/plugins/datasource/cloudwatch/types.ts
0 → 100644
View file @
8f167c47
import
{
DataQuery
}
from
'@grafana/ui/src/types'
;
export
interface
CloudWatchQuery
extends
DataQuery
{
id
:
string
;
region
:
string
;
namespace
:
string
;
metricName
:
string
;
dimensions
:
{
[
key
:
string
]:
string
};
statistics
:
string
[];
period
:
string
;
expression
:
string
;
returnData
:
boolean
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment