Skip to content

Commit 455ae02

Browse files
cojenconoahdietz
authored andcommitted
feat(storage): add Custom Placement Config Dual Region Support (#6294)
* feat(storage): support Custom Dual Regions with CustomPlacementConfig * fix typo * add comments * address pr comments * new sublink
1 parent 6d1e9fe commit 455ae02

2 files changed

Lines changed: 100 additions & 40 deletions

File tree

storage/bucket.go

Lines changed: 82 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,13 @@ type BucketAttrs struct {
460460
PredefinedDefaultObjectACL string
461461

462462
// Location is the location of the bucket. It defaults to "US".
463+
// If specifying a dual-region, CustomPlacementConfig should be set in conjunction.
463464
Location string
464465

466+
// The bucket's custom placement configuration that holds a list of
467+
// regional locations for custom dual regions.
468+
CustomPlacementConfig *CustomPlacementConfig
469+
465470
// MetaGeneration is the metadata generation of the bucket.
466471
// This field is read-only.
467472
MetaGeneration int64
@@ -781,6 +786,15 @@ type BucketWebsite struct {
781786
NotFoundPage string
782787
}
783788

789+
// CustomPlacementConfig holds the bucket's custom placement
790+
// configuration for Custom Dual Regions. See
791+
// https://cloud.google.com/storage/docs/locations#location-dr for more information.
792+
type CustomPlacementConfig struct {
793+
// The list of regional locations in which data is placed.
794+
// Custom Dual Regions require exactly 2 regional locations.
795+
DataLocations []string
796+
}
797+
784798
func newBucket(b *raw.Bucket) (*BucketAttrs, error) {
785799
if b == nil {
786800
return nil, nil
@@ -814,6 +828,7 @@ func newBucket(b *raw.Bucket) (*BucketAttrs, error) {
814828
LocationType: b.LocationType,
815829
ProjectNumber: b.ProjectNumber,
816830
RPO: toRPO(b),
831+
CustomPlacementConfig: customPlacementFromRaw(b.CustomPlacementConfig),
817832
}, nil
818833
}
819834

@@ -844,6 +859,7 @@ func newBucketFromProto(b *storagepb.Bucket) *BucketAttrs {
844859
PublicAccessPrevention: toPublicAccessPreventionFromProto(b.GetIamConfig()),
845860
LocationType: b.GetLocationType(),
846861
RPO: toRPOFromProto(b),
862+
CustomPlacementConfig: customPlacementFromProto(b.GetCustomPlacementConfig()),
847863
}
848864
}
849865

@@ -881,22 +897,23 @@ func (b *BucketAttrs) toRawBucket() *raw.Bucket {
881897
}
882898
}
883899
return &raw.Bucket{
884-
Name: b.Name,
885-
Location: b.Location,
886-
StorageClass: b.StorageClass,
887-
Acl: toRawBucketACL(b.ACL),
888-
DefaultObjectAcl: toRawObjectACL(b.DefaultObjectACL),
889-
Versioning: v,
890-
Labels: labels,
891-
Billing: bb,
892-
Lifecycle: toRawLifecycle(b.Lifecycle),
893-
RetentionPolicy: b.RetentionPolicy.toRawRetentionPolicy(),
894-
Cors: toRawCORS(b.CORS),
895-
Encryption: b.Encryption.toRawBucketEncryption(),
896-
Logging: b.Logging.toRawBucketLogging(),
897-
Website: b.Website.toRawBucketWebsite(),
898-
IamConfiguration: bktIAM,
899-
Rpo: b.RPO.String(),
900+
Name: b.Name,
901+
Location: b.Location,
902+
StorageClass: b.StorageClass,
903+
Acl: toRawBucketACL(b.ACL),
904+
DefaultObjectAcl: toRawObjectACL(b.DefaultObjectACL),
905+
Versioning: v,
906+
Labels: labels,
907+
Billing: bb,
908+
Lifecycle: toRawLifecycle(b.Lifecycle),
909+
RetentionPolicy: b.RetentionPolicy.toRawRetentionPolicy(),
910+
Cors: toRawCORS(b.CORS),
911+
Encryption: b.Encryption.toRawBucketEncryption(),
912+
Logging: b.Logging.toRawBucketLogging(),
913+
Website: b.Website.toRawBucketWebsite(),
914+
IamConfiguration: bktIAM,
915+
Rpo: b.RPO.String(),
916+
CustomPlacementConfig: b.CustomPlacementConfig.toRawCustomPlacement(),
900917
}
901918
}
902919

@@ -939,22 +956,23 @@ func (b *BucketAttrs) toProtoBucket() *storagepb.Bucket {
939956
}
940957

941958
return &storagepb.Bucket{
942-
Name: b.Name,
943-
Location: b.Location,
944-
StorageClass: b.StorageClass,
945-
Acl: toProtoBucketACL(b.ACL),
946-
DefaultObjectAcl: toProtoObjectACL(b.DefaultObjectACL),
947-
Versioning: v,
948-
Labels: labels,
949-
Billing: bb,
950-
Lifecycle: toProtoLifecycle(b.Lifecycle),
951-
RetentionPolicy: b.RetentionPolicy.toProtoRetentionPolicy(),
952-
Cors: toProtoCORS(b.CORS),
953-
Encryption: b.Encryption.toProtoBucketEncryption(),
954-
Logging: b.Logging.toProtoBucketLogging(),
955-
Website: b.Website.toProtoBucketWebsite(),
956-
IamConfig: bktIAM,
957-
Rpo: b.RPO.String(),
959+
Name: b.Name,
960+
Location: b.Location,
961+
StorageClass: b.StorageClass,
962+
Acl: toProtoBucketACL(b.ACL),
963+
DefaultObjectAcl: toProtoObjectACL(b.DefaultObjectACL),
964+
Versioning: v,
965+
Labels: labels,
966+
Billing: bb,
967+
Lifecycle: toProtoLifecycle(b.Lifecycle),
968+
RetentionPolicy: b.RetentionPolicy.toProtoRetentionPolicy(),
969+
Cors: toProtoCORS(b.CORS),
970+
Encryption: b.Encryption.toProtoBucketEncryption(),
971+
Logging: b.Logging.toProtoBucketLogging(),
972+
Website: b.Website.toProtoBucketWebsite(),
973+
IamConfig: bktIAM,
974+
Rpo: b.RPO.String(),
975+
CustomPlacementConfig: b.CustomPlacementConfig.toProtoCustomPlacement(),
958976
}
959977
}
960978

@@ -1932,6 +1950,38 @@ func toRPOFromProto(b *storagepb.Bucket) RPO {
19321950
}
19331951
}
19341952

1953+
func customPlacementFromRaw(c *raw.BucketCustomPlacementConfig) *CustomPlacementConfig {
1954+
if c == nil {
1955+
return nil
1956+
}
1957+
return &CustomPlacementConfig{DataLocations: c.DataLocations}
1958+
}
1959+
1960+
func (c *CustomPlacementConfig) toRawCustomPlacement() *raw.BucketCustomPlacementConfig {
1961+
if c == nil {
1962+
return nil
1963+
}
1964+
return &raw.BucketCustomPlacementConfig{
1965+
DataLocations: c.DataLocations,
1966+
}
1967+
}
1968+
1969+
func (c *CustomPlacementConfig) toProtoCustomPlacement() *storagepb.Bucket_CustomPlacementConfig {
1970+
if c == nil {
1971+
return nil
1972+
}
1973+
return &storagepb.Bucket_CustomPlacementConfig{
1974+
DataLocations: c.DataLocations,
1975+
}
1976+
}
1977+
1978+
func customPlacementFromProto(c *storagepb.Bucket_CustomPlacementConfig) *CustomPlacementConfig {
1979+
if c == nil {
1980+
return nil
1981+
}
1982+
return &CustomPlacementConfig{DataLocations: c.GetDataLocations()}
1983+
}
1984+
19351985
// Objects returns an iterator over the objects in the bucket that match the
19361986
// Query q. If q is nil, no filtering is done. Objects will be iterated over
19371987
// lexicographically by name.

storage/integration_test.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,13 @@ func TestIntegration_BucketCreateDelete(t *testing.T) {
314314

315315
// testedAttrs are the bucket attrs directly compared in this test
316316
type testedAttrs struct {
317-
StorageClass string
318-
VersioningEnabled bool
319-
LocationType string
320-
Labels map[string]string
321-
Location string
322-
Lifecycle Lifecycle
317+
StorageClass string
318+
VersioningEnabled bool
319+
LocationType string
320+
Labels map[string]string
321+
Location string
322+
Lifecycle Lifecycle
323+
CustomPlacementConfig *CustomPlacementConfig
323324
}
324325

325326
for _, test := range []struct {
@@ -358,12 +359,18 @@ func TestIntegration_BucketCreateDelete(t *testing.T) {
358359
{
359360
name: "dual-region",
360361
attrs: &BucketAttrs{
361-
Location: "US-EAST1+US-WEST1",
362+
Location: "US",
363+
CustomPlacementConfig: &CustomPlacementConfig{
364+
DataLocations: []string{"US-EAST1", "US-WEST1"},
365+
},
362366
},
363367
wantAttrs: testedAttrs{
364-
Location: "US-EAST1+US-WEST1",
368+
Location: "US",
365369
LocationType: "dual-region",
366370
StorageClass: "STANDARD",
371+
CustomPlacementConfig: &CustomPlacementConfig{
372+
DataLocations: []string{"US-EAST1", "US-WEST1"},
373+
},
367374
},
368375
},
369376
} {
@@ -407,6 +414,9 @@ func TestIntegration_BucketCreateDelete(t *testing.T) {
407414
if gotAttrs.Location != test.wantAttrs.Location {
408415
t.Errorf("location: got %s, want %s", gotAttrs.Location, test.wantAttrs.Location)
409416
}
417+
if got, want := gotAttrs.CustomPlacementConfig, test.wantAttrs.CustomPlacementConfig; !testutil.Equal(got, want) {
418+
t.Errorf("customPlacementConfig: \ngot\t%v\nwant\t%v", got, want)
419+
}
410420

411421
// Delete the bucket and check that the deletion was succesful
412422
if err := b.Delete(ctx); err != nil {

0 commit comments

Comments
 (0)