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. The S3 storage class applied to each registry file. The default value is STANDARD.
</td> </td>
</tr> </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> </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. `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 ## 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. 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 // validRegions maps known s3 region identifiers to region descriptors
var validRegions = map[string]struct{}{} 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 //DriverParameters A struct that encapsulates all of the driver parameters after all values have been set
type DriverParameters struct { type DriverParameters struct {
AccessKey string AccessKey string
@ -67,6 +70,7 @@ type DriverParameters struct {
RootDirectory string RootDirectory string
StorageClass string StorageClass string
UserAgent string UserAgent string
ObjectAcl string
} }
func init() { func init() {
@ -87,6 +91,18 @@ func init() {
validRegions[region] = struct{}{} 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 // Register this as the default s3 driver in addition to s3aws
factory.Register("s3", &s3DriverFactory{}) factory.Register("s3", &s3DriverFactory{})
factory.Register(driverName, &s3DriverFactory{}) factory.Register(driverName, &s3DriverFactory{})
@ -107,6 +123,7 @@ type driver struct {
KeyID string KeyID string
RootDirectory string RootDirectory string
StorageClass string StorageClass string
ObjectAcl string
} }
type baseEmbed struct { type baseEmbed struct {
@ -248,6 +265,20 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
userAgent = "" 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{ params := DriverParameters{
fmt.Sprint(accessKey), fmt.Sprint(accessKey),
fmt.Sprint(secretKey), fmt.Sprint(secretKey),
@ -261,6 +292,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
fmt.Sprint(rootDirectory), fmt.Sprint(rootDirectory),
storageClass, storageClass,
fmt.Sprint(userAgent), fmt.Sprint(userAgent),
objectAcl,
} }
return New(params) return New(params)
@ -321,6 +353,7 @@ func New(params DriverParameters) (*Driver, error) {
KeyID: params.KeyID, KeyID: params.KeyID,
RootDirectory: params.RootDirectory, RootDirectory: params.RootDirectory,
StorageClass: params.StorageClass, StorageClass: params.StorageClass,
ObjectAcl: params.ObjectAcl,
} }
return &Driver{ return &Driver{
@ -688,7 +721,7 @@ func (d *driver) getContentType() *string {
} }
func (d *driver) getACL() *string { func (d *driver) getACL() *string {
return aws.String("private") return aws.String(d.ObjectAcl)
} }
func (d *driver) getStorageClass() *string { func (d *driver) getStorageClass() *string {

View File

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