From f2cbfaa24e6e7a9c1dce1552d64b69dc0c1c84e4 Mon Sep 17 00:00:00 2001 From: Eric Fu Date: Tue, 13 Dec 2016 14:39:34 +0800 Subject: [PATCH 1/3] Fix bugs in fmt.Errorf --- as.go | 2 +- cw.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/as.go b/as.go index ee8882a..61543ec 100644 --- a/as.go +++ b/as.go @@ -23,7 +23,7 @@ func getAutoscalingGroup(instanceId string, region string) (*string, error) { resp, err := svc.DescribeAutoScalingInstances(params) if err != nil { if awsErr, ok := err.(awserr.Error); ok { - return nil, fmt.Errorf("[%s] %s", awsErr.Code, awsErr.Message) + return nil, fmt.Errorf("[%s] %s", awsErr.Code(), awsErr.Message()) } else if err != nil { return nil, err } diff --git a/cw.go b/cw.go index 8d659b9..b49e703 100644 --- a/cw.go +++ b/cw.go @@ -84,7 +84,7 @@ func putMetric(metricdata []*cloudwatch.MetricDatum, namespace, region string) e resp, err := svc.PutMetricData(metric_input) if err != nil { if awsErr, ok := err.(awserr.Error); ok { - return fmt.Errorf("[%s] %s", awsErr.Code, awsErr.Message) + return fmt.Errorf("[%s] %s", awsErr.Code(), awsErr.Message()) } else if err != nil { return err } From 4647f140d5210444b532278606f6ac642eef60cc Mon Sep 17 00:00:00 2001 From: Eric Fu Date: Tue, 13 Dec 2016 15:29:24 +0800 Subject: [PATCH 2/3] Print error when failed to put metrics --- go-aws-mon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-aws-mon.go b/go-aws-mon.go index 3f2f1a0..edadcaf 100644 --- a/go-aws-mon.go +++ b/go-aws-mon.go @@ -124,6 +124,6 @@ func main() { err = putMetric(metricData, *ns, metadata["region"]) if err != nil { - log.Fatal("Can't put CloudWatch Metric") + log.Fatal("Can't put CloudWatch Metric: ", err) } } From c87b9f5ffdc07f39e7562c87d394bce5d52453e6 Mon Sep 17 00:00:00 2001 From: Eric Fu Date: Tue, 13 Dec 2016 15:28:16 +0800 Subject: [PATCH 3/3] Fetch IAM credentials from Metadata API --- as.go | 9 +++----- cw.go | 4 +--- go-aws-mon.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/as.go b/as.go index 61543ec..0df8fc8 100644 --- a/as.go +++ b/as.go @@ -6,18 +6,15 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/autoscaling" ) - -func getAutoscalingGroup(instanceId string, region string) (*string, error) { - session := session.New(&aws.Config{Region: ®ion}) +func getAutoscalingGroup(instanceId string) (*string, error) { svc := autoscaling.New(session) params := &autoscaling.DescribeAutoScalingInstancesInput{ InstanceIds: []*string{&instanceId}, - MaxRecords: aws.Int64(1), + MaxRecords: aws.Int64(1), } resp, err := svc.DescribeAutoScalingInstances(params) @@ -34,4 +31,4 @@ func getAutoscalingGroup(instanceId string, region string) (*string, error) { } return resp.AutoScalingInstances[0].AutoScalingGroupName, nil -} \ No newline at end of file +} diff --git a/cw.go b/cw.go index b49e703..87b5cf9 100644 --- a/cw.go +++ b/cw.go @@ -6,7 +6,6 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awsutil" - "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudwatch" "io/ioutil" "log" @@ -71,9 +70,8 @@ func addMetric(name, unit string, value float64, dimensions []*cloudwatch.Dimens return metricData, nil } -func putMetric(metricdata []*cloudwatch.MetricDatum, namespace, region string) error { +func putMetric(metricdata []*cloudwatch.MetricDatum, namespace string) error { - session := session.New(&aws.Config{Region: ®ion}) svc := cloudwatch.New(session) metric_input := &cloudwatch.PutMetricDataInput{ diff --git a/go-aws-mon.go b/go-aws-mon.go index edadcaf..08f0363 100644 --- a/go-aws-mon.go +++ b/go-aws-mon.go @@ -2,13 +2,22 @@ package main import ( "flag" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/cloudwatch" "log" "os" "strings" + "net/http" + "fmt" + "io/ioutil" + "encoding/json" + + "github.com/aws/aws-sdk-go/aws" + aws_session "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/cloudwatch" + "github.com/aws/aws-sdk-go/aws/credentials" ) +var session *aws_session.Session + func main() { isAggregated := flag.Bool("aggregated", false, "Adds aggregated metrics for instance type, AMI ID, and overall for the region") isAutoScaling := flag.Bool("auto-scaling", false, "Adds aggregated metrics for the Auto Scaling group") @@ -34,6 +43,18 @@ func main() { os.Exit(1) } + credential, err := getIamCredential() + + if err != nil { + log.Fatal("Can't get IAM Credential: ", err) + os.Exit(1) + } + + session = aws_session.New(&aws.Config{ + Region: aws.String(metadata["region"]), + Credentials: credentials.NewStaticCredentials(credential["AccessKeyId"], credential["SecretAccessKey"], credential["Token"]), + }) + memUtil, memUsed, memAvail, swapUtil, swapUsed, err := memoryUsage() var metricData []*cloudwatch.MetricDatum @@ -44,7 +65,7 @@ func main() { } if *isAutoScaling { - if as, err := getAutoscalingGroup(metadata["instanceId"], metadata["region"]); as != nil && err == nil { + if as, err := getAutoscalingGroup(metadata["instanceId"]); as != nil && err == nil { dims = append(dims, &cloudwatch.Dimension{ Name: aws.String("AutoScalingGroupName"), Value: as, @@ -122,8 +143,39 @@ func main() { } } - err = putMetric(metricData, *ns, metadata["region"]) + err = putMetric(metricData, *ns) if err != nil { log.Fatal("Can't put CloudWatch Metric: ", err) } } + +func getIamCredential() (credential map[string]string, err error) { + var data map[string]string + resp, err := http.Get("http://169.254.169.254/latest/meta-data/iam/security-credentials/") + if err != nil { + return data, fmt.Errorf("can't reach credentials endpoint - %s", err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return data, fmt.Errorf("can't read credentials response body - %s", err) + } + + iamRole := string(body) + + resp, err = http.Get("http://169.254.169.254/latest/meta-data/iam/security-credentials/" + iamRole) + if err != nil { + return data, fmt.Errorf("can't reach credentials content endpoint - %s", err) + } + defer resp.Body.Close() + + body, err = ioutil.ReadAll(resp.Body) + if err != nil { + return data, fmt.Errorf("can't read credentials content response body - %s", err) + } + + json.Unmarshal(body, &data) + + return data, err +}