diff --git a/internal/plugin/loopback/client.go b/internal/plugin/loopback/client.go index 98d47e63a..76f83a5ba 100644 --- a/internal/plugin/loopback/client.go +++ b/internal/plugin/loopback/client.go @@ -102,3 +102,7 @@ func (tpc *WrappingPluginStorageClient) GetObject(ctx context.Context, req *plgp func (tpc *WrappingPluginStorageClient) PutObject(ctx context.Context, req *plgpb.PutObjectRequest, opts ...grpc.CallOption) (*plgpb.PutObjectResponse, error) { return tpc.Server.PutObject(ctx, req) } + +func (tpc *WrappingPluginStorageClient) DeleteObjects(ctx context.Context, req *plgpb.DeleteObjectsRequest, opts ...grpc.CallOption) (*plgpb.DeleteObjectsResponse, error) { + return tpc.Server.DeleteObjects(ctx, req) +} diff --git a/internal/plugin/loopback/loopback.go b/internal/plugin/loopback/loopback.go index 5f23295f8..a973215dc 100644 --- a/internal/plugin/loopback/loopback.go +++ b/internal/plugin/loopback/loopback.go @@ -75,6 +75,7 @@ func NewLoopbackPlugin(opt ...TestOption) (*LoopbackPlugin, error) { ret.HeadObjectFn = ret.headObject ret.GetObjectFn = ret.getObject ret.PutObjectFn = ret.putObject + ret.DeleteObjectsFn = ret.deleteObjects if len(opts.withMockBuckets) > 0 { ret.buckets = opts.withMockBuckets } diff --git a/internal/plugin/loopback/options.go b/internal/plugin/loopback/options.go index f802b5333..9c345a02f 100644 --- a/internal/plugin/loopback/options.go +++ b/internal/plugin/loopback/options.go @@ -36,6 +36,9 @@ const ( // Will return an error for the PutObject method PutObject + + // Will return an error for the DeleteObjects method + DeleteObjects ) const ( diff --git a/internal/plugin/loopback/storage.go b/internal/plugin/loopback/storage.go index 431703ca0..497f4c1b5 100644 --- a/internal/plugin/loopback/storage.go +++ b/internal/plugin/loopback/storage.go @@ -10,6 +10,7 @@ import ( "io" "os" "path" + "strings" "sync" "time" @@ -32,6 +33,7 @@ type TestPluginStorageServer struct { HeadObjectFn func(context.Context, *plgpb.HeadObjectRequest) (*plgpb.HeadObjectResponse, error) GetObjectFn func(*plgpb.GetObjectRequest, plgpb.StoragePluginService_GetObjectServer) error PutObjectFn func(context.Context, *plgpb.PutObjectRequest) (*plgpb.PutObjectResponse, error) + DeleteObjectsFn func(context.Context, *plgpb.DeleteObjectsRequest) (*plgpb.DeleteObjectsResponse, error) plgpb.UnimplementedStoragePluginServiceServer } @@ -84,6 +86,13 @@ func (t TestPluginStorageServer) PutObject(ctx context.Context, req *plgpb.PutOb return t.PutObjectFn(ctx, req) } +func (t TestPluginStorageServer) DeleteObjects(ctx context.Context, req *plgpb.DeleteObjectsRequest) (*plgpb.DeleteObjectsResponse, error) { + if t.DeleteObjectsFn == nil { + return t.UnimplementedStoragePluginServiceServer.DeleteObjects(ctx, req) + } + return t.DeleteObjectsFn(ctx, req) +} + type ( BucketName string ObjectName string @@ -406,6 +415,52 @@ func (l *LoopbackStorage) putObject(ctx context.Context, req *plgpb.PutObjectReq }, nil } +func (l *LoopbackStorage) deleteObjects(ctx context.Context, req *plgpb.DeleteObjectsRequest) (*plgpb.DeleteObjectsResponse, error) { + const op = "loopback.(LoopbackStorage).deleteObjects" + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "%s: request is nil", op) + } + if req.GetBucket() == nil { + return nil, status.Errorf(codes.InvalidArgument, "%s: missing storage bucket", op) + } + if req.GetBucket().GetAttributes() == nil { + return nil, status.Errorf(codes.InvalidArgument, "%s: missing attributes", op) + } + if req.GetKeyPrefix() == "" { + return nil, status.Errorf(codes.InvalidArgument, "%s; missing key prefix", op) + } + l.m.Lock() + defer l.m.Unlock() + bucket, ok := l.buckets[BucketName(req.GetBucket().GetBucketName())] + if !ok { + return nil, status.Errorf(codes.NotFound, "%s: bucket not found", op) + } + for _, err := range l.errs { + if err.match(req.GetBucket(), req.GetKeyPrefix(), DeleteObjects) { + return nil, status.Errorf(err.ErrCode, "%s: %s", op, err.ErrMsg) + } + } + prefix := ObjectName(req.GetBucket().GetBucketPrefix() + req.GetKeyPrefix()) + var deleted uint32 = 0 + if req.GetRecursive() { + for key := range bucket { + if strings.HasPrefix(string(key), string(prefix)) { + delete(bucket, key) + deleted++ + } + } + } else { + _, ok := bucket[prefix] + if ok { + delete(bucket, prefix) + deleted++ + } + } + return &plgpb.DeleteObjectsResponse{ + ObjectsDeleted: deleted, + }, nil +} + // CloneBucket returns a clone of the bucket. // returns nil when the bucket is not found. func (l *LoopbackStorage) CloneBucket(name string) Bucket { diff --git a/internal/plugin/loopback/storage_test.go b/internal/plugin/loopback/storage_test.go index afd7bfa42..ae0303597 100644 --- a/internal/plugin/loopback/storage_test.go +++ b/internal/plugin/loopback/storage_test.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "crypto/sha256" + "fmt" "io" "io/fs" "os" @@ -14,6 +15,7 @@ import ( "strings" "sync" "testing" + "time" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/storagebuckets" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -1224,6 +1226,199 @@ func TestLoopbackPutObject(t *testing.T) { } } +func TestLoopbackDeleteObjects(t *testing.T) { + require := tr.New(t) + + now := time.Now() + var zero int64 = 0 + mockStorageMapData := map[BucketName]Bucket{ + "object_store": { + ObjectName("test-file-1"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + ObjectName("test-file-2"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + ObjectName("test-file-3"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + ObjectName("abc/file-1"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + ObjectName("abc/file-2"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + ObjectName("abc/file-3"): &storagePluginStorageInfo{ + lastModified: &now, + contentLength: &zero, + DataChunks: []Chunk{}, + }, + }, + "object_store_err": {}, + } + + plg, err := NewLoopbackPlugin( + WithMockBuckets(mockStorageMapData), + WithMockError(PluginMockError{ + BucketName: "object_store_err", + ObjectKey: "mock_object", + ErrMsg: "invalid credentials", + ErrCode: codes.PermissionDenied, + }), + ) + require.NoError(err) + require.NotNil(plg) + + client := NewWrappingPluginStorageClient(plg) + + tests := []struct { + name string + request *plgpb.DeleteObjectsRequest + expected *plgpb.DeleteObjectsResponse + expectedErr string + check func() error + }{ + { + name: "valid delete object no recursive", + request: &plgpb.DeleteObjectsRequest{ + KeyPrefix: "test-file-1", + Bucket: &storagebuckets.StorageBucket{ + BucketName: "object_store", + Attributes: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "endpoint": structpb.NewStringValue("0.0.0.0"), + }, + }, + }, + Recursive: false, + }, + expected: &plgpb.DeleteObjectsResponse{ + ObjectsDeleted: 1, + }, + check: func() error { + filename := "test-file-1" + bucket, _ := mockStorageMapData["object_store"] + _, ok := bucket[ObjectName(filename)] + if ok { + return fmt.Errorf("failed to delete object %s", filename) + } + return nil + }, + }, { + name: "valid delete objects recursive", + request: &plgpb.DeleteObjectsRequest{ + KeyPrefix: "abc/", + Bucket: &storagebuckets.StorageBucket{ + BucketName: "object_store", + Attributes: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "endpoint": structpb.NewStringValue("0.0.0.0"), + }, + }, + }, + Recursive: true, + }, + expected: &plgpb.DeleteObjectsResponse{ + ObjectsDeleted: 3, + }, + check: func() error { + filenames := []string{ + "abc/file-1", + "abc/file-2", + "abc/file-3", + } + bucket, _ := mockStorageMapData["object_store"] + for _, filename := range filenames { + _, ok := bucket[ObjectName(filename)] + if ok { + return fmt.Errorf("failed to delete object %s", filename) + } + } + return nil + }, + }, { + name: "valid delete objects none", + request: &plgpb.DeleteObjectsRequest{ + KeyPrefix: "abcd/", + Bucket: &storagebuckets.StorageBucket{ + BucketName: "object_store", + Attributes: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "endpoint": structpb.NewStringValue("0.0.0.0"), + }, + }, + }, + Recursive: true, + }, + expected: &plgpb.DeleteObjectsResponse{ + ObjectsDeleted: 0, + }, + check: func() error { + return nil + }, + }, { + name: "delete objects object doesn't exist", + request: &plgpb.DeleteObjectsRequest{ + KeyPrefix: "non-existent-object", + Bucket: &storagebuckets.StorageBucket{ + BucketName: "object_store", + Attributes: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "endpoint": structpb.NewStringValue("0.0.0.0"), + }, + }, + }, + Recursive: false, + }, + expected: &plgpb.DeleteObjectsResponse{ + ObjectsDeleted: 0, + }, + check: func() error { + return nil + }, + }, { + name: "delete objects bucket doesn't exist", + request: &plgpb.DeleteObjectsRequest{ + KeyPrefix: "abc/", + Bucket: &storagebuckets.StorageBucket{ + BucketName: "non-existent-bucket", + Attributes: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "endpoint": structpb.NewStringValue("0.0.0.0"), + }, + }, + }, + Recursive: false, + }, + expectedErr: "loopback.(LoopbackStorage).deleteObjects: bucket not found", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resp, err := client.DeleteObjects(context.Background(), tt.request) + if tt.expectedErr != "" { + require.Error(err) + require.Nil(resp) + require.ErrorContains(err, tt.expectedErr) + return + } + + require.Equal(tt.expected, resp) + require.NoError(tt.check()) + }) + } +} + func TestLoopbackStoragePlugin(t *testing.T) { td := t.TempDir() diff --git a/internal/proto/plugin/v1/storage_plugin_service.proto b/internal/proto/plugin/v1/storage_plugin_service.proto index 632b189d9..51df8b023 100644 --- a/internal/proto/plugin/v1/storage_plugin_service.proto +++ b/internal/proto/plugin/v1/storage_plugin_service.proto @@ -37,6 +37,10 @@ service StoragePluginService { // PutObject is a hook that reads a file stored on local disk and // stores it to an external object store. rpc PutObject(PutObjectRequest) returns (PutObjectResponse); + + // DeleteObjects is a hook that deletes one or many files in an external object store + // via a provided key prefix. + rpc DeleteObjects(DeleteObjectsRequest) returns (DeleteObjectsResponse); } message OnCreateStorageBucketRequest { @@ -133,3 +137,33 @@ message PutObjectResponse { // 256-bit SHA-256 digest of the object. bytes checksum_sha_256 = 10; } + +message DeleteObjectsRequest { + // Required. The existing state of the storage bucket. + controller.api.resources.storagebuckets.v1.StorageBucket bucket = 10; + + // Required. The prefix of object keys to be deleted. + // + // Deletes all objects whose keys start with this field. Note that object storage keys + // use fully qualified names, including the full directory path in the object key. This + // allows you to delete entire "folders" stored on remote by passing the directory path + // and setting recursive to true, or only a single object by passing the object's full + // key and setting recursive to false. + string key_prefix = 20; + + // Required. Determines whether or not to delete all objects beginning with the prefix + // or only a single key that matches the prefix in its entirety. + // + // Note that this means when recursive = false, key_prefix is not treated as a prefix + // but as a fully qualified key. + bool recursive = 30; +} + +message DeleteObjectsResponse { + // The number of objects successfully deleted. + // + // Note that when receiving a successful response, the plugin guarantees that all + // objects beginning with the prefix have been deleted. This response is purely + // informational and not meant to be used for validation. + uint32 objects_deleted = 10; +} diff --git a/sdk/pbs/plugin/storage_plugin_service.pb.go b/sdk/pbs/plugin/storage_plugin_service.pb.go index 3173adb37..1d46951af 100644 --- a/sdk/pbs/plugin/storage_plugin_service.pb.go +++ b/sdk/pbs/plugin/storage_plugin_service.pb.go @@ -762,6 +762,134 @@ func (x *PutObjectResponse) GetChecksumSha_256() []byte { return nil } +type DeleteObjectsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Required. The existing state of the storage bucket. + Bucket *storagebuckets.StorageBucket `protobuf:"bytes,10,opt,name=bucket,proto3" json:"bucket,omitempty"` + // Required. The prefix of object keys to be deleted. + // + // Deletes all objects whose keys start with this field. Note that object storage keys + // use fully qualified names, including the full directory path in the object key. This + // allows you to delete entire "folders" stored on remote by passing the directory path + // and setting recursive to true, or only a single object by passing the object's full + // key and setting recursive to false. + KeyPrefix string `protobuf:"bytes,20,opt,name=key_prefix,json=keyPrefix,proto3" json:"key_prefix,omitempty"` + // Required. Determines whether or not to delete all objects beginning with the prefix + // or only a single key that matches the prefix in its entirety. + // + // Note that this means when recursive = false, key_prefix is not treated as a prefix + // but as a fully qualified key. + Recursive bool `protobuf:"varint,30,opt,name=recursive,proto3" json:"recursive,omitempty"` +} + +func (x *DeleteObjectsRequest) Reset() { + *x = DeleteObjectsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_v1_storage_plugin_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteObjectsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteObjectsRequest) ProtoMessage() {} + +func (x *DeleteObjectsRequest) ProtoReflect() protoreflect.Message { + mi := &file_plugin_v1_storage_plugin_service_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteObjectsRequest.ProtoReflect.Descriptor instead. +func (*DeleteObjectsRequest) Descriptor() ([]byte, []int) { + return file_plugin_v1_storage_plugin_service_proto_rawDescGZIP(), []int{14} +} + +func (x *DeleteObjectsRequest) GetBucket() *storagebuckets.StorageBucket { + if x != nil { + return x.Bucket + } + return nil +} + +func (x *DeleteObjectsRequest) GetKeyPrefix() string { + if x != nil { + return x.KeyPrefix + } + return "" +} + +func (x *DeleteObjectsRequest) GetRecursive() bool { + if x != nil { + return x.Recursive + } + return false +} + +type DeleteObjectsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The number of objects successfully deleted. + // + // Note that when receiving a successful response, the plugin guarantees that all + // objects beginning with the prefix have been deleted. This response is purely + // informational and not meant to be used for validation. + ObjectsDeleted uint32 `protobuf:"varint,10,opt,name=objects_deleted,json=objectsDeleted,proto3" json:"objects_deleted,omitempty"` +} + +func (x *DeleteObjectsResponse) Reset() { + *x = DeleteObjectsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_plugin_v1_storage_plugin_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteObjectsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteObjectsResponse) ProtoMessage() {} + +func (x *DeleteObjectsResponse) ProtoReflect() protoreflect.Message { + mi := &file_plugin_v1_storage_plugin_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteObjectsResponse.ProtoReflect.Descriptor instead. +func (*DeleteObjectsResponse) Descriptor() ([]byte, []int) { + return file_plugin_v1_storage_plugin_service_proto_rawDescGZIP(), []int{15} +} + +func (x *DeleteObjectsResponse) GetObjectsDeleted() uint32 { + if x != nil { + return x.ObjectsDeleted + } + return 0 +} + var File_plugin_v1_storage_plugin_service_proto protoreflect.FileDescriptor var file_plugin_v1_storage_plugin_service_proto_rawDesc = []byte{ @@ -883,53 +1011,73 @@ var file_plugin_v1_storage_plugin_service_proto_rawDesc = []byte{ 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x5f, 0x73, 0x68, 0x61, 0x5f, 0x32, 0x35, 0x36, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, - 0x75, 0x6d, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x32, 0x9d, 0x05, 0x0a, 0x14, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x4f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x75, 0x6d, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x22, 0xa6, 0x01, 0x0a, 0x14, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x51, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x06, 0x62, 0x75, + 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x50, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, + 0x18, 0x1e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, + 0x65, 0x22, 0x40, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x32, 0xf1, 0x05, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, + 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x4f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, - 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, - 0x15, 0x4f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, - 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x55, 0x70, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x6e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x4f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x4f, 0x6e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, - 0x65, 0x74, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, - 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, - 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, - 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x70, - 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a, 0x48, - 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, - 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x1b, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, - 0x12, 0x46, 0x0a, 0x09, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1b, 0x2e, - 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x6c, 0x75, - 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, - 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x12, 0x27, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, + 0x6b, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x15, 0x4f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x27, 0x2e, + 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x76, 0x31, 0x2e, 0x4f, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x64, 0x0a, 0x13, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x25, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x48, + 0x65, 0x61, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x48, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1b, + 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x46, 0x0a, 0x09, 0x50, + 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1b, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x75, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, 0x31, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, + 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, + 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -944,7 +1092,7 @@ func file_plugin_v1_storage_plugin_service_proto_rawDescGZIP() []byte { return file_plugin_v1_storage_plugin_service_proto_rawDescData } -var file_plugin_v1_storage_plugin_service_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_plugin_v1_storage_plugin_service_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_plugin_v1_storage_plugin_service_proto_goTypes = []interface{}{ (*OnCreateStorageBucketRequest)(nil), // 0: plugin.v1.OnCreateStorageBucketRequest (*OnCreateStorageBucketResponse)(nil), // 1: plugin.v1.OnCreateStorageBucketResponse @@ -960,43 +1108,48 @@ var file_plugin_v1_storage_plugin_service_proto_goTypes = []interface{}{ (*GetObjectResponse)(nil), // 11: plugin.v1.GetObjectResponse (*PutObjectRequest)(nil), // 12: plugin.v1.PutObjectRequest (*PutObjectResponse)(nil), // 13: plugin.v1.PutObjectResponse - (*storagebuckets.StorageBucket)(nil), // 14: controller.api.resources.storagebuckets.v1.StorageBucket - (*storagebuckets.StorageBucketPersisted)(nil), // 15: controller.api.resources.storagebuckets.v1.StorageBucketPersisted - (*timestamppb.Timestamp)(nil), // 16: google.protobuf.Timestamp + (*DeleteObjectsRequest)(nil), // 14: plugin.v1.DeleteObjectsRequest + (*DeleteObjectsResponse)(nil), // 15: plugin.v1.DeleteObjectsResponse + (*storagebuckets.StorageBucket)(nil), // 16: controller.api.resources.storagebuckets.v1.StorageBucket + (*storagebuckets.StorageBucketPersisted)(nil), // 17: controller.api.resources.storagebuckets.v1.StorageBucketPersisted + (*timestamppb.Timestamp)(nil), // 18: google.protobuf.Timestamp } var file_plugin_v1_storage_plugin_service_proto_depIdxs = []int32{ - 14, // 0: plugin.v1.OnCreateStorageBucketRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 15, // 1: plugin.v1.OnCreateStorageBucketResponse.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted - 14, // 2: plugin.v1.OnUpdateStorageBucketRequest.current_bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 14, // 3: plugin.v1.OnUpdateStorageBucketRequest.new_bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 15, // 4: plugin.v1.OnUpdateStorageBucketRequest.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted - 15, // 5: plugin.v1.OnUpdateStorageBucketResponse.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted - 14, // 6: plugin.v1.OnDeleteStorageBucketRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 15, // 7: plugin.v1.OnDeleteStorageBucketRequest.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted - 14, // 8: plugin.v1.ValidatePermissionsRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 14, // 9: plugin.v1.HeadObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 16, // 10: plugin.v1.HeadObjectResponse.last_modified:type_name -> google.protobuf.Timestamp - 14, // 11: plugin.v1.GetObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 14, // 12: plugin.v1.PutObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket - 0, // 13: plugin.v1.StoragePluginService.OnCreateStorageBucket:input_type -> plugin.v1.OnCreateStorageBucketRequest - 2, // 14: plugin.v1.StoragePluginService.OnUpdateStorageBucket:input_type -> plugin.v1.OnUpdateStorageBucketRequest - 4, // 15: plugin.v1.StoragePluginService.OnDeleteStorageBucket:input_type -> plugin.v1.OnDeleteStorageBucketRequest - 6, // 16: plugin.v1.StoragePluginService.ValidatePermissions:input_type -> plugin.v1.ValidatePermissionsRequest - 8, // 17: plugin.v1.StoragePluginService.HeadObject:input_type -> plugin.v1.HeadObjectRequest - 10, // 18: plugin.v1.StoragePluginService.GetObject:input_type -> plugin.v1.GetObjectRequest - 12, // 19: plugin.v1.StoragePluginService.PutObject:input_type -> plugin.v1.PutObjectRequest - 1, // 20: plugin.v1.StoragePluginService.OnCreateStorageBucket:output_type -> plugin.v1.OnCreateStorageBucketResponse - 3, // 21: plugin.v1.StoragePluginService.OnUpdateStorageBucket:output_type -> plugin.v1.OnUpdateStorageBucketResponse - 5, // 22: plugin.v1.StoragePluginService.OnDeleteStorageBucket:output_type -> plugin.v1.OnDeleteStorageBucketResponse - 7, // 23: plugin.v1.StoragePluginService.ValidatePermissions:output_type -> plugin.v1.ValidatePermissionsResponse - 9, // 24: plugin.v1.StoragePluginService.HeadObject:output_type -> plugin.v1.HeadObjectResponse - 11, // 25: plugin.v1.StoragePluginService.GetObject:output_type -> plugin.v1.GetObjectResponse - 13, // 26: plugin.v1.StoragePluginService.PutObject:output_type -> plugin.v1.PutObjectResponse - 20, // [20:27] is the sub-list for method output_type - 13, // [13:20] is the sub-list for method input_type - 13, // [13:13] is the sub-list for extension type_name - 13, // [13:13] is the sub-list for extension extendee - 0, // [0:13] is the sub-list for field type_name + 16, // 0: plugin.v1.OnCreateStorageBucketRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 17, // 1: plugin.v1.OnCreateStorageBucketResponse.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted + 16, // 2: plugin.v1.OnUpdateStorageBucketRequest.current_bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 16, // 3: plugin.v1.OnUpdateStorageBucketRequest.new_bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 17, // 4: plugin.v1.OnUpdateStorageBucketRequest.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted + 17, // 5: plugin.v1.OnUpdateStorageBucketResponse.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted + 16, // 6: plugin.v1.OnDeleteStorageBucketRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 17, // 7: plugin.v1.OnDeleteStorageBucketRequest.persisted:type_name -> controller.api.resources.storagebuckets.v1.StorageBucketPersisted + 16, // 8: plugin.v1.ValidatePermissionsRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 16, // 9: plugin.v1.HeadObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 18, // 10: plugin.v1.HeadObjectResponse.last_modified:type_name -> google.protobuf.Timestamp + 16, // 11: plugin.v1.GetObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 16, // 12: plugin.v1.PutObjectRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 16, // 13: plugin.v1.DeleteObjectsRequest.bucket:type_name -> controller.api.resources.storagebuckets.v1.StorageBucket + 0, // 14: plugin.v1.StoragePluginService.OnCreateStorageBucket:input_type -> plugin.v1.OnCreateStorageBucketRequest + 2, // 15: plugin.v1.StoragePluginService.OnUpdateStorageBucket:input_type -> plugin.v1.OnUpdateStorageBucketRequest + 4, // 16: plugin.v1.StoragePluginService.OnDeleteStorageBucket:input_type -> plugin.v1.OnDeleteStorageBucketRequest + 6, // 17: plugin.v1.StoragePluginService.ValidatePermissions:input_type -> plugin.v1.ValidatePermissionsRequest + 8, // 18: plugin.v1.StoragePluginService.HeadObject:input_type -> plugin.v1.HeadObjectRequest + 10, // 19: plugin.v1.StoragePluginService.GetObject:input_type -> plugin.v1.GetObjectRequest + 12, // 20: plugin.v1.StoragePluginService.PutObject:input_type -> plugin.v1.PutObjectRequest + 14, // 21: plugin.v1.StoragePluginService.DeleteObjects:input_type -> plugin.v1.DeleteObjectsRequest + 1, // 22: plugin.v1.StoragePluginService.OnCreateStorageBucket:output_type -> plugin.v1.OnCreateStorageBucketResponse + 3, // 23: plugin.v1.StoragePluginService.OnUpdateStorageBucket:output_type -> plugin.v1.OnUpdateStorageBucketResponse + 5, // 24: plugin.v1.StoragePluginService.OnDeleteStorageBucket:output_type -> plugin.v1.OnDeleteStorageBucketResponse + 7, // 25: plugin.v1.StoragePluginService.ValidatePermissions:output_type -> plugin.v1.ValidatePermissionsResponse + 9, // 26: plugin.v1.StoragePluginService.HeadObject:output_type -> plugin.v1.HeadObjectResponse + 11, // 27: plugin.v1.StoragePluginService.GetObject:output_type -> plugin.v1.GetObjectResponse + 13, // 28: plugin.v1.StoragePluginService.PutObject:output_type -> plugin.v1.PutObjectResponse + 15, // 29: plugin.v1.StoragePluginService.DeleteObjects:output_type -> plugin.v1.DeleteObjectsResponse + 22, // [22:30] is the sub-list for method output_type + 14, // [14:22] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_plugin_v1_storage_plugin_service_proto_init() } @@ -1173,6 +1326,30 @@ func file_plugin_v1_storage_plugin_service_proto_init() { return nil } } + file_plugin_v1_storage_plugin_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteObjectsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_plugin_v1_storage_plugin_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteObjectsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1180,7 +1357,7 @@ func file_plugin_v1_storage_plugin_service_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_plugin_v1_storage_plugin_service_proto_rawDesc, NumEnums: 0, - NumMessages: 14, + NumMessages: 16, NumExtensions: 0, NumServices: 1, }, diff --git a/sdk/pbs/plugin/storage_plugin_service_grpc.pb.go b/sdk/pbs/plugin/storage_plugin_service_grpc.pb.go index 370d4120c..3135dd550 100644 --- a/sdk/pbs/plugin/storage_plugin_service_grpc.pb.go +++ b/sdk/pbs/plugin/storage_plugin_service_grpc.pb.go @@ -29,6 +29,7 @@ const ( StoragePluginService_HeadObject_FullMethodName = "/plugin.v1.StoragePluginService/HeadObject" StoragePluginService_GetObject_FullMethodName = "/plugin.v1.StoragePluginService/GetObject" StoragePluginService_PutObject_FullMethodName = "/plugin.v1.StoragePluginService/PutObject" + StoragePluginService_DeleteObjects_FullMethodName = "/plugin.v1.StoragePluginService/DeleteObjects" ) // StoragePluginServiceClient is the client API for StoragePluginService service. @@ -54,6 +55,9 @@ type StoragePluginServiceClient interface { // PutObject is a hook that reads a file stored on local disk and // stores it to an external object store. PutObject(ctx context.Context, in *PutObjectRequest, opts ...grpc.CallOption) (*PutObjectResponse, error) + // DeleteObjects is a hook that deletes one or many files in an external object store + // via a provided key prefix. + DeleteObjects(ctx context.Context, in *DeleteObjectsRequest, opts ...grpc.CallOption) (*DeleteObjectsResponse, error) } type storagePluginServiceClient struct { @@ -150,6 +154,15 @@ func (c *storagePluginServiceClient) PutObject(ctx context.Context, in *PutObjec return out, nil } +func (c *storagePluginServiceClient) DeleteObjects(ctx context.Context, in *DeleteObjectsRequest, opts ...grpc.CallOption) (*DeleteObjectsResponse, error) { + out := new(DeleteObjectsResponse) + err := c.cc.Invoke(ctx, StoragePluginService_DeleteObjects_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // StoragePluginServiceServer is the server API for StoragePluginService service. // All implementations must embed UnimplementedStoragePluginServiceServer // for forward compatibility @@ -173,6 +186,9 @@ type StoragePluginServiceServer interface { // PutObject is a hook that reads a file stored on local disk and // stores it to an external object store. PutObject(context.Context, *PutObjectRequest) (*PutObjectResponse, error) + // DeleteObjects is a hook that deletes one or many files in an external object store + // via a provided key prefix. + DeleteObjects(context.Context, *DeleteObjectsRequest) (*DeleteObjectsResponse, error) mustEmbedUnimplementedStoragePluginServiceServer() } @@ -201,6 +217,9 @@ func (UnimplementedStoragePluginServiceServer) GetObject(*GetObjectRequest, Stor func (UnimplementedStoragePluginServiceServer) PutObject(context.Context, *PutObjectRequest) (*PutObjectResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method PutObject not implemented") } +func (UnimplementedStoragePluginServiceServer) DeleteObjects(context.Context, *DeleteObjectsRequest) (*DeleteObjectsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteObjects not implemented") +} func (UnimplementedStoragePluginServiceServer) mustEmbedUnimplementedStoragePluginServiceServer() {} // UnsafeStoragePluginServiceServer may be embedded to opt out of forward compatibility for this service. @@ -343,6 +362,24 @@ func _StoragePluginService_PutObject_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } +func _StoragePluginService_DeleteObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteObjectsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StoragePluginServiceServer).DeleteObjects(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: StoragePluginService_DeleteObjects_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StoragePluginServiceServer).DeleteObjects(ctx, req.(*DeleteObjectsRequest)) + } + return interceptor(ctx, in, info, handler) +} + // StoragePluginService_ServiceDesc is the grpc.ServiceDesc for StoragePluginService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -374,6 +411,10 @@ var StoragePluginService_ServiceDesc = grpc.ServiceDesc{ MethodName: "PutObject", Handler: _StoragePluginService_PutObject_Handler, }, + { + MethodName: "DeleteObjects", + Handler: _StoragePluginService_DeleteObjects_Handler, + }, }, Streams: []grpc.StreamDesc{ {