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
3c662ade
Commit
3c662ade
authored
Nov 29, 2016
by
Carl Bergquist
Committed by
GitHub
Nov 29, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6698 from grafana/cloudwatch_configurable_keys
Cloudwatch configurable keys from config page.
parents
180940a3
7bc1c3cc
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
236 additions
and
114 deletions
+236
-114
pkg/api/cloudwatch/cloudwatch.go
+47
-9
pkg/api/cloudwatch/metrics.go
+44
-40
pkg/api/cloudwatch/metrics_test.go
+16
-12
pkg/api/datasources.go
+6
-0
pkg/api/dtos/models.go
+18
-18
public/app/features/plugins/ds_edit_ctrl.ts
+0
-1
public/app/plugins/datasource/cloudwatch/config_ctrl.ts
+51
-0
public/app/plugins/datasource/cloudwatch/module.ts
+1
-4
public/app/plugins/datasource/cloudwatch/partials/config.html
+53
-30
No files found.
pkg/api/cloudwatch/cloudwatch.go
View file @
3c662ade
...
...
@@ -33,6 +33,39 @@ type cwRequest struct {
DataSource
*
m
.
DataSource
}
type
datasourceInfo
struct
{
Profile
string
Region
string
AssumeRoleArn
string
Namespace
string
AccessKey
string
SecretKey
string
}
func
(
req
*
cwRequest
)
GetDatasourceInfo
()
*
datasourceInfo
{
assumeRoleArn
:=
req
.
DataSource
.
JsonData
.
Get
(
"assumeRoleArn"
)
.
MustString
()
accessKey
:=
""
secretKey
:=
""
for
key
,
value
:=
range
req
.
DataSource
.
SecureJsonData
.
Decrypt
()
{
if
key
==
"accessKey"
{
accessKey
=
value
}
if
key
==
"secretKey"
{
secretKey
=
value
}
}
return
&
datasourceInfo
{
AssumeRoleArn
:
assumeRoleArn
,
Region
:
req
.
Region
,
Profile
:
req
.
DataSource
.
Database
,
AccessKey
:
accessKey
,
SecretKey
:
secretKey
,
}
}
func
init
()
{
actionHandlers
=
map
[
string
]
actionHandler
{
"GetMetricStatistics"
:
handleGetMetricStatistics
,
...
...
@@ -56,8 +89,8 @@ type cache struct {
var
awsCredentialCache
map
[
string
]
cache
=
make
(
map
[
string
]
cache
)
var
credentialCacheLock
sync
.
RWMutex
func
getCredentials
(
profile
string
,
region
string
,
assumeRoleArn
string
)
*
credentials
.
Credentials
{
cacheKey
:=
profile
+
":"
+
a
ssumeRoleArn
func
getCredentials
(
dsInfo
*
datasourceInfo
)
*
credentials
.
Credentials
{
cacheKey
:=
dsInfo
.
Profile
+
":"
+
dsInfo
.
A
ssumeRoleArn
credentialCacheLock
.
RLock
()
if
_
,
ok
:=
awsCredentialCache
[
cacheKey
];
ok
{
if
awsCredentialCache
[
cacheKey
]
.
expiration
!=
nil
&&
...
...
@@ -74,9 +107,9 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
sessionToken
:=
""
var
expiration
*
time
.
Time
expiration
=
nil
if
strings
.
Index
(
a
ssumeRoleArn
,
"arn:aws:iam:"
)
==
0
{
if
strings
.
Index
(
dsInfo
.
A
ssumeRoleArn
,
"arn:aws:iam:"
)
==
0
{
params
:=
&
sts
.
AssumeRoleInput
{
RoleArn
:
aws
.
String
(
a
ssumeRoleArn
),
RoleArn
:
aws
.
String
(
dsInfo
.
A
ssumeRoleArn
),
RoleSessionName
:
aws
.
String
(
"GrafanaSession"
),
DurationSeconds
:
aws
.
Int64
(
900
),
}
...
...
@@ -85,13 +118,14 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
stsCreds
:=
credentials
.
NewChainCredentials
(
[]
credentials
.
Provider
{
&
credentials
.
EnvProvider
{},
&
credentials
.
SharedCredentialsProvider
{
Filename
:
""
,
Profile
:
p
rofile
},
&
credentials
.
SharedCredentialsProvider
{
Filename
:
""
,
Profile
:
dsInfo
.
P
rofile
},
&
ec2rolecreds
.
EC2RoleProvider
{
Client
:
ec2metadata
.
New
(
stsSess
),
ExpiryWindow
:
5
*
time
.
Minute
},
})
stsConfig
:=
&
aws
.
Config
{
Region
:
aws
.
String
(
r
egion
),
Region
:
aws
.
String
(
dsInfo
.
R
egion
),
Credentials
:
stsCreds
,
}
svc
:=
sts
.
New
(
session
.
New
(
stsConfig
),
stsConfig
)
resp
,
err
:=
svc
.
AssumeRole
(
params
)
if
err
!=
nil
{
...
...
@@ -115,9 +149,14 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
SessionToken
:
sessionToken
,
}},
&
credentials
.
EnvProvider
{},
&
credentials
.
SharedCredentialsProvider
{
Filename
:
""
,
Profile
:
profile
},
&
credentials
.
StaticProvider
{
Value
:
credentials
.
Value
{
AccessKeyID
:
dsInfo
.
AccessKey
,
SecretAccessKey
:
dsInfo
.
SecretKey
,
}},
&
credentials
.
SharedCredentialsProvider
{
Filename
:
""
,
Profile
:
dsInfo
.
Profile
},
&
ec2rolecreds
.
EC2RoleProvider
{
Client
:
ec2metadata
.
New
(
sess
),
ExpiryWindow
:
5
*
time
.
Minute
},
})
credentialCacheLock
.
Lock
()
awsCredentialCache
[
cacheKey
]
=
cache
{
credential
:
creds
,
...
...
@@ -129,10 +168,9 @@ func getCredentials(profile string, region string, assumeRoleArn string) *creden
}
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
,
req
.
Region
,
assumeRoleArn
),
Credentials
:
getCredentials
(
req
.
GetDatasourceInfo
()
),
}
return
cfg
}
...
...
pkg/api/cloudwatch/metrics.go
View file @
3c662ade
...
...
@@ -192,8 +192,10 @@ func handleGetMetrics(req *cwRequest, c *middleware.Context) {
}
}
else
{
var
err
error
assumeRoleArn
:=
req
.
DataSource
.
JsonData
.
Get
(
"assumeRoleArn"
)
.
MustString
()
if
namespaceMetrics
,
err
=
getMetricsForCustomMetrics
(
req
.
Region
,
reqParam
.
Parameters
.
Namespace
,
req
.
DataSource
.
Database
,
assumeRoleArn
,
getAllMetrics
);
err
!=
nil
{
cwData
:=
req
.
GetDatasourceInfo
()
cwData
.
Namespace
=
reqParam
.
Parameters
.
Namespace
if
namespaceMetrics
,
err
=
getMetricsForCustomMetrics
(
cwData
,
getAllMetrics
);
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Unable to call AWS API"
,
err
)
return
}
...
...
@@ -226,8 +228,10 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
}
}
else
{
var
err
error
assumeRoleArn
:=
req
.
DataSource
.
JsonData
.
Get
(
"assumeRoleArn"
)
.
MustString
()
if
dimensionValues
,
err
=
getDimensionsForCustomMetrics
(
req
.
Region
,
reqParam
.
Parameters
.
Namespace
,
req
.
DataSource
.
Database
,
assumeRoleArn
,
getAllMetrics
);
err
!=
nil
{
dsInfo
:=
req
.
GetDatasourceInfo
()
dsInfo
.
Namespace
=
reqParam
.
Parameters
.
Namespace
if
dimensionValues
,
err
=
getDimensionsForCustomMetrics
(
dsInfo
,
getAllMetrics
);
err
!=
nil
{
c
.
JsonApiErr
(
500
,
"Unable to call AWS API"
,
err
)
return
}
...
...
@@ -242,16 +246,16 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
c
.
JSON
(
200
,
result
)
}
func
getAllMetrics
(
region
string
,
namespace
string
,
database
string
,
assumeRoleArn
string
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
func
getAllMetrics
(
cwData
*
datasourceInfo
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
cfg
:=
&
aws
.
Config
{
Region
:
aws
.
String
(
r
egion
),
Credentials
:
getCredentials
(
database
,
region
,
assumeRoleArn
),
Region
:
aws
.
String
(
cwData
.
R
egion
),
Credentials
:
getCredentials
(
cwData
),
}
svc
:=
cloudwatch
.
New
(
session
.
New
(
cfg
),
cfg
)
params
:=
&
cloudwatch
.
ListMetricsInput
{
Namespace
:
aws
.
String
(
n
amespace
),
Namespace
:
aws
.
String
(
cwData
.
N
amespace
),
}
var
resp
cloudwatch
.
ListMetricsOutput
...
...
@@ -272,8 +276,8 @@ func getAllMetrics(region string, namespace string, database string, assumeRoleA
var
metricsCacheLock
sync
.
Mutex
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
)
func
getMetricsForCustomMetrics
(
dsInfo
*
datasourceInfo
,
getAllMetrics
func
(
*
datasourceInfo
)
(
cloudwatch
.
ListMetricsOutput
,
error
))
([]
string
,
error
)
{
result
,
err
:=
getAllMetrics
(
dsInfo
)
if
err
!=
nil
{
return
[]
string
{},
err
}
...
...
@@ -281,37 +285,37 @@ func getMetricsForCustomMetrics(region string, namespace string, database string
metricsCacheLock
.
Lock
()
defer
metricsCacheLock
.
Unlock
()
if
_
,
ok
:=
customMetricsMetricsMap
[
d
atabas
e
];
!
ok
{
customMetricsMetricsMap
[
d
atabas
e
]
=
make
(
map
[
string
]
map
[
string
]
*
CustomMetricsCache
)
if
_
,
ok
:=
customMetricsMetricsMap
[
d
sInfo
.
Profil
e
];
!
ok
{
customMetricsMetricsMap
[
d
sInfo
.
Profil
e
]
=
make
(
map
[
string
]
map
[
string
]
*
CustomMetricsCache
)
}
if
_
,
ok
:=
customMetricsMetricsMap
[
d
atabase
][
r
egion
];
!
ok
{
customMetricsMetricsMap
[
d
atabase
][
r
egion
]
=
make
(
map
[
string
]
*
CustomMetricsCache
)
if
_
,
ok
:=
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
R
egion
];
!
ok
{
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
R
egion
]
=
make
(
map
[
string
]
*
CustomMetricsCache
)
}
if
_
,
ok
:=
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
];
!
ok
{
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
=
&
CustomMetricsCache
{}
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
=
make
([]
string
,
0
)
if
_
,
ok
:=
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
];
!
ok
{
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
=
&
CustomMetricsCache
{}
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
=
make
([]
string
,
0
)
}
if
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Expire
.
After
(
time
.
Now
())
{
return
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
nil
if
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Expire
.
After
(
time
.
Now
())
{
return
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
nil
}
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
=
make
([]
string
,
0
)
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Expire
=
time
.
Now
()
.
Add
(
5
*
time
.
Minute
)
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
=
make
([]
string
,
0
)
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Expire
=
time
.
Now
()
.
Add
(
5
*
time
.
Minute
)
for
_
,
metric
:=
range
result
.
Metrics
{
if
isDuplicate
(
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
*
metric
.
MetricName
)
{
if
isDuplicate
(
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
*
metric
.
MetricName
)
{
continue
}
customMetricsMetricsMap
[
d
atabase
][
region
][
namespace
]
.
Cache
=
append
(
customMetricsMetricsMap
[
database
][
region
][
n
amespace
]
.
Cache
,
*
metric
.
MetricName
)
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
Namespace
]
.
Cache
=
append
(
customMetricsMetricsMap
[
dsInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
*
metric
.
MetricName
)
}
return
customMetricsMetricsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
nil
return
customMetricsMetricsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
nil
}
var
dimensionsCacheLock
sync
.
Mutex
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
)
func
getDimensionsForCustomMetrics
(
dsInfo
*
datasourceInfo
,
getAllMetrics
func
(
*
datasourceInfo
)
(
cloudwatch
.
ListMetricsOutput
,
error
))
([]
string
,
error
)
{
result
,
err
:=
getAllMetrics
(
dsInfo
)
if
err
!=
nil
{
return
[]
string
{},
err
}
...
...
@@ -319,33 +323,33 @@ func getDimensionsForCustomMetrics(region string, namespace string, database str
dimensionsCacheLock
.
Lock
()
defer
dimensionsCacheLock
.
Unlock
()
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
atabas
e
];
!
ok
{
customMetricsDimensionsMap
[
d
atabas
e
]
=
make
(
map
[
string
]
map
[
string
]
*
CustomMetricsCache
)
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
sInfo
.
Profil
e
];
!
ok
{
customMetricsDimensionsMap
[
d
sInfo
.
Profil
e
]
=
make
(
map
[
string
]
map
[
string
]
*
CustomMetricsCache
)
}
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
atabase
][
r
egion
];
!
ok
{
customMetricsDimensionsMap
[
d
atabase
][
r
egion
]
=
make
(
map
[
string
]
*
CustomMetricsCache
)
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
R
egion
];
!
ok
{
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
R
egion
]
=
make
(
map
[
string
]
*
CustomMetricsCache
)
}
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
];
!
ok
{
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
=
&
CustomMetricsCache
{}
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
=
make
([]
string
,
0
)
if
_
,
ok
:=
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
];
!
ok
{
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
=
&
CustomMetricsCache
{}
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
=
make
([]
string
,
0
)
}
if
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Expire
.
After
(
time
.
Now
())
{
return
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
nil
if
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Expire
.
After
(
time
.
Now
())
{
return
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
nil
}
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
=
make
([]
string
,
0
)
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Expire
=
time
.
Now
()
.
Add
(
5
*
time
.
Minute
)
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
=
make
([]
string
,
0
)
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Expire
=
time
.
Now
()
.
Add
(
5
*
time
.
Minute
)
for
_
,
metric
:=
range
result
.
Metrics
{
for
_
,
dimension
:=
range
metric
.
Dimensions
{
if
isDuplicate
(
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
*
dimension
.
Name
)
{
if
isDuplicate
(
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
*
dimension
.
Name
)
{
continue
}
customMetricsDimensionsMap
[
d
atabase
][
region
][
namespace
]
.
Cache
=
append
(
customMetricsDimensionsMap
[
database
][
region
][
n
amespace
]
.
Cache
,
*
dimension
.
Name
)
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
Namespace
]
.
Cache
=
append
(
customMetricsDimensionsMap
[
dsInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
*
dimension
.
Name
)
}
}
return
customMetricsDimensionsMap
[
d
atabase
][
region
][
n
amespace
]
.
Cache
,
nil
return
customMetricsDimensionsMap
[
d
sInfo
.
Profile
][
dsInfo
.
Region
][
dsInfo
.
N
amespace
]
.
Cache
,
nil
}
func
isDuplicate
(
nameList
[]
string
,
target
string
)
bool
{
...
...
pkg/api/cloudwatch/metrics_test.go
View file @
3c662ade
...
...
@@ -11,11 +11,13 @@ import (
func
TestCloudWatchMetrics
(
t
*
testing
.
T
)
{
Convey
(
"When calling getMetricsForCustomMetrics"
,
t
,
func
()
{
region
:=
"us-east-1"
namespace
:=
"Foo"
database
:=
"default"
assumeRoleArn
:=
""
f
:=
func
(
region
string
,
namespace
string
,
database
string
,
assumeRoleArn
string
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
dsInfo
:=
&
datasourceInfo
{
Region
:
"us-east-1"
,
Namespace
:
"Foo"
,
Profile
:
"default"
,
AssumeRoleArn
:
""
,
}
f
:=
func
(
dsInfo
*
datasourceInfo
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
return
cloudwatch
.
ListMetricsOutput
{
Metrics
:
[]
*
cloudwatch
.
Metric
{
{
...
...
@@ -29,7 +31,7 @@ func TestCloudWatchMetrics(t *testing.T) {
},
},
nil
}
metrics
,
_
:=
getMetricsForCustomMetrics
(
region
,
namespace
,
database
,
assumeRoleArn
,
f
)
metrics
,
_
:=
getMetricsForCustomMetrics
(
dsInfo
,
f
)
Convey
(
"Should contain Test_MetricName"
,
func
()
{
So
(
metrics
,
ShouldContain
,
"Test_MetricName"
)
...
...
@@ -37,11 +39,13 @@ func TestCloudWatchMetrics(t *testing.T) {
})
Convey
(
"When calling getDimensionsForCustomMetrics"
,
t
,
func
()
{
region
:=
"us-east-1"
namespace
:=
"Foo"
database
:=
"default"
assumeRoleArn
:=
""
f
:=
func
(
region
string
,
namespace
string
,
database
string
,
assumeRoleArn
string
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
dsInfo
:=
&
datasourceInfo
{
Region
:
"us-east-1"
,
Namespace
:
"Foo"
,
Profile
:
"default"
,
AssumeRoleArn
:
""
,
}
f
:=
func
(
dsInfo
*
datasourceInfo
)
(
cloudwatch
.
ListMetricsOutput
,
error
)
{
return
cloudwatch
.
ListMetricsOutput
{
Metrics
:
[]
*
cloudwatch
.
Metric
{
{
...
...
@@ -55,7 +59,7 @@ func TestCloudWatchMetrics(t *testing.T) {
},
},
nil
}
dimensionKeys
,
_
:=
getDimensionsForCustomMetrics
(
region
,
namespace
,
database
,
assumeRoleArn
,
f
)
dimensionKeys
,
_
:=
getDimensionsForCustomMetrics
(
dsInfo
,
f
)
Convey
(
"Should contain Test_DimensionName"
,
func
()
{
So
(
dimensionKeys
,
ShouldContain
,
"Test_DimensionName"
)
...
...
pkg/api/datasources.go
View file @
3c662ade
...
...
@@ -215,5 +215,11 @@ func convertModelToDtos(ds *m.DataSource) dtos.DataSource {
dto
.
TLSAuth
.
ClientKeySet
=
len
(
ds
.
SecureJsonData
[
"tlsClientKey"
])
>
0
}
for
k
,
v
:=
range
ds
.
SecureJsonData
{
if
len
(
v
)
>
0
{
dto
.
EncryptedFields
=
append
(
dto
.
EncryptedFields
,
k
)
}
}
return
dto
}
pkg/api/dtos/models.go
View file @
3c662ade
...
...
@@ -64,24 +64,24 @@ type DashboardRedirect struct {
}
type
DataSource
struct
{
Id
int64
`json:"id"`
OrgId
int64
`json:"orgId"`
Name
string
`json:"name"`
Type
string
`json:"type"`
TypeLogoUrl
string
`json:"typeLogoUrl"`
Access
m
.
DsAccess
`json:"access"`
Url
string
`json:"url"`
Password
string
`json:"password"`
User
string
`json:"user"`
Database
string
`json:"database"`
BasicAuth
bool
`json:"basicAuth"`
BasicAuthUser
string
`json:"basicAuthUser"`
BasicAuthPassword
string
`json:"basicAuthPassword"`
WithCredentials
bool
`json:"withCredentials"`
IsDefault
bool
`json:"isDefault"`
JsonData
*
simplejson
.
Json
`json:"jsonData,omitempty"`
SecureJsonData
map
[
string
]
string
`json:"secureJsonData
,omitempty"`
TLSAuth
TLSAuth
`json:"tlsAuth,omitempty
"`
Id
int64
`json:"id"`
OrgId
int64
`json:"orgId"`
Name
string
`json:"name"`
Type
string
`json:"type"`
TypeLogoUrl
string
`json:"typeLogoUrl"`
Access
m
.
DsAccess
`json:"access"`
Url
string
`json:"url"`
Password
string
`json:"password"`
User
string
`json:"user"`
Database
string
`json:"database"`
BasicAuth
bool
`json:"basicAuth"`
BasicAuthUser
string
`json:"basicAuthUser"`
BasicAuthPassword
string
`json:"basicAuthPassword"`
WithCredentials
bool
`json:"withCredentials"`
IsDefault
bool
`json:"isDefault"`
JsonData
*
simplejson
.
Json
`json:"jsonData,omitempty"`
TLSAuth
TLSAuth
`json:"tlsAuth
,omitempty"`
EncryptedFields
[]
string
`json:"encryptedFields
"`
}
// TLSAuth is used to show if TLS certs have been uploaded already
...
...
public/app/features/plugins/ds_edit_ctrl.ts
View file @
3c662ade
...
...
@@ -68,7 +68,6 @@ export class DataSourceEditCtrl {
this
.
backendSrv
.
get
(
'/api/datasources/'
+
id
).
then
(
ds
=>
{
this
.
isNew
=
false
;
this
.
current
=
ds
;
if
(
datasourceCreated
)
{
datasourceCreated
=
false
;
this
.
testDatasource
();
...
...
public/app/plugins/datasource/cloudwatch/config_ctrl.ts
0 → 100644
View file @
3c662ade
///<reference path="../../../headers/common.d.ts" />
import
angular
from
'angular'
;
import
_
from
'lodash'
;
export
class
CloudWatchConfigCtrl
{
static
templateUrl
=
'partials/config.html'
;
current
:
any
;
accessKeyExist
:
boolean
=
false
;
secretKeyExist
:
boolean
=
false
;
/** @ngInject */
constructor
(
$scope
)
{
this
.
current
.
jsonData
.
timeField
=
this
.
current
.
jsonData
.
timeField
||
'@timestamp'
;
this
.
current
.
jsonData
.
authType
=
this
.
current
.
jsonData
.
authType
||
'credentials'
;
for
(
let
key
of
this
.
current
.
encryptedFields
)
{
if
(
key
===
"accessKey"
)
{
this
.
accessKeyExist
=
true
;
}
if
(
key
===
"secretKey"
)
{
this
.
secretKeyExist
=
true
;
}
}
}
resetAccessKey
()
{
this
.
accessKeyExist
=
false
;
}
resetSecretKey
()
{
this
.
secretKeyExist
=
false
;
}
authTypes
=
[
{
name
:
'Access & secret key'
,
value
:
'keys'
},
{
name
:
'Credentials file'
,
value
:
'credentials'
},
{
name
:
'ARN'
,
value
:
'arn'
},
];
indexPatternTypes
=
[
{
name
:
'No pattern'
,
value
:
undefined
},
{
name
:
'Hourly'
,
value
:
'Hourly'
,
example
:
'[logstash-]YYYY.MM.DD.HH'
},
{
name
:
'Daily'
,
value
:
'Daily'
,
example
:
'[logstash-]YYYY.MM.DD'
},
{
name
:
'Weekly'
,
value
:
'Weekly'
,
example
:
'[logstash-]GGGG.WW'
},
{
name
:
'Monthly'
,
value
:
'Monthly'
,
example
:
'[logstash-]YYYY.MM'
},
{
name
:
'Yearly'
,
value
:
'Yearly'
,
example
:
'[logstash-]YYYY'
},
];
}
public/app/plugins/datasource/cloudwatch/module.ts
View file @
3c662ade
...
...
@@ -2,10 +2,7 @@ import './query_parameter_ctrl';
import
{
CloudWatchDatasource
}
from
'./datasource'
;
import
{
CloudWatchQueryCtrl
}
from
'./query_ctrl'
;
class
CloudWatchConfigCtrl
{
static
templateUrl
=
'partials/config.html'
;
}
import
{
CloudWatchConfigCtrl
}
from
'./config_ctrl'
;
class
CloudWatchAnnotationsQueryCtrl
{
static
templateUrl
=
'partials/annotations.editor.html'
;
...
...
public/app/plugins/datasource/cloudwatch/partials/config.html
View file @
3c662ade
<h3
class=
"page-heading"
>
CloudWatch details
</h3>
<div
class=
"gf-form-group max-width-30"
>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Credentials profile name
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.database'
placeholder=
"default"
></input>
<info-popover
mode=
"right-absolute"
>
Credentials profile name, as specified in ~/.aws/credentials, leave blank for default
</info-popover>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Default Region
</label>
<div
class=
"gf-form-select-wrapper max-width-18 gf-form-select-wrapper--has-help-icon"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.current.jsonData.defaultRegion"
ng-options=
"region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2']"
></select>
<info-popover
mode=
"right-absolute"
>
Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.
</info-popover>
</div>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Custom Metrics namespace
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.jsonData.customMetricsNamespaces'
placeholder=
"Namespace1,Namespace2"
></input>
<info-popover
mode=
"right-absolute"
>
Namespaces of Custom Metrics
</info-popover>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Assume Role ARN
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.jsonData.assumeRoleArn'
placeholder=
"arn:aws:iam:*"
></input>
<info-popover
mode=
"right-absolute"
>
ARN of Assume Role
</info-popover>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Auth Provider
</label>
<select
class=
"gf-form-input gf-max-width-13"
ng-model=
"ctrl.current.jsonData.authType"
ng-options=
"f.value as f.name for f in ctrl.authTypes"
></select>
</div>
<div
class=
"gf-form"
ng-show=
'ctrl.current.jsonData.authType == "credentials"'
>
<label
class=
"gf-form-label width-13"
>
Credentials profile name
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.database'
placeholder=
"default"
></input>
<info-popover
mode=
"right-absolute"
>
Credentials profile name, as specified in ~/.aws/credentials, leave blank for default
</info-popover>
</div>
<div
class=
"gf-form"
ng-show=
'ctrl.current.jsonData.authType == "keys"'
>
<label
class=
"gf-form-label width-13"
>
Access key
</label>
<label
class=
"gf-form-label width-13"
ng-show=
"ctrl.accessKeyExist"
>
Configured
</label>
<a
class=
"gf-form-button btn btn-danger btn-small"
type=
"submit"
ng-click=
"ctrl.resetAccessKey()"
ng-show=
"ctrl.accessKeyExist"
>
Reset
</a>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-hide=
"ctrl.accessKeyExist"
ng-model=
'ctrl.current.secureJsonData.accessKey'
></input>
</div>
<div
class=
"gf-form"
ng-show=
'ctrl.current.jsonData.authType == "keys"'
>
<label
class=
"gf-form-label width-13"
>
Secret key
</label>
<label
class=
"gf-form-label width-13"
ng-show=
"ctrl.secretKeyExist"
>
Configured
</label>
<a
class=
"btn btn-danger gf-form-button btn-small"
type=
"submit"
ng-click=
"ctrl.resetSecretKey()"
ng-show=
"ctrl.secretKeyExist"
>
Reset
</a>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-hide=
"ctrl.secretKeyExist"
ng-model=
'ctrl.current.secureJsonData.secretKey'
></input>
</div>
<div
class=
"gf-form"
ng-show=
'ctrl.current.jsonData.authType == "arn"'
>
<label
class=
"gf-form-label width-13"
>
Assume Role ARN
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.jsonData.assumeRoleArn'
placeholder=
"arn:aws:iam:*"
></input>
<info-popover
mode=
"right-absolute"
>
ARN of Assume Role
</info-popover>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Default Region
</label>
<div
class=
"gf-form-select-wrapper max-width-18 gf-form-select-wrapper--has-help-icon"
>
<select
class=
"gf-form-input"
ng-model=
"ctrl.current.jsonData.defaultRegion"
ng-options=
"region for region in ['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-south-1', 'cn-north-1', 'eu-central-1', 'eu-west-1', 'sa-east-1', 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2']"
></select>
<info-popover
mode=
"right-absolute"
>
Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region.
</info-popover>
</div>
</div>
<div
class=
"gf-form"
>
<label
class=
"gf-form-label width-13"
>
Custom Metrics namespace
</label>
<input
type=
"text"
class=
"gf-form-input max-width-18"
ng-model=
'ctrl.current.jsonData.customMetricsNamespaces'
placeholder=
"Namespace1,Namespace2"
></input>
<info-popover
mode=
"right-absolute"
>
Namespaces of Custom Metrics
</info-popover>
</div>
</div>
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