github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/pkg/blobserver/s3/s3.go (about)

     1  /*
     2  Copyright 2011 Google Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8       http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  /*
    18  Package s3 registers the "s3" blobserver storage type, storing
    19  blobs in an Amazon Web Services' S3 storage bucket.
    20  
    21  Example low-level config:
    22  
    23       "/r1/": {
    24           "handler": "storage-s3",
    25           "handlerArgs": {
    26              "bucket": "foo",
    27              "aws_access_key": "...",
    28              "aws_secret_access_key": "...",
    29              "skipStartupCheck": false
    30            }
    31       },
    32  
    33  */
    34  package s3
    35  
    36  import (
    37  	"fmt"
    38  	"net/http"
    39  
    40  	"camlistore.org/pkg/blobserver"
    41  	"camlistore.org/pkg/jsonconfig"
    42  	"camlistore.org/pkg/misc/amazon/s3"
    43  )
    44  
    45  type s3Storage struct {
    46  	s3Client *s3.Client
    47  	bucket   string
    48  }
    49  
    50  func newFromConfig(_ blobserver.Loader, config jsonconfig.Obj) (blobserver.Storage, error) {
    51  	client := &s3.Client{
    52  		Auth: &s3.Auth{
    53  			AccessKey:       config.RequiredString("aws_access_key"),
    54  			SecretAccessKey: config.RequiredString("aws_secret_access_key"),
    55  			Hostname:        config.OptionalString("hostname", ""),
    56  		},
    57  		HTTPClient: http.DefaultClient,
    58  	}
    59  	sto := &s3Storage{
    60  		s3Client: client,
    61  		bucket:   config.RequiredString("bucket"),
    62  	}
    63  	skipStartupCheck := config.OptionalBool("skipStartupCheck", false)
    64  	if err := config.Validate(); err != nil {
    65  		return nil, err
    66  	}
    67  	if !skipStartupCheck {
    68  		// TODO: skip this check if a file
    69  		// ~/.camli/.configcheck/sha1-("IS GOOD: s3: sha1(access key +
    70  		// secret key)") exists and has recent time?
    71  		buckets, err := client.Buckets()
    72  		if err != nil {
    73  			return nil, fmt.Errorf("Failed to get bucket list from S3: %v", err)
    74  		}
    75  		haveBucket := make(map[string]bool)
    76  		for _, b := range buckets {
    77  			haveBucket[b.Name] = true
    78  		}
    79  		if !haveBucket[sto.bucket] {
    80  			return nil, fmt.Errorf("S3 bucket %q doesn't exist. Create it first at https://console.aws.amazon.com/s3/home")
    81  		}
    82  	}
    83  	return sto, nil
    84  }
    85  
    86  func init() {
    87  	blobserver.RegisterStorageConstructor("s3", blobserver.StorageConstructor(newFromConfig))
    88  }