Google-cloud-go: storage: Allow users to Put and Write with predefined ACL rules

Created on 19 Oct 2014  路  7Comments  路  Source: googleapis/google-cloud-go

storage help wanted p2 feature request

Most helpful comment

This issue is about the high-level client, cloud.google.com/go/storage, which we generally recommend. However, since we don't have this feature yet, you should continue using the google.golang.org/api/storage client for now.

To answer your question, call PredefinedAcl as one of the chained methods in your second line, before calling Do.

All 7 comments

A predefined ACL is an alias for a list of ACLs. The alias is expanded by the service at write time; it is not present in returned bucket or object metadata.

Predefined ACLs would need to be supported for the following methods (* = not yet implemented):

BucketHandle.Create, Update: PredefinedACL, PredefinedDefaultObjectACL
ObjectHandle.CopyTo, Compose
, Rewrite*: DestinationPredefinedACL
ObjectHandle.NewWriter, Update: PredefinedACL

We already have Conditions, which are effectively call options applied to subsequent calls. We should use Conditions for predefined ACLs as well.

Other choices, for completeness:

  • Add fields to the Attrs types, carefully documented as write-only.
  • BucketHandle.Create: add the two Predefined* as additional arguments, or options (and perhaps also represent the current required *BucketAttrs param as an option).
  • ObjectHandle.CopyTo, Compose, Rewrite; both Updates: similarly, add as an option or additional arg.
  • NewWriter: add a field to the Writer.

OK, not Conditions, since these are more like options on the call. So here are two alternatives, one per comment. Comment on or vote for (via the "reactions" smiley face) your fave.

We could add a PredefinedACL field to ObjectAttrs and BucketAttrs, and a PredefinedDefaultObjectACL field to BucketAttrs. These would be documented as write-only: set them on an Attrs that you pass to one of the methods that creates or changes an object or bucket. They will always be empty when retrieving an Attrs from the service.

Examples:

bkt := client.Bucket("mybucket").Create(ctx, "myproject", &BucketAttrs{
    PredefinedACL: "private",
    PredefinedDefaultObjectACL: "authenticatedRead",
})
bkt.Object("foo").Update(ctx, ObjectAttrs{PredefinedACL: "publicRead"})

Pros:

  • No need for extra Options types and related machinery.
  • No signature changes to existing methods.

Cons:

  • These new fields _aren't_ attributes of buckets or objects. It's misleading to put them there.
  • They are always empty on read, possibly confusing users who expect them.
  • You can't set both the field and the corresponding ACL; we have to check at runtime.

Variant: Change the type of the ACL fields of the Attrs so it can be either a []ACLRule (which it is now) or a string, the predefined ACL name.

type ACL interface { implsACL() }
type PredefinedACL string
type ACLRules []ACLRule
...

Pros:

  • Compiler enforces that at most one can be set.

Cons:

  • Extra typing when setting:

    • ObjectAttrs{ACL: PredefinedACL("private")}

    • var rs []ACLRule; ObjectAttrs{ACL: ACLRules(rs)}

    • But not the literal case: ObjectAttrs{ACL: ACLRules{{...}, {...}}}

  • Extra work to retrieve: either a cast or a method call.

Second alternative: Options.

type Option interface { ... }

func PredefinedACL(string) Option {...}
func PredefinedDefaultObjectACL(string) Option {...}

func (*BucketHandle) Create(ctx context.Context, projectID string, attrs *BucketAttrs,
        opts ...Option) {...}

Pros:

  • A common Go idiom, and one we follow in most other cloud clients, so familiar to our users.
  • Room for future growth, if the API grows other option-like parameters. (True of the first alternative as well, but in that case each added non-attribute makes the whole struct feel more wrong.)

Cons:

  • Requires a few runtime checks:

    • Each option occurs only once.

    • Object methods don't take PredefinedDefaultObjectACL.

    • Could be handled by having different BucketOption and ObjectOption types, but then we need two functions for PredefinedACL.

  • A bigger, more complicated surface.

@okdave @mcgreevy @broady @bradfitz

I am having similar problems and I can't find the answer in the API documentation.

In my case, I want to set PredefinedACL: "publicRead" while uploading a file.

object := &storage.Object{Name: fileName}
service.Objects.Insert(*bucketName, object).Media(file).Do();

How should I set PredefinedACL?

Cheers

PS: A link to the answer in the documentation would be hugely appreciated, probably it is there but I don't know where to find it.

This issue is about the high-level client, cloud.google.com/go/storage, which we generally recommend. However, since we don't have this feature yet, you should continue using the google.golang.org/api/storage client for now.

To answer your question, call PredefinedAcl as one of the chained methods in your second line, before calling Do.

Wonderful, thanks a bunch @jba

Was this page helpful?
0 / 5 - 0 ratings