Last active
May 5, 2017 21:54
-
-
Save aerostitch/1867ba357a91b8885df1eca37de8ca2a to your computer and use it in GitHub Desktop.
Take all the buckets and list their website policy if any. Support multi-region and profile or static auth.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"encoding/json" | |
"flag" | |
"io/ioutil" | |
"log" | |
"time" | |
"github.com/aws/aws-sdk-go/aws" | |
"github.com/aws/aws-sdk-go/aws/awserr" | |
"github.com/aws/aws-sdk-go/aws/credentials" | |
"github.com/aws/aws-sdk-go/aws/session" | |
"github.com/aws/aws-sdk-go/service/s3" | |
"github.com/gobike/envflag" | |
) | |
type awsS3Websites struct { | |
Name string | |
Region string | |
HasWebsiteConfig bool | |
RedirectToHost string `json:",omitempty"` | |
RoutingRules []*s3.RoutingRule `json:",omitempty"` | |
Tags map[string]string `json:",omitempty"` | |
} | |
func main() { | |
var ( | |
awsRegion string | |
awsProfile string | |
awsKey string | |
awsSecret string | |
awsToken string | |
outputFilePath string | |
outputObject []*awsS3Websites | |
) | |
flag.StringVar(&awsRegion, "aws-region", "us-east-1", "AWS Region to use") | |
flag.StringVar(&awsProfile, "aws-profile", "", "AWS profile to use - ignored if empty") | |
flag.StringVar(&awsKey, "aws-access-key-id", "", "AWS key id to use - ignored if empty") | |
flag.StringVar(&awsSecret, "aws-secret-access-key", "", "AWS secret key to use - ignored if aws-access-key-id is empty") | |
flag.StringVar(&awsToken, "aws-session-token", "", "AWS session token to use - ignored if aws-access-key-id is empty") | |
flag.StringVar(&outputFilePath, "output-json-path", "/tmp/s3_endpoints.json", "Path to the json output") | |
envflag.Parse() | |
awsConfig := &aws.Config{Region: aws.String(awsRegion)} | |
if awsKey != "" { | |
awsConfig.Credentials = credentials.NewStaticCredentials(awsKey, awsSecret, awsToken) | |
} | |
awsSessOpts := &session.Options{Config: *awsConfig} | |
if awsProfile != "" { | |
awsSessOpts.SharedConfigState = session.SharedConfigEnable | |
awsSessOpts.Profile = awsProfile | |
} | |
sess := session.Must(session.NewSessionWithOptions(*awsSessOpts)) | |
svc := s3.New(sess) | |
bucketsList, err := svc.ListBuckets(&s3.ListBucketsInput{}) | |
if err != nil { | |
log.Fatal(err.Error()) | |
} | |
for _, bucket := range bucketsList.Buckets { | |
currentBucketRegion := awsRegion | |
// Make sure to be compliant with signature v4 when querying buckets that | |
// are not in the default region | |
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | |
defer cancel() | |
bucketRegion, err := svc.GetBucketLocationWithContext(ctx, &s3.GetBucketLocationInput{Bucket: aws.String(*bucket.Name)}, s3.WithNormalizeBucketLocation) | |
if err != nil { | |
log.Printf("[WARNING] while retrieving the bucket location for %s: %s\n", *bucket.Name, err.Error()) | |
} | |
regionalSvc := svc | |
if bucketRegion.LocationConstraint != nil { | |
currentBucketRegion = *bucketRegion.LocationConstraint | |
regionalSvc = s3.New(sess.Copy(&aws.Config{Region: bucketRegion.LocationConstraint})) | |
} | |
ws := &awsS3Websites{Name: *bucket.Name, Region: currentBucketRegion, HasWebsiteConfig: false} | |
// Get the bucket tag | |
ws.Tags = make(map[string]string) | |
bucketTags, err := regionalSvc.GetBucketTagging(&s3.GetBucketTaggingInput{Bucket: aws.String(*bucket.Name)}) | |
if err != nil { | |
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() != "NoSuchTagSet" { | |
log.Println(err.Error()) | |
} | |
} | |
for _, tag := range bucketTags.TagSet { | |
ws.Tags[*tag.Key] = *tag.Value | |
} | |
// Get the website config | |
website, err := regionalSvc.GetBucketWebsite(&s3.GetBucketWebsiteInput{Bucket: aws.String(*bucket.Name)}) | |
if err != nil { | |
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() != "NoSuchWebsiteConfiguration" { | |
log.Printf("[WARNING] while retrieving the bucket website for %s: %s\n", *bucket.Name, err.Error()) | |
// } else { | |
// log.Printf("Bucket %s has no website configured", *bucket.Name) | |
} | |
} else { | |
ws.RoutingRules = website.RoutingRules | |
ws.HasWebsiteConfig = true | |
if website.RedirectAllRequestsTo != nil { | |
ws.RedirectToHost = *website.RedirectAllRequestsTo.HostName | |
} | |
} | |
outputObject = append(outputObject, ws) | |
} | |
outputJson, err := json.MarshalIndent(outputObject, "", " ") | |
if err != nil { | |
log.Fatal(err) | |
} | |
err = ioutil.WriteFile(outputFilePath, outputJson, 0600) | |
if err != nil { | |
log.Fatal(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment