Merged with master, resolved conflicts

This commit is contained in:
utkarshcmu
2015-12-18 00:23:08 -08:00
229 changed files with 4350 additions and 3690 deletions
+8 -4
View File
@@ -13,7 +13,7 @@ func Register(r *macaron.Macaron) {
reqSignedIn := middleware.Auth(&middleware.AuthOptions{ReqSignedIn: true})
reqGrafanaAdmin := middleware.Auth(&middleware.AuthOptions{ReqSignedIn: true, ReqGrafanaAdmin: true})
reqEditorRole := middleware.RoleAuth(m.ROLE_EDITOR, m.ROLE_ADMIN)
regOrgAdmin := middleware.RoleAuth(m.ROLE_ADMIN)
reqOrgAdmin := middleware.RoleAuth(m.ROLE_ADMIN)
quota := middleware.Quota
bind := binding.Bind
@@ -41,6 +41,9 @@ func Register(r *macaron.Macaron) {
r.Get("/admin/orgs", reqGrafanaAdmin, Index)
r.Get("/admin/orgs/edit/:id", reqGrafanaAdmin, Index)
r.Get("/plugins", reqSignedIn, Index)
r.Get("/plugins/edit/*", reqSignedIn, Index)
r.Get("/dashboard/*", reqSignedIn, Index)
r.Get("/dashboard-solo/*", reqSignedIn, Index)
@@ -65,6 +68,7 @@ func Register(r *macaron.Macaron) {
r.Post("/api/snapshots/", bind(m.CreateDashboardSnapshotCommand{}), CreateDashboardSnapshot)
r.Get("/dashboard/snapshot/*", Index)
r.Get("/api/snapshot/shared-options/", GetSharingOptions)
r.Get("/api/snapshots/:key", GetDashboardSnapshot)
r.Get("/api/snapshots-delete/:key", DeleteDashboardSnapshot)
@@ -113,7 +117,7 @@ func Register(r *macaron.Macaron) {
r.Get("/invites", wrap(GetPendingOrgInvites))
r.Post("/invites", quota("user"), bind(dtos.AddInviteForm{}), wrap(AddOrgInvite))
r.Patch("/invites/:code/revoke", wrap(RevokeInvite))
}, regOrgAdmin)
}, reqOrgAdmin)
// create new org
r.Post("/orgs", quota("org"), bind(m.CreateOrgCommand{}), wrap(CreateOrg))
@@ -140,7 +144,7 @@ func Register(r *macaron.Macaron) {
r.Get("/", wrap(GetApiKeys))
r.Post("/", quota("api_key"), bind(m.AddApiKeyCommand{}), wrap(AddApiKey))
r.Delete("/:id", wrap(DeleteApiKey))
}, regOrgAdmin)
}, reqOrgAdmin)
// Data sources
r.Group("/datasources", func() {
@@ -150,7 +154,7 @@ func Register(r *macaron.Macaron) {
r.Delete("/:id", DeleteDataSource)
r.Get("/:id", wrap(GetDataSourceById))
r.Get("/plugins", GetDataSourcePlugins)
}, regOrgAdmin)
}, reqOrgAdmin)
r.Get("/frontend/settings/", GetFrontendSettings)
r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest)
+120 -9
View File
@@ -7,6 +7,7 @@ import (
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
@@ -30,13 +31,15 @@ type cwRequest struct {
func init() {
actionHandlers = map[string]actionHandler{
"GetMetricStatistics": handleGetMetricStatistics,
"ListMetrics": handleListMetrics,
"DescribeInstances": handleDescribeInstances,
"__GetRegions": handleGetRegions,
"__GetNamespaces": handleGetNamespaces,
"__GetMetrics": handleGetMetrics,
"__GetDimensions": handleGetDimensions,
"GetMetricStatistics": handleGetMetricStatistics,
"ListMetrics": handleListMetrics,
"DescribeAlarmsForMetric": handleDescribeAlarmsForMetric,
"DescribeAlarmHistory": handleDescribeAlarmHistory,
"DescribeInstances": handleDescribeInstances,
"__GetRegions": handleGetRegions,
"__GetNamespaces": handleGetNamespaces,
"__GetMetrics": handleGetMetrics,
"__GetDimensions": handleGetDimensions,
}
}
@@ -119,7 +122,107 @@ func handleListMetrics(req *cwRequest, c *middleware.Context) {
Dimensions: reqParam.Parameters.Dimensions,
}
resp, err := svc.ListMetrics(params)
var resp cloudwatch.ListMetricsOutput
err := svc.ListMetricsPages(params,
func(page *cloudwatch.ListMetricsOutput, lastPage bool) bool {
metrics, _ := awsutil.ValuesAtPath(page, "Metrics")
for _, metric := range metrics {
resp.Metrics = append(resp.Metrics, metric.(*cloudwatch.Metric))
}
return !lastPage
})
if err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
}
c.JSON(200, resp)
}
func handleDescribeAlarmsForMetric(req *cwRequest, c *middleware.Context) {
sess := session.New()
creds := credentials.NewChainCredentials(
[]credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: req.DataSource.Database},
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
})
cfg := &aws.Config{
Region: aws.String(req.Region),
Credentials: creds,
}
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
Parameters struct {
Namespace string `json:"namespace"`
MetricName string `json:"metricName"`
Dimensions []*cloudwatch.Dimension `json:"dimensions"`
Statistic string `json:"statistic"`
Period int64 `json:"period"`
} `json:"parameters"`
}{}
json.Unmarshal(req.Body, reqParam)
params := &cloudwatch.DescribeAlarmsForMetricInput{
Namespace: aws.String(reqParam.Parameters.Namespace),
MetricName: aws.String(reqParam.Parameters.MetricName),
Period: aws.Int64(reqParam.Parameters.Period),
}
if len(reqParam.Parameters.Dimensions) != 0 {
params.Dimensions = reqParam.Parameters.Dimensions
}
if reqParam.Parameters.Statistic != "" {
params.Statistic = aws.String(reqParam.Parameters.Statistic)
}
resp, err := svc.DescribeAlarmsForMetric(params)
if err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
}
c.JSON(200, resp)
}
func handleDescribeAlarmHistory(req *cwRequest, c *middleware.Context) {
sess := session.New()
creds := credentials.NewChainCredentials(
[]credentials.Provider{
&credentials.EnvProvider{},
&credentials.SharedCredentialsProvider{Filename: "", Profile: req.DataSource.Database},
&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(sess), ExpiryWindow: 5 * time.Minute},
})
cfg := &aws.Config{
Region: aws.String(req.Region),
Credentials: creds,
}
svc := cloudwatch.New(session.New(cfg), cfg)
reqParam := &struct {
Parameters struct {
AlarmName string `json:"alarmName"`
HistoryItemType string `json:"historyItemType"`
StartDate int64 `json:"startDate"`
EndDate int64 `json:"endDate"`
} `json:"parameters"`
}{}
json.Unmarshal(req.Body, reqParam)
params := &cloudwatch.DescribeAlarmHistoryInput{
AlarmName: aws.String(reqParam.Parameters.AlarmName),
StartDate: aws.Time(time.Unix(reqParam.Parameters.StartDate, 0)),
EndDate: aws.Time(time.Unix(reqParam.Parameters.EndDate, 0)),
}
if reqParam.Parameters.HistoryItemType != "" {
params.HistoryItemType = aws.String(reqParam.Parameters.HistoryItemType)
}
resp, err := svc.DescribeAlarmHistory(params)
if err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
@@ -160,7 +263,15 @@ func handleDescribeInstances(req *cwRequest, c *middleware.Context) {
params.InstanceIds = reqParam.Parameters.InstanceIds
}
resp, err := svc.DescribeInstances(params)
var resp ec2.DescribeInstancesOutput
err := svc.DescribeInstancesPages(params,
func(page *ec2.DescribeInstancesOutput, lastPage bool) bool {
reservations, _ := awsutil.ValuesAtPath(page, "Reservations")
for _, reservation := range reservations {
resp.Reservations = append(resp.Reservations, reservation.(*ec2.Reservation))
}
return !lastPage
})
if err != nil {
c.JsonApiErr(500, "Unable to call AWS API", err)
return
+43 -22
View File
@@ -15,31 +15,47 @@ func init() {
metricsMap = map[string][]string{
"AWS/AutoScaling": {"GroupMinSize", "GroupMaxSize", "GroupDesiredCapacity", "GroupInServiceInstances", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"},
"AWS/Billing": {"EstimatedCharges"},
"AWS/EC2": {"CPUCreditUsage", "CPUCreditBalance", "CPUUtilization", "DiskReadOps", "DiskWriteOps", "DiskReadBytes", "DiskWriteBytes", "NetworkIn", "NetworkOut", "StatusCheckFailed", "StatusCheckFailed_Instance", "StatusCheckFailed_System"},
"AWS/ECS": {"CPUUtilization", "MemoryUtilization"},
"AWS/CloudFront": {"Requests", "BytesDownloaded", "BytesUploaded", "TotalErrorRate", "4xxErrorRate", "5xxErrorRate"},
"AWS/CloudSearch": {"SuccessfulRequests", "SearchableDocuments", "IndexUtilization", "Partitions"},
"AWS/DynamoDB": {"ConditionalCheckFailedRequests", "ConsumedReadCapacityUnits", "ConsumedWriteCapacityUnits", "OnlineIndexConsumedWriteCapacity", "OnlineIndexPercentageProgress", "OnlineIndexThrottleEvents", "ProvisionedReadCapacityUnits", "ProvisionedWriteCapacityUnits", "ReadThrottleEvents", "ReturnedItemCount", "SuccessfulRequestLatency", "SystemErrors", "ThrottledRequests", "UserErrors", "WriteThrottleEvents"},
"AWS/ECS": {"CPUUtilization", "MemoryUtilization"},
"AWS/ElastiCache": {
"CPUUtilization", "SwapUsage", "FreeableMemory", "NetworkBytesIn", "NetworkBytesOut",
"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",
"CurrConnections", "Evictions", "Reclaimed", "NewConnections", "BytesUsedForCache", "CacheHits", "CacheMisses", "ReplicationLag", "GetTypeCmds", "SetTypeCmds", "KeyBasedCmds", "StringBasedCmds", "HashBasedCmds", "ListBasedCmds", "SetBasedCmds", "SortedSetBasedCmds", "CurrItems",
"BytesUsedForHash", "CmdConfigGet", "CmdConfigSet", "CmdTouch", "CurrConfig", "EvictedUnfetched", "ExpiredUnfetched", "SlabsMoved", "TouchHits", "TouchMisses",
"NewConnections", "NewItems", "UnusedMemory",
"BytesUsedForCache", "CacheHits", "CacheMisses", "CurrConnections", "Evictions", "HyperLogLogBasedCmds", "NewConnections", "Reclaimed", "ReplicationBytes", "ReplicationLag", "SaveInProgress",
"CurrItems", "GetTypeCmds", "HashBasedCmds", "KeyBasedCmds", "ListBasedCmds", "SetBasedCmds", "SetTypeCmds", "SortedSetBasedCmds", "StringBasedCmds",
},
"AWS/EBS": {"VolumeReadBytes", "VolumeWriteBytes", "VolumeReadOps", "VolumeWriteOps", "VolumeTotalReadTime", "VolumeTotalWriteTime", "VolumeIdleTime", "VolumeQueueLength", "VolumeThroughputPercentage", "VolumeConsumedReadWriteOps"},
"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/ElasticMapReduce": {"CoreNodesPending", "CoreNodesRunning", "HBaseBackupFailed", "HBaseMostRecentBackupDuration", "HBaseTimeSinceLastSuccessfulBackup", "HDFSBytesRead", "HDFSBytesWritten", "HDFSUtilization", "IsIdle", "JobsFailed", "JobsRunning", "LiveDataNodes", "LiveTaskTrackers", "MapSlotsOpen", "MissingBlocks", "ReduceSlotsOpen", "RemainingMapTasks", "RemainingMapTasksPerSlot", "RemainingReduceTasks", "RunningMapTasks", "RunningReduceTasks", "S3BytesRead", "S3BytesWritten", "TaskNodesPending", "TaskNodesRunning", "TotalLoad"},
"AWS/Kinesis": {"PutRecord.Bytes", "PutRecord.Latency", "PutRecord.Success", "PutRecords.Bytes", "PutRecords.Latency", "PutRecords.Records", "PutRecords.Success", "IncomingBytes", "IncomingRecords", "GetRecords.Bytes", "GetRecords.IteratorAgeMilliseconds", "GetRecords.Latency", "GetRecords.Success"},
"AWS/ML": {"PredictCount", "PredictFailureCount"},
"AWS/OpsWorks": {"cpu_idle", "cpu_nice", "cpu_system", "cpu_user", "cpu_waitio", "load_1", "load_5", "load_15", "memory_buffers", "memory_cached", "memory_free", "memory_swap", "memory_total", "memory_used", "procs"},
"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
"AWS/RDS": {"BinLogDiskUsage", "CPUUtilization", "DatabaseConnections", "DiskQueueDepth", "FreeableMemory", "FreeStorageSpace", "ReplicaLag", "SwapUsage", "ReadIOPS", "WriteIOPS", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "NetworkReceiveThroughput", "NetworkTransmitThroughput"},
"AWS/Route53": {"HealthCheckStatus", "HealthCheckPercentageHealthy"},
"AWS/SNS": {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"},
"AWS/SQS": {"NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"},
"AWS/S3": {"BucketSizeBytes", "NumberOfObjects"},
"AWS/SWF": {"DecisionTaskScheduleToStartTime", "DecisionTaskStartToCloseTime", "DecisionTasksCompleted", "StartedDecisionTasksTimedOutOnClose", "WorkflowStartToCloseTime", "WorkflowsCanceled", "WorkflowsCompleted", "WorkflowsContinuedAsNew", "WorkflowsFailed", "WorkflowsTerminated", "WorkflowsTimedOut"},
"AWS/StorageGateway": {"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "CloudBytesDownloaded", "CloudDownloadLatency", "CloudBytesUploaded", "UploadBufferFree", "UploadBufferPercentUsed", "UploadBufferUsed", "QueuedWrites", "ReadBytes", "ReadTime", "TotalCacheSize", "WriteBytes", "WriteTime", "WorkingStorageFree", "WorkingStoragePercentUsed", "WorkingStorageUsed", "CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "ReadBytes", "ReadTime", "WriteBytes", "WriteTime", "QueuedWrites"},
"AWS/WorkSpaces": {"Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"},
"AWS/EBS": {"VolumeReadBytes", "VolumeWriteBytes", "VolumeReadOps", "VolumeWriteOps", "VolumeTotalReadTime", "VolumeTotalWriteTime", "VolumeIdleTime", "VolumeQueueLength", "VolumeThroughputPercentage", "VolumeConsumedReadWriteOps"},
"AWS/EC2": {"CPUCreditUsage", "CPUCreditBalance", "CPUUtilization", "DiskReadOps", "DiskWriteOps", "DiskReadBytes", "DiskWriteBytes", "NetworkIn", "NetworkOut", "StatusCheckFailed", "StatusCheckFailed_Instance", "StatusCheckFailed_System"},
"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/ElasticMapReduce": {"IsIdle", "JobsRunning", "JobsFailed",
"MapTasksRunning", "MapTasksRemaining", "MapSlotsOpen", "RemainingMapTasksPerSlot", "ReduceTasksRunning", "ReduceTasksRemaining", "ReduceSlotsOpen",
"CoreNodesRunning", "CoreNodesPending", "LiveDataNodes", "TaskNodesRunning", "TaskNodesPending", "LiveTaskTrackers",
"S3BytesWritten", "S3BytesRead", "HDFSUtilization", "HDFSBytesRead", "HDFSBytesWritten", "MissingBlocks", "TotalLoad",
"BackupFailed", "MostRecentBackupDuration", "TimeSinceLastSuccessfulBackup",
"IsIdle", "ContainerAllocated", "ContainerReserved", "ContainerPending", "AppsCompleted", "AppsFailed", "AppsKilled", "AppsPending", "AppsRunning", "AppsSubmitted",
"CoreNodesRunning", "CoreNodesPending", "LiveDataNodes", "MRTotalNodes", "MRActiveNodes", "MRLostNodes", "MRUnhealthyNodes", "MRDecommissionedNodes", "MRRebootedNodes",
"S3BytesWritten", "S3BytesRead", "HDFSUtilization", "HDFSBytesRead", "HDFSBytesWritten", "MissingBlocks", "CorruptBlocks", "TotalLoad", "MemoryTotalMB", "MemoryReservedMB", "MemoryAvailableMB", "MemoryAllocatedMB", "PendingDeletionBlocks", "UnderReplicatedBlocks", "DfsPendingReplicationBlocks", "CapacityRemainingGB",
"HbaseBackupFailed", "MostRecentBackupDuration", "TimeSinceLastSuccessfulBackup"},
"AWS/ES": {"ClusterStatus.green", "ClusterStatus.yellow", "ClusterStatus.red", "Nodes", "SearchableDocuments", "DeletedDocuments", "CPUUtilization", "FreeStorageSpace", "JVMMemoryPressure", "AutomatedSnapshotFailure", "MasterCPUUtilization", "MasterFreeStorageSpace", "MasterJVMMemoryPressure", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "DiskQueueLength", "ReadIOPS", "WriteIOPS"},
"AWS/Kinesis": {"PutRecord.Bytes", "PutRecord.Latency", "PutRecord.Success", "PutRecords.Bytes", "PutRecords.Latency", "PutRecords.Records", "PutRecords.Success", "IncomingBytes", "IncomingRecords", "GetRecords.Bytes", "GetRecords.IteratorAgeMilliseconds", "GetRecords.Latency", "GetRecords.Success"},
"AWS/Lambda": {"Invocations", "Errors", "Duration", "Throttles"},
"AWS/ML": {"PredictCount", "PredictFailureCount"},
"AWS/OpsWorks": {"cpu_idle", "cpu_nice", "cpu_system", "cpu_user", "cpu_waitio", "load_1", "load_5", "load_15", "memory_buffers", "memory_cached", "memory_free", "memory_swap", "memory_total", "memory_used", "procs"},
"AWS/Redshift": {"CPUUtilization", "DatabaseConnections", "HealthStatus", "MaintenanceMode", "NetworkReceiveThroughput", "NetworkTransmitThroughput", "PercentageDiskSpaceUsed", "ReadIOPS", "ReadLatency", "ReadThroughput", "WriteIOPS", "WriteLatency", "WriteThroughput"},
"AWS/RDS": {"BinLogDiskUsage", "CPUUtilization", "CPUCreditUsage", "CPUCreditBalance", "DatabaseConnections", "DiskQueueDepth", "FreeableMemory", "FreeStorageSpace", "ReplicaLag", "SwapUsage", "ReadIOPS", "WriteIOPS", "ReadLatency", "WriteLatency", "ReadThroughput", "WriteThroughput", "NetworkReceiveThroughput", "NetworkTransmitThroughput"},
"AWS/Route53": {"HealthCheckStatus", "HealthCheckPercentageHealthy"},
"AWS/SNS": {"NumberOfMessagesPublished", "PublishSize", "NumberOfNotificationsDelivered", "NumberOfNotificationsFailed"},
"AWS/SQS": {"NumberOfMessagesSent", "SentMessageSize", "NumberOfMessagesReceived", "NumberOfEmptyReceives", "NumberOfMessagesDeleted", "ApproximateNumberOfMessagesDelayed", "ApproximateNumberOfMessagesVisible", "ApproximateNumberOfMessagesNotVisible"},
"AWS/S3": {"BucketSizeBytes", "NumberOfObjects"},
"AWS/SWF": {"DecisionTaskScheduleToStartTime", "DecisionTaskStartToCloseTime", "DecisionTasksCompleted", "StartedDecisionTasksTimedOutOnClose", "WorkflowStartToCloseTime", "WorkflowsCanceled", "WorkflowsCompleted", "WorkflowsContinuedAsNew", "WorkflowsFailed", "WorkflowsTerminated", "WorkflowsTimedOut",
"ActivityTaskScheduleToCloseTime", "ActivityTaskScheduleToStartTime", "ActivityTaskStartToCloseTime", "ActivityTasksCanceled", "ActivityTasksCompleted", "ActivityTasksFailed", "ScheduledActivityTasksTimedOutOnClose", "ScheduledActivityTasksTimedOutOnStart", "StartedActivityTasksTimedOutOnClose", "StartedActivityTasksTimedOutOnHeartbeat"},
"AWS/StorageGateway": {"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "CloudBytesDownloaded", "CloudDownloadLatency", "CloudBytesUploaded", "UploadBufferFree", "UploadBufferPercentUsed", "UploadBufferUsed", "QueuedWrites", "ReadBytes", "ReadTime", "TotalCacheSize", "WriteBytes", "WriteTime", "TimeSinceLastRecoveryPoint", "WorkingStorageFree", "WorkingStoragePercentUsed", "WorkingStorageUsed",
"CacheHitPercent", "CachePercentUsed", "CachePercentDirty", "ReadBytes", "ReadTime", "WriteBytes", "WriteTime", "QueuedWrites"},
"AWS/WAF": {"AllowedRequests", "BlockedRequests", "CountedRequests"},
"AWS/WorkSpaces": {"Available", "Unhealthy", "ConnectionAttempt", "ConnectionSuccess", "ConnectionFailure", "SessionLaunchTime", "InSessionLatency", "SessionDisconnect"},
}
dimensionsMap = map[string][]string{
"AWS/AutoScaling": {"AutoScalingGroupName"},
@@ -47,13 +63,15 @@ func init() {
"AWS/CloudFront": {"DistributionId", "Region"},
"AWS/CloudSearch": {},
"AWS/DynamoDB": {"TableName", "GlobalSecondaryIndexName", "Operation"},
"AWS/ECS": {"ClusterName", "ServiceName"},
"AWS/ElastiCache": {"CacheClusterId", "CacheNodeId"},
"AWS/EBS": {"VolumeId"},
"AWS/EC2": {"AutoScalingGroupName", "ImageId", "InstanceId", "InstanceType"},
"AWS/ECS": {"ClusterName", "ServiceName"},
"AWS/ELB": {"LoadBalancerName", "AvailabilityZone"},
"AWS/ElasticMapReduce": {"ClusterId", "JobId"},
"AWS/ElasticMapReduce": {"ClusterId", "JobFlowId", "JobId"},
"AWS/ES": {},
"AWS/Kinesis": {"StreamName"},
"AWS/Lambda": {"FunctionName"},
"AWS/ML": {"MLModelId", "RequestMode"},
"AWS/OpsWorks": {"StackId", "LayerId", "InstanceId"},
"AWS/Redshift": {"NodeID", "ClusterIdentifier"},
@@ -62,8 +80,9 @@ func init() {
"AWS/SNS": {"Application", "Platform", "TopicName"},
"AWS/SQS": {"QueueName"},
"AWS/S3": {"BucketName", "StorageType"},
"AWS/SWF": {"Domain", "ActivityTypeName", "ActivityTypeVersion"},
"AWS/SWF": {"Domain", "WorkflowTypeName", "WorkflowTypeVersion", "ActivityTypeName", "ActivityTypeVersion"},
"AWS/StorageGateway": {"GatewayId", "GatewayName", "VolumeId"},
"AWS/WAF": {"Rule", "WebACL"},
"AWS/WorkSpaces": {"DirectoryId", "WorkspaceId"},
}
}
@@ -113,6 +132,7 @@ func handleGetMetrics(req *cwRequest, c *middleware.Context) {
c.JsonApiErr(404, "Unable to find namespace "+reqParam.Parameters.Namespace, nil)
return
}
sort.Sort(sort.StringSlice(namespaceMetrics))
result := []interface{}{}
for _, name := range namespaceMetrics {
@@ -136,6 +156,7 @@ func handleGetDimensions(req *cwRequest, c *middleware.Context) {
c.JsonApiErr(404, "Unable to find dimension "+reqParam.Parameters.Namespace, nil)
return
}
sort.Sort(sort.StringSlice(dimensionValues))
result := []interface{}{}
for _, name := range dimensionValues {
+8
View File
@@ -12,6 +12,14 @@ import (
"github.com/grafana/grafana/pkg/util"
)
func GetSharingOptions(c *middleware.Context) {
c.JSON(200, util.DynMap{
"externalSnapshotURL": setting.ExternalSnapshotUrl,
"externalSnapshotName": setting.ExternalSnapshotName,
"externalEnabled": setting.ExternalEnabled,
})
}
func CreateDashboardSnapshot(c *middleware.Context, cmd m.CreateDashboardSnapshotCommand) {
if cmd.External {
// external snapshot ref requires key and delete key
+2 -1
View File
@@ -65,6 +65,7 @@ func GetDataSourceById(c *middleware.Context) Response {
BasicAuth: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser,
BasicAuthPassword: ds.BasicAuthPassword,
WithCredentials: ds.WithCredentials,
IsDefault: ds.IsDefault,
JsonData: ds.JsonData,
})
@@ -117,7 +118,7 @@ func GetDataSourcePlugins(c *middleware.Context) {
dsList := make(map[string]interface{})
for key, value := range plugins.DataSources {
if value.(map[string]interface{})["builtIn"] == nil {
if !value.BuiltIn {
dsList[key] = value
}
}
+25
View File
@@ -0,0 +1,25 @@
package dtos
type IndexViewData struct {
User *CurrentUser
Settings map[string]interface{}
AppUrl string
AppSubUrl string
GoogleAnalyticsId string
GoogleTagManagerId string
PluginCss []*PluginCss
PluginJs []string
MainNavLinks []*NavLink
}
type PluginCss struct {
Light string `json:"light"`
Dark string `json:"dark"`
}
type NavLink struct {
Text string `json:"text"`
Icon string `json:"icon"`
Href string `json:"href"`
}
+8
View File
@@ -0,0 +1,8 @@
package dtos
type PluginBundle struct {
Type string `json:"type"`
Enabled bool `json:"enabled"`
Module string `json:"module"`
JsonData map[string]interface{} `json:"jsonData"`
}
+13
View File
@@ -62,6 +62,9 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
if ds.BasicAuth {
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.BasicAuthPassword)
}
if ds.WithCredentials {
dsMap["withCredentials"] = ds.WithCredentials
}
if ds.Type == m.DS_INFLUXDB_08 {
dsMap["username"] = ds.User
@@ -106,11 +109,21 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
defaultDatasource = "-- Grafana --"
}
panels := map[string]interface{}{}
for _, panel := range plugins.Panels {
panels[panel.Type] = map[string]interface{}{
"module": panel.Module,
"name": panel.Name,
}
}
jsonObj := map[string]interface{}{
"defaultDatasource": defaultDatasource,
"datasources": datasources,
"panels": panels,
"appSubUrl": setting.AppSubUrl,
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
"authProxyEnabled": setting.AuthProxyEnabled,
"buildInfo": map[string]interface{}{
"version": setting.BuildVersion,
"commit": setting.BuildCommit,
+44 -35
View File
@@ -3,65 +3,74 @@ package api
import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/middleware"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
)
func setIndexViewData(c *middleware.Context) error {
func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
settings, err := getFrontendSettingsMap(c)
if err != nil {
return err
return nil, err
}
currentUser := &dtos.CurrentUser{
Id: c.UserId,
IsSignedIn: c.IsSignedIn,
Login: c.Login,
Email: c.Email,
Name: c.Name,
LightTheme: c.Theme == "light",
OrgId: c.OrgId,
OrgName: c.OrgName,
OrgRole: c.OrgRole,
GravatarUrl: dtos.GetGravatarUrl(c.Email),
IsGrafanaAdmin: c.IsGrafanaAdmin,
var data = dtos.IndexViewData{
User: &dtos.CurrentUser{
Id: c.UserId,
IsSignedIn: c.IsSignedIn,
Login: c.Login,
Email: c.Email,
Name: c.Name,
LightTheme: c.Theme == "light",
OrgId: c.OrgId,
OrgName: c.OrgName,
OrgRole: c.OrgRole,
GravatarUrl: dtos.GetGravatarUrl(c.Email),
IsGrafanaAdmin: c.IsGrafanaAdmin,
},
Settings: settings,
AppUrl: setting.AppUrl,
AppSubUrl: setting.AppSubUrl,
GoogleAnalyticsId: setting.GoogleAnalyticsId,
GoogleTagManagerId: setting.GoogleTagManagerId,
}
if setting.DisableGravatar {
currentUser.GravatarUrl = setting.AppSubUrl + "/img/user_profile.png"
data.User.GravatarUrl = setting.AppSubUrl + "/img/user_profile.png"
}
if len(currentUser.Name) == 0 {
currentUser.Name = currentUser.Login
if len(data.User.Name) == 0 {
data.User.Name = data.User.Login
}
themeUrlParam := c.Query("theme")
if themeUrlParam == "light" {
currentUser.LightTheme = true
data.User.LightTheme = true
}
c.Data["User"] = currentUser
c.Data["Settings"] = settings
c.Data["AppUrl"] = setting.AppUrl
c.Data["AppSubUrl"] = setting.AppSubUrl
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
Text: "Dashboards",
Icon: "fa fa-fw fa-th-large",
Href: "/",
})
if setting.GoogleAnalyticsId != "" {
c.Data["GoogleAnalyticsId"] = setting.GoogleAnalyticsId
if c.OrgRole == m.ROLE_ADMIN {
data.MainNavLinks = append(data.MainNavLinks, &dtos.NavLink{
Text: "Data Sources",
Icon: "fa fa-fw fa-database",
Href: "/datasources",
})
}
if setting.GoogleTagManagerId != "" {
c.Data["GoogleTagManagerId"] = setting.GoogleTagManagerId
}
return nil
return &data, nil
}
func Index(c *middleware.Context) {
if err := setIndexViewData(c); err != nil {
if data, err := setIndexViewData(c); err != nil {
c.Handle(500, "Failed to get settings", err)
return
} else {
c.HTML(200, "index", data)
}
c.HTML(200, "index")
}
func NotFoundHandler(c *middleware.Context) {
@@ -70,10 +79,10 @@ func NotFoundHandler(c *middleware.Context) {
return
}
if err := setIndexViewData(c); err != nil {
if data, err := setIndexViewData(c); err != nil {
c.Handle(500, "Failed to get settings", err)
return
} else {
c.HTML(404, "index", data)
}
c.HTML(404, "index")
}
+7 -6
View File
@@ -19,18 +19,19 @@ const (
)
func LoginView(c *middleware.Context) {
if err := setIndexViewData(c); err != nil {
viewData, err := setIndexViewData(c)
if err != nil {
c.Handle(500, "Failed to get settings", err)
return
}
settings := c.Data["Settings"].(map[string]interface{})
settings["googleAuthEnabled"] = setting.OAuthService.Google
settings["githubAuthEnabled"] = setting.OAuthService.GitHub
settings["disableUserSignUp"] = !setting.AllowUserSignUp
viewData.Settings["googleAuthEnabled"] = setting.OAuthService.Google
viewData.Settings["githubAuthEnabled"] = setting.OAuthService.GitHub
viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp
viewData.Settings["loginHint"] = setting.LoginHint
if !tryLoginUsingRememberCookie(c) {
c.HTML(200, VIEW_INDEX)
c.HTML(200, VIEW_INDEX, viewData)
return
}