Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save aerostitch/1867ba357a91b8885df1eca37de8ca2a to your computer and use it in GitHub Desktop.
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.
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