Skip to content

Commit

Permalink
Merge branch 'main' into release-please--branches--main--components--…
Browse files Browse the repository at this point in the history
…spanner
  • Loading branch information
rahul2393 committed May 2, 2022
2 parents ca8bd51 + dd8973b commit 286a0c8
Show file tree
Hide file tree
Showing 5 changed files with 355 additions and 9 deletions.
69 changes: 69 additions & 0 deletions storage/bucket.go
Expand Up @@ -945,6 +945,75 @@ func (b *BucketAttrs) toProtoBucket() *storagepb.Bucket {
}
}

func (ua *BucketAttrsToUpdate) toProtoBucket() *storagepb.Bucket {
if ua == nil {
return &storagepb.Bucket{}
}

// TODO(cathyo): Handle labels. Pending b/230510191.

var v *storagepb.Bucket_Versioning
if ua.VersioningEnabled != nil {
v = &storagepb.Bucket_Versioning{Enabled: optional.ToBool(ua.VersioningEnabled)}
}
var bb *storagepb.Bucket_Billing
if ua.RequesterPays != nil {
bb = &storage.Bucket_Billing{RequesterPays: optional.ToBool(ua.RequesterPays)}
}
var bktIAM *storagepb.Bucket_IamConfig
var ublaEnabled bool
var bktPolicyOnlyEnabled bool
if ua.UniformBucketLevelAccess != nil {
ublaEnabled = optional.ToBool(ua.UniformBucketLevelAccess.Enabled)
}
if ua.BucketPolicyOnly != nil {
bktPolicyOnlyEnabled = optional.ToBool(ua.BucketPolicyOnly.Enabled)
}
if ublaEnabled || bktPolicyOnlyEnabled {
bktIAM.UniformBucketLevelAccess = &storagepb.Bucket_IamConfig_UniformBucketLevelAccess{
Enabled: true,
}
}
if ua.PublicAccessPrevention != PublicAccessPreventionUnknown {
bktIAM.PublicAccessPrevention = ua.PublicAccessPrevention.String()
}
var defaultHold bool
if ua.DefaultEventBasedHold != nil {
defaultHold = optional.ToBool(ua.DefaultEventBasedHold)
}
var lifecycle Lifecycle
if ua.Lifecycle != nil {
lifecycle = *ua.Lifecycle
}
var bktACL []*storagepb.BucketAccessControl
if ua.PredefinedACL != "" {
// Clear ACL or the call will fail.
bktACL = nil
}
var bktDefaultObjectACL []*storagepb.ObjectAccessControl
if ua.PredefinedDefaultObjectACL != "" {
// Clear ACLs or the call will fail.
bktDefaultObjectACL = nil
}

return &storagepb.Bucket{
StorageClass: ua.StorageClass,
Acl: bktACL,
DefaultObjectAcl: bktDefaultObjectACL,
DefaultEventBasedHold: defaultHold,
Versioning: v,
Billing: bb,
Lifecycle: toProtoLifecycle(lifecycle),
RetentionPolicy: ua.RetentionPolicy.toProtoRetentionPolicy(),
Cors: toProtoCORS(ua.CORS),
Encryption: ua.Encryption.toProtoBucketEncryption(),
Logging: ua.Logging.toProtoBucketLogging(),
Website: ua.Website.toProtoBucketWebsite(),
IamConfig: bktIAM,
Rpo: ua.RPO.String(),
}
}

// CORS is the bucket's Cross-Origin Resource Sharing (CORS) configuration.
type CORS struct {
// MaxAge is the value to return in the Access-Control-Max-Age
Expand Down
2 changes: 1 addition & 1 deletion storage/client.go
Expand Up @@ -50,7 +50,7 @@ type storageClient interface {

DeleteBucket(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) error
GetBucket(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error)
UpdateBucket(ctx context.Context, uattrs *BucketAttrsToUpdate, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error)
UpdateBucket(ctx context.Context, bucket string, uattrs *BucketAttrsToUpdate, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error)
LockBucketRetentionPolicy(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) error
ListObjects(ctx context.Context, bucket string, q *Query, opts ...storageOption) *ObjectIterator

Expand Down
130 changes: 130 additions & 0 deletions storage/client_test.go
Expand Up @@ -88,6 +88,92 @@ func TestGetBucketEmulated(t *testing.T) {
})
}

func TestUpdateBucketEmulated(t *testing.T) {
transportClientTest(t, func(t *testing.T, project, bucket string, client storageClient) {
bkt := &BucketAttrs{
Name: bucket,
}
// Create the bucket that will be updated.
_, err := client.CreateBucket(context.Background(), project, bkt)
if err != nil {
t.Fatalf("client.CreateBucket: %v", err)
}

ua := &BucketAttrsToUpdate{
VersioningEnabled: false,
RequesterPays: false,
DefaultEventBasedHold: false,
Encryption: &BucketEncryption{DefaultKMSKeyName: "key2"},
Lifecycle: &Lifecycle{
Rules: []LifecycleRule{
{
Action: LifecycleAction{Type: "Delete"},
Condition: LifecycleCondition{AgeInDays: 30},
},
},
},
Logging: &BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"},
Website: &BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"},
StorageClass: "NEARLINE",
RPO: RPOAsyncTurbo,
}
want := &BucketAttrs{
Name: bucket,
VersioningEnabled: false,
RequesterPays: false,
DefaultEventBasedHold: false,
Encryption: &BucketEncryption{DefaultKMSKeyName: "key2"},
Lifecycle: Lifecycle{
Rules: []LifecycleRule{
{
Action: LifecycleAction{Type: "Delete"},
Condition: LifecycleCondition{AgeInDays: 30},
},
},
},
Logging: &BucketLogging{LogBucket: "lb", LogObjectPrefix: "p"},
Website: &BucketWebsite{MainPageSuffix: "mps", NotFoundPage: "404"},
StorageClass: "NEARLINE",
RPO: RPOAsyncTurbo,
}

got, err := client.UpdateBucket(context.Background(), bucket, ua, &BucketConditions{MetagenerationMatch: 1})
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(got.Name, want.Name); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.VersioningEnabled, want.VersioningEnabled); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.RequesterPays, want.RequesterPays); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.DefaultEventBasedHold, want.DefaultEventBasedHold); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.Encryption, want.Encryption); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.Lifecycle, want.Lifecycle); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.Logging, want.Logging); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.Website, want.Website); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.RPO, want.RPO); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
if diff := cmp.Diff(got.StorageClass, want.StorageClass); diff != "" {
t.Errorf("got(-),want(+):\n%s", diff)
}
})
}

func TestGetServiceAccountEmulated(t *testing.T) {
transportClientTest(t, func(t *testing.T, project, bucket string, client storageClient) {
_, err := client.GetServiceAccount(context.Background(), project)
Expand Down Expand Up @@ -287,6 +373,50 @@ func TestListBucketsEmulated(t *testing.T) {
})
}

func TestListBucketACLsEmulated(t *testing.T) {
transportClientTest(t, func(t *testing.T, project, bucket string, client storageClient) {
ctx := context.Background()
attrs := &BucketAttrs{
Name: bucket,
PredefinedACL: "publicRead",
}
// Create the bucket that will be retrieved.
if _, err := client.CreateBucket(ctx, project, attrs); err != nil {
t.Fatalf("client.CreateBucket: %v", err)
}

acls, err := client.ListBucketACLs(ctx, bucket)
if err != nil {
t.Fatalf("client.ListBucketACLs: %v", err)
}
if want, got := len(acls), 2; want != got {
t.Errorf("ListBucketACLs: got %v, want %v items", acls, want)
}
})
}

func TestListDefaultObjectACLsEmulated(t *testing.T) {
transportClientTest(t, func(t *testing.T, project, bucket string, client storageClient) {
ctx := context.Background()
attrs := &BucketAttrs{
Name: bucket,
PredefinedDefaultObjectACL: "publicRead",
}
// Create the bucket that will be retrieved.
if _, err := client.CreateBucket(ctx, project, attrs); err != nil {
t.Fatalf("client.CreateBucket: %v", err)
}

acls, err := client.ListDefaultObjectACLs(ctx, bucket)
if err != nil {
t.Fatalf("client.ListDefaultObjectACLs: %v", err)
}
if want, got := len(acls), 2; want != got {
t.Errorf("ListDefaultObjectACLs: got %v, want %v items", acls, want)
}
})
}

func initEmulatorClients() func() error {
noopCloser := func() error { return nil }
if !isEmulatorEnvironmentSet() {
Expand Down
90 changes: 86 additions & 4 deletions storage/grpc_client.go
Expand Up @@ -26,6 +26,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
)

const (
Expand Down Expand Up @@ -255,8 +256,81 @@ func (c *grpcStorageClient) GetBucket(ctx context.Context, bucket string, conds

return battrs, err
}
func (c *grpcStorageClient) UpdateBucket(ctx context.Context, uattrs *BucketAttrsToUpdate, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error) {
return nil, errMethodNotSupported
func (c *grpcStorageClient) UpdateBucket(ctx context.Context, bucket string, uattrs *BucketAttrsToUpdate, conds *BucketConditions, opts ...storageOption) (*BucketAttrs, error) {
s := callSettings(c.settings, opts...)
b := uattrs.toProtoBucket()
b.Name = bucketResourceName(globalProjectAlias, bucket)
req := &storagepb.UpdateBucketRequest{
Bucket: b,
PredefinedAcl: uattrs.PredefinedACL,
PredefinedDefaultObjectAcl: uattrs.PredefinedDefaultObjectACL,
}
if err := applyBucketCondsProto("grpcStorageClient.UpdateBucket", conds, req); err != nil {
return nil, err
}
if s.userProject != "" {
req.CommonRequestParams = &storagepb.CommonRequestParams{
UserProject: toProjectResource(s.userProject),
}
}

var paths []string
fieldMask := &fieldmaskpb.FieldMask{
Paths: paths,
}
if uattrs.CORS != nil {
fieldMask.Paths = append(fieldMask.Paths, "cors")
}
if uattrs.DefaultEventBasedHold != nil {
fieldMask.Paths = append(fieldMask.Paths, "default_event_based_hold")
}
if uattrs.RetentionPolicy != nil {
fieldMask.Paths = append(fieldMask.Paths, "retention_policy")
}
if uattrs.VersioningEnabled != nil {
fieldMask.Paths = append(fieldMask.Paths, "versioning")
}
if uattrs.RequesterPays != nil {
fieldMask.Paths = append(fieldMask.Paths, "billing")
}
if uattrs.BucketPolicyOnly != nil || uattrs.UniformBucketLevelAccess != nil || uattrs.PublicAccessPrevention != PublicAccessPreventionUnknown {
fieldMask.Paths = append(fieldMask.Paths, "iam_config")
}
if uattrs.Encryption != nil {
fieldMask.Paths = append(fieldMask.Paths, "encryption")
}
if uattrs.Lifecycle != nil {
fieldMask.Paths = append(fieldMask.Paths, "lifecycle")
}
if uattrs.Logging != nil {
fieldMask.Paths = append(fieldMask.Paths, "logging")
}
if uattrs.Website != nil {
fieldMask.Paths = append(fieldMask.Paths, "website")
}
if uattrs.PredefinedACL != "" {
fieldMask.Paths = append(fieldMask.Paths, "acl")
}
if uattrs.PredefinedDefaultObjectACL != "" {
fieldMask.Paths = append(fieldMask.Paths, "default_object_acl")
}
if uattrs.StorageClass != "" {
fieldMask.Paths = append(fieldMask.Paths, "storage_class")
}
if uattrs.RPO != RPOUnknown {
fieldMask.Paths = append(fieldMask.Paths, "rpo")
}
// TODO(cathyo): Handle labels. Pending b/230510191.
req.UpdateMask = fieldMask

var battrs *BucketAttrs
err := run(ctx, func() error {
res, err := c.raw.UpdateBucket(ctx, req, s.gax...)
battrs = newBucketFromProto(res)
return err
}, s.retry, s.idempotent)

return battrs, err
}
func (c *grpcStorageClient) LockBucketRetentionPolicy(ctx context.Context, bucket string, conds *BucketConditions, opts ...storageOption) error {
return errMethodNotSupported
Expand Down Expand Up @@ -329,7 +403,11 @@ func (c *grpcStorageClient) DeleteDefaultObjectACL(ctx context.Context, bucket s
return errMethodNotSupported
}
func (c *grpcStorageClient) ListDefaultObjectACLs(ctx context.Context, bucket string, opts ...storageOption) ([]ACLRule, error) {
return nil, errMethodNotSupported
attrs, err := c.GetBucket(ctx, bucket, nil, opts...)
if err != nil {
return nil, err
}
return attrs.DefaultObjectACL, nil
}
func (c *grpcStorageClient) UpdateDefaultObjectACL(ctx context.Context, opts ...storageOption) (*ACLRule, error) {
return nil, errMethodNotSupported
Expand All @@ -341,7 +419,11 @@ func (c *grpcStorageClient) DeleteBucketACL(ctx context.Context, bucket string,
return errMethodNotSupported
}
func (c *grpcStorageClient) ListBucketACLs(ctx context.Context, bucket string, opts ...storageOption) ([]ACLRule, error) {
return nil, errMethodNotSupported
attrs, err := c.GetBucket(ctx, bucket, nil, opts...)
if err != nil {
return nil, err
}
return attrs.ACL, nil
}
func (c *grpcStorageClient) UpdateBucketACL(ctx context.Context, bucket string, entity ACLEntity, role ACLRole, opts ...storageOption) (*ACLRule, error) {
return nil, errMethodNotSupported
Expand Down

0 comments on commit 286a0c8

Please sign in to comment.