Add 'objectAcl' Option to the S3 Storage Backend (#1867)

* Add Object ACL Support to the S3 Storage Backend

Signed-off-by: Frank Chen <frankchn@gmail.com>

* Made changes per @RichardScothern's comments

Signed-off-by: Frank Chen <frankchn@gmail.com>

* Fix Typos

Signed-off-by: Frank Chen <frankchn@gmail.com>
This commit is contained in:
Frank Chen 2016-07-27 12:26:57 -07:00 committed by Richard Scothern
parent 4abae2ae56
commit 87917f3052
3 changed files with 49 additions and 1 deletions

View file

@ -160,6 +160,17 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
The S3 storage class applied to each registry file. The default value is STANDARD.
</td>
</tr>
<tr>
<td>
<code>objectacl</code>
</td>
<td>
no
</td>
<td>
The S3 Canned ACL for objects. The default value is "private".
</td>
</tr>
</table>
@ -189,6 +200,8 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
`storageclass`: (optional) The storage class applied to each registry file. Defaults to STANDARD. Valid options are STANDARD and REDUCED_REDUNDANCY.
`objectacl`: (optional) The canned object ACL to be applied to each registry object. Defaults to `private`. If you are using a bucket owned by another AWS account, it is recommended that you set this to `bucket-owner-full-control` so that the bucket owner can access your objects. Other valid options are available in the [AWS S3 documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl).
## S3 permission scopes
The following IAM permissions are required by the registry for push and pull. See [the S3 policy documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) for more details.

View file

@ -53,6 +53,9 @@ const listMax = 1000
// validRegions maps known s3 region identifiers to region descriptors
var validRegions = map[string]struct{}{}
// validObjectAcls contains known s3 object Acls
var validObjectAcls = map[string]struct{}{}
//DriverParameters A struct that encapsulates all of the driver parameters after all values have been set
type DriverParameters struct {
AccessKey string
@ -67,6 +70,7 @@ type DriverParameters struct {
RootDirectory string
StorageClass string
UserAgent string
ObjectAcl string
}
func init() {
@ -87,6 +91,18 @@ func init() {
validRegions[region] = struct{}{}
}
for _, objectAcl := range []string{
s3.ObjectCannedACLPrivate,
s3.ObjectCannedACLPublicRead,
s3.ObjectCannedACLPublicReadWrite,
s3.ObjectCannedACLAuthenticatedRead,
s3.ObjectCannedACLAwsExecRead,
s3.ObjectCannedACLBucketOwnerRead,
s3.ObjectCannedACLBucketOwnerFullControl,
} {
validObjectAcls[objectAcl] = struct{}{}
}
// Register this as the default s3 driver in addition to s3aws
factory.Register("s3", &s3DriverFactory{})
factory.Register(driverName, &s3DriverFactory{})
@ -107,6 +123,7 @@ type driver struct {
KeyID string
RootDirectory string
StorageClass string
ObjectAcl string
}
type baseEmbed struct {
@ -248,6 +265,20 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
userAgent = ""
}
objectAcl := s3.ObjectCannedACLPrivate
objectAclParam := parameters["objectacl"]
if objectAclParam != nil {
objectAclString, ok := objectAclParam.(string)
if !ok {
return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectAclParam)
}
if _, ok = validObjectAcls[objectAclString]; !ok {
return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectAclParam)
}
objectAcl = objectAclString
}
params := DriverParameters{
fmt.Sprint(accessKey),
fmt.Sprint(secretKey),
@ -261,6 +292,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
fmt.Sprint(rootDirectory),
storageClass,
fmt.Sprint(userAgent),
objectAcl,
}
return New(params)
@ -321,6 +353,7 @@ func New(params DriverParameters) (*Driver, error) {
KeyID: params.KeyID,
RootDirectory: params.RootDirectory,
StorageClass: params.StorageClass,
ObjectAcl: params.ObjectAcl,
}
return &Driver{
@ -688,7 +721,7 @@ func (d *driver) getContentType() *string {
}
func (d *driver) getACL() *string {
return aws.String("private")
return aws.String(d.ObjectAcl)
}
func (d *driver) getStorageClass() *string {

View file

@ -30,6 +30,7 @@ func init() {
keyID := os.Getenv("S3_KEY_ID")
secure := os.Getenv("S3_SECURE")
region := os.Getenv("AWS_REGION")
objectAcl := os.Getenv("S3_OBJECT_ACL")
root, err := ioutil.TempDir("", "driver-")
regionEndpoint := os.Getenv("REGION_ENDPOINT")
if err != nil {
@ -67,6 +68,7 @@ func init() {
rootDirectory,
storageClass,
driverName + "-test",
objectAcl,
}
return New(parameters)