diff --git a/backend/api/v2beta1/artifacts.proto b/backend/api/v2beta1/artifacts.proto index b9b2a6458490..df1c940da7d7 100644 --- a/backend/api/v2beta1/artifacts.proto +++ b/backend/api/v2beta1/artifacts.proto @@ -55,6 +55,10 @@ message GetArtifactRequest { // Server responses include download_url DOWNLOAD = 2; + + // Server response includes a signed URL, + // allowing in-browser rendering or preview of the artifact. + RENDER = 3; } // Optional. Set to "DOWNLOAD" to included a signed URL with @@ -137,4 +141,7 @@ message Artifact { // and the error message is returned. Client has the flexibility of choosing // how to handle the error. This is especially useful when calling ListArtifacts. google.rpc.Status error = 11; + // Optional Output. Specifies a signed URL that can be used to + // render this Artifact directly from its store. + string render_url = 12; } diff --git a/backend/api/v2beta1/go_client/artifacts.pb.go b/backend/api/v2beta1/go_client/artifacts.pb.go index c7ec73e88615..fa87f4d36438 100644 --- a/backend/api/v2beta1/go_client/artifacts.pb.go +++ b/backend/api/v2beta1/go_client/artifacts.pb.go @@ -14,20 +14,16 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.33.0 -// protoc v3.17.3 -// source: backend/api/v2beta1/artifacts.proto +// protoc-gen-go v1.35.1 +// protoc v3.19.6 +// source: artifacts.proto package go_client import ( - context "context" _ "google.golang.org/genproto/googleapis/api/annotations" _ "google.golang.org/genproto/googleapis/api/httpbody" status "google.golang.org/genproto/googleapis/rpc/status" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status1 "google.golang.org/grpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" timestamppb "google.golang.org/protobuf/types/known/timestamppb" @@ -51,6 +47,9 @@ const ( GetArtifactRequest_BASIC GetArtifactRequest_ArtifactView = 1 // Server responses include download_url GetArtifactRequest_DOWNLOAD GetArtifactRequest_ArtifactView = 2 + // Server response includes a signed URL, + // allowing in-browser rendering or preview of the artifact. + GetArtifactRequest_RENDER GetArtifactRequest_ArtifactView = 3 ) // Enum value maps for GetArtifactRequest_ArtifactView. @@ -59,11 +58,13 @@ var ( 0: "ARTIFACT_VIEW_UNSPECIFIED", 1: "BASIC", 2: "DOWNLOAD", + 3: "RENDER", } GetArtifactRequest_ArtifactView_value = map[string]int32{ "ARTIFACT_VIEW_UNSPECIFIED": 0, "BASIC": 1, "DOWNLOAD": 2, + "RENDER": 3, } ) @@ -78,11 +79,11 @@ func (x GetArtifactRequest_ArtifactView) String() string { } func (GetArtifactRequest_ArtifactView) Descriptor() protoreflect.EnumDescriptor { - return file_backend_api_v2beta1_artifacts_proto_enumTypes[0].Descriptor() + return file_artifacts_proto_enumTypes[0].Descriptor() } func (GetArtifactRequest_ArtifactView) Type() protoreflect.EnumType { - return &file_backend_api_v2beta1_artifacts_proto_enumTypes[0] + return &file_artifacts_proto_enumTypes[0] } func (x GetArtifactRequest_ArtifactView) Number() protoreflect.EnumNumber { @@ -91,7 +92,7 @@ func (x GetArtifactRequest_ArtifactView) Number() protoreflect.EnumNumber { // Deprecated: Use GetArtifactRequest_ArtifactView.Descriptor instead. func (GetArtifactRequest_ArtifactView) EnumDescriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{0, 0} + return file_artifacts_proto_rawDescGZIP(), []int{0, 0} } type ListArtifactRequest_Field int32 @@ -130,11 +131,11 @@ func (x ListArtifactRequest_Field) String() string { } func (ListArtifactRequest_Field) Descriptor() protoreflect.EnumDescriptor { - return file_backend_api_v2beta1_artifacts_proto_enumTypes[1].Descriptor() + return file_artifacts_proto_enumTypes[1].Descriptor() } func (ListArtifactRequest_Field) Type() protoreflect.EnumType { - return &file_backend_api_v2beta1_artifacts_proto_enumTypes[1] + return &file_artifacts_proto_enumTypes[1] } func (x ListArtifactRequest_Field) Number() protoreflect.EnumNumber { @@ -143,7 +144,7 @@ func (x ListArtifactRequest_Field) Number() protoreflect.EnumNumber { // Deprecated: Use ListArtifactRequest_Field.Descriptor instead. func (ListArtifactRequest_Field) EnumDescriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{1, 0} + return file_artifacts_proto_rawDescGZIP(), []int{1, 0} } type GetArtifactRequest struct { @@ -165,11 +166,9 @@ type GetArtifactRequest struct { func (x *GetArtifactRequest) Reset() { *x = GetArtifactRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_artifacts_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *GetArtifactRequest) String() string { @@ -179,8 +178,8 @@ func (x *GetArtifactRequest) String() string { func (*GetArtifactRequest) ProtoMessage() {} func (x *GetArtifactRequest) ProtoReflect() protoreflect.Message { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_artifacts_proto_msgTypes[0] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -192,7 +191,7 @@ func (x *GetArtifactRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetArtifactRequest.ProtoReflect.Descriptor instead. func (*GetArtifactRequest) Descriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{0} + return file_artifacts_proto_rawDescGZIP(), []int{0} } func (x *GetArtifactRequest) GetArtifactId() string { @@ -235,11 +234,9 @@ type ListArtifactRequest struct { func (x *ListArtifactRequest) Reset() { *x = ListArtifactRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_artifacts_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListArtifactRequest) String() string { @@ -249,8 +246,8 @@ func (x *ListArtifactRequest) String() string { func (*ListArtifactRequest) ProtoMessage() {} func (x *ListArtifactRequest) ProtoReflect() protoreflect.Message { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_artifacts_proto_msgTypes[1] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -262,7 +259,7 @@ func (x *ListArtifactRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListArtifactRequest.ProtoReflect.Descriptor instead. func (*ListArtifactRequest) Descriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{1} + return file_artifacts_proto_rawDescGZIP(), []int{1} } func (x *ListArtifactRequest) GetMaxResultSize() int32 { @@ -313,11 +310,9 @@ type ListArtifactResponse struct { func (x *ListArtifactResponse) Reset() { *x = ListArtifactResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_artifacts_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ListArtifactResponse) String() string { @@ -327,8 +322,8 @@ func (x *ListArtifactResponse) String() string { func (*ListArtifactResponse) ProtoMessage() {} func (x *ListArtifactResponse) ProtoReflect() protoreflect.Message { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_artifacts_proto_msgTypes[2] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -340,7 +335,7 @@ func (x *ListArtifactResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListArtifactResponse.ProtoReflect.Descriptor instead. func (*ListArtifactResponse) Descriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{2} + return file_artifacts_proto_rawDescGZIP(), []int{2} } func (x *ListArtifactResponse) GetArtifacts() []*Artifact { @@ -392,15 +387,16 @@ type Artifact struct { // and the error message is returned. Client has the flexibility of choosing // how to handle the error. This is especially useful when calling ListArtifacts. Error *status.Status `protobuf:"bytes,11,opt,name=error,proto3" json:"error,omitempty"` + // Optional Output. Specifies a signed URL that can be used to + // render this Artifact directly from its store. + RenderUrl string `protobuf:"bytes,12,opt,name=render_url,json=renderUrl,proto3" json:"render_url,omitempty"` } func (x *Artifact) Reset() { *x = Artifact{} - if protoimpl.UnsafeEnabled { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_artifacts_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Artifact) String() string { @@ -410,8 +406,8 @@ func (x *Artifact) String() string { func (*Artifact) ProtoMessage() {} func (x *Artifact) ProtoReflect() protoreflect.Message { - mi := &file_backend_api_v2beta1_artifacts_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_artifacts_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -423,7 +419,7 @@ func (x *Artifact) ProtoReflect() protoreflect.Message { // Deprecated: Use Artifact.ProtoReflect.Descriptor instead. func (*Artifact) Descriptor() ([]byte, []int) { - return file_backend_api_v2beta1_artifacts_proto_rawDescGZIP(), []int{3} + return file_artifacts_proto_rawDescGZIP(), []int{3} } func (x *Artifact) GetArtifactId() string { @@ -503,138 +499,147 @@ func (x *Artifact) GetError() *status.Status { return nil } -var File_backend_api_v2beta1_artifacts_proto protoreflect.FileDescriptor - -var file_backend_api_v2beta1_artifacts_proto_rawDesc = []byte{ - 0x0a, 0x23, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x26, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, - 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f, 0x64, 0x79, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, - 0x70, 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0xda, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x5b, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, +func (x *Artifact) GetRenderUrl() string { + if x != nil { + return x.RenderUrl + } + return "" +} + +var File_artifacts_proto protoreflect.FileDescriptor + +var file_artifacts_proto_rawDesc = []byte{ + 0x0a, 0x0f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x12, 0x26, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe6, 0x01, 0x0a, + 0x12, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x49, 0x64, 0x12, 0x5b, 0x0a, 0x04, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x47, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x56, 0x69, 0x65, 0x77, 0x52, 0x04, 0x76, 0x69, 0x65, + 0x77, 0x22, 0x52, 0x0a, 0x0c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x56, 0x69, 0x65, + 0x77, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x5f, 0x56, 0x49, + 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x09, 0x0a, 0x05, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, + 0x4f, 0x57, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4e, + 0x44, 0x45, 0x52, 0x10, 0x03, 0x22, 0xd6, 0x02, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, + 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x67, 0x0a, 0x0e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, + 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, + 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, + 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x52, 0x0c, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x19, + 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, + 0x4d, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, 0x45, 0x4c, + 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, + 0x12, 0x14, 0x0a, 0x10, 0x4c, 0x41, 0x53, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, + 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x44, 0x10, 0x03, 0x22, 0x8e, + 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6b, 0x75, 0x62, + 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, + 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, + 0xde, 0x03, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, + 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x21, 0x0a, + 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x72, 0x6c, + 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, + 0x32, 0xec, 0x02, 0x0a, 0x0f, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0xab, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x3b, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x56, 0x69, 0x65, 0x77, 0x52, - 0x04, 0x76, 0x69, 0x65, 0x77, 0x22, 0x46, 0x0a, 0x0c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, - 0x74, 0x56, 0x69, 0x65, 0x77, 0x12, 0x1d, 0x0a, 0x19, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, - 0x54, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x41, 0x53, 0x49, 0x43, 0x10, 0x01, 0x12, - 0x0c, 0x0a, 0x08, 0x44, 0x4f, 0x57, 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x10, 0x02, 0x22, 0xd6, 0x02, - 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, - 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x67, 0x0a, - 0x0e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, - 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, - 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0c, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, - 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, - 0x62, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, - 0x79, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, - 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x4d, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, - 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4c, 0x41, 0x53, 0x54, - 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x06, - 0x0a, 0x02, 0x49, 0x44, 0x10, 0x03, 0x22, 0x8e, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x4e, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x12, 0x17, 0x2f, 0x61, 0x70, 0x69, 0x73, + 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x73, 0x12, 0xaa, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x12, 0x3a, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, - 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, - 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbf, 0x03, 0x0a, 0x08, 0x41, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, - 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, - 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, - 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x77, - 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x61, - 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x69, 0x7a, 0x65, - 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x6c, - 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x28, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xec, 0x02, 0x0a, 0x0f, 0x41, 0x72, - 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0xab, 0x01, - 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, - 0x3b, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, - 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3c, 0x2e, 0x6b, - 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, - 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, - 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x19, 0x12, 0x17, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0xaa, 0x01, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x3a, 0x2e, 0x6b, 0x75, - 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, - 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, - 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x2f, 0x7b, 0x61, 0x72, 0x74, 0x69, - 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x42, 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2f, - 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, - 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x6f, - 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, + 0x2e, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x73, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x61, 0x70, 0x69, 0x73, 0x2f, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x2f, 0x7b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x42, + 0x3d, 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, + 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, + 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x32, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2f, 0x67, 0x6f, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_backend_api_v2beta1_artifacts_proto_rawDescOnce sync.Once - file_backend_api_v2beta1_artifacts_proto_rawDescData = file_backend_api_v2beta1_artifacts_proto_rawDesc + file_artifacts_proto_rawDescOnce sync.Once + file_artifacts_proto_rawDescData = file_artifacts_proto_rawDesc ) -func file_backend_api_v2beta1_artifacts_proto_rawDescGZIP() []byte { - file_backend_api_v2beta1_artifacts_proto_rawDescOnce.Do(func() { - file_backend_api_v2beta1_artifacts_proto_rawDescData = protoimpl.X.CompressGZIP(file_backend_api_v2beta1_artifacts_proto_rawDescData) +func file_artifacts_proto_rawDescGZIP() []byte { + file_artifacts_proto_rawDescOnce.Do(func() { + file_artifacts_proto_rawDescData = protoimpl.X.CompressGZIP(file_artifacts_proto_rawDescData) }) - return file_backend_api_v2beta1_artifacts_proto_rawDescData + return file_artifacts_proto_rawDescData } -var file_backend_api_v2beta1_artifacts_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_backend_api_v2beta1_artifacts_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_backend_api_v2beta1_artifacts_proto_goTypes = []interface{}{ +var file_artifacts_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_artifacts_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_artifacts_proto_goTypes = []any{ (GetArtifactRequest_ArtifactView)(0), // 0: kubeflow.pipelines.backend.api.v2beta1.GetArtifactRequest.ArtifactView (ListArtifactRequest_Field)(0), // 1: kubeflow.pipelines.backend.api.v2beta1.ListArtifactRequest.Field (*GetArtifactRequest)(nil), // 2: kubeflow.pipelines.backend.api.v2beta1.GetArtifactRequest @@ -644,7 +649,7 @@ var file_backend_api_v2beta1_artifacts_proto_goTypes = []interface{}{ (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp (*status.Status)(nil), // 7: google.rpc.Status } -var file_backend_api_v2beta1_artifacts_proto_depIdxs = []int32{ +var file_artifacts_proto_depIdxs = []int32{ 0, // 0: kubeflow.pipelines.backend.api.v2beta1.GetArtifactRequest.view:type_name -> kubeflow.pipelines.backend.api.v2beta1.GetArtifactRequest.ArtifactView 1, // 1: kubeflow.pipelines.backend.api.v2beta1.ListArtifactRequest.order_by_field:type_name -> kubeflow.pipelines.backend.api.v2beta1.ListArtifactRequest.Field 5, // 2: kubeflow.pipelines.backend.api.v2beta1.ListArtifactResponse.artifacts:type_name -> kubeflow.pipelines.backend.api.v2beta1.Artifact @@ -662,204 +667,28 @@ var file_backend_api_v2beta1_artifacts_proto_depIdxs = []int32{ 0, // [0:6] is the sub-list for field type_name } -func init() { file_backend_api_v2beta1_artifacts_proto_init() } -func file_backend_api_v2beta1_artifacts_proto_init() { - if File_backend_api_v2beta1_artifacts_proto != nil { +func init() { file_artifacts_proto_init() } +func file_artifacts_proto_init() { + if File_artifacts_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_backend_api_v2beta1_artifacts_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetArtifactRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_backend_api_v2beta1_artifacts_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListArtifactRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_backend_api_v2beta1_artifacts_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListArtifactResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_backend_api_v2beta1_artifacts_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Artifact); 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{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_backend_api_v2beta1_artifacts_proto_rawDesc, + RawDescriptor: file_artifacts_proto_rawDesc, NumEnums: 2, NumMessages: 4, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_backend_api_v2beta1_artifacts_proto_goTypes, - DependencyIndexes: file_backend_api_v2beta1_artifacts_proto_depIdxs, - EnumInfos: file_backend_api_v2beta1_artifacts_proto_enumTypes, - MessageInfos: file_backend_api_v2beta1_artifacts_proto_msgTypes, + GoTypes: file_artifacts_proto_goTypes, + DependencyIndexes: file_artifacts_proto_depIdxs, + EnumInfos: file_artifacts_proto_enumTypes, + MessageInfos: file_artifacts_proto_msgTypes, }.Build() - File_backend_api_v2beta1_artifacts_proto = out.File - file_backend_api_v2beta1_artifacts_proto_rawDesc = nil - file_backend_api_v2beta1_artifacts_proto_goTypes = nil - file_backend_api_v2beta1_artifacts_proto_depIdxs = nil -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConnInterface - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion6 - -// ArtifactServiceClient is the client API for ArtifactService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ArtifactServiceClient interface { - // Finds all artifacts within the specified namespace. - // Namespace field is required. In multi-user mode, the caller - // is required to have RBAC verb "list" on the "artifacts" - // resource for the specified namespace. - ListArtifacts(ctx context.Context, in *ListArtifactRequest, opts ...grpc.CallOption) (*ListArtifactResponse, error) - // Finds a specific Artifact by ID. - GetArtifact(ctx context.Context, in *GetArtifactRequest, opts ...grpc.CallOption) (*Artifact, error) -} - -type artifactServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewArtifactServiceClient(cc grpc.ClientConnInterface) ArtifactServiceClient { - return &artifactServiceClient{cc} -} - -func (c *artifactServiceClient) ListArtifacts(ctx context.Context, in *ListArtifactRequest, opts ...grpc.CallOption) (*ListArtifactResponse, error) { - out := new(ListArtifactResponse) - err := c.cc.Invoke(ctx, "/kubeflow.pipelines.backend.api.v2beta1.ArtifactService/ListArtifacts", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *artifactServiceClient) GetArtifact(ctx context.Context, in *GetArtifactRequest, opts ...grpc.CallOption) (*Artifact, error) { - out := new(Artifact) - err := c.cc.Invoke(ctx, "/kubeflow.pipelines.backend.api.v2beta1.ArtifactService/GetArtifact", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ArtifactServiceServer is the server API for ArtifactService service. -type ArtifactServiceServer interface { - // Finds all artifacts within the specified namespace. - // Namespace field is required. In multi-user mode, the caller - // is required to have RBAC verb "list" on the "artifacts" - // resource for the specified namespace. - ListArtifacts(context.Context, *ListArtifactRequest) (*ListArtifactResponse, error) - // Finds a specific Artifact by ID. - GetArtifact(context.Context, *GetArtifactRequest) (*Artifact, error) -} - -// UnimplementedArtifactServiceServer can be embedded to have forward compatible implementations. -type UnimplementedArtifactServiceServer struct { -} - -func (*UnimplementedArtifactServiceServer) ListArtifacts(context.Context, *ListArtifactRequest) (*ListArtifactResponse, error) { - return nil, status1.Errorf(codes.Unimplemented, "method ListArtifacts not implemented") -} -func (*UnimplementedArtifactServiceServer) GetArtifact(context.Context, *GetArtifactRequest) (*Artifact, error) { - return nil, status1.Errorf(codes.Unimplemented, "method GetArtifact not implemented") -} - -func RegisterArtifactServiceServer(s *grpc.Server, srv ArtifactServiceServer) { - s.RegisterService(&_ArtifactService_serviceDesc, srv) -} - -func _ArtifactService_ListArtifacts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListArtifactRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ArtifactServiceServer).ListArtifacts(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/kubeflow.pipelines.backend.api.v2beta1.ArtifactService/ListArtifacts", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArtifactServiceServer).ListArtifacts(ctx, req.(*ListArtifactRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _ArtifactService_GetArtifact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetArtifactRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ArtifactServiceServer).GetArtifact(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/kubeflow.pipelines.backend.api.v2beta1.ArtifactService/GetArtifact", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArtifactServiceServer).GetArtifact(ctx, req.(*GetArtifactRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _ArtifactService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "kubeflow.pipelines.backend.api.v2beta1.ArtifactService", - HandlerType: (*ArtifactServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ListArtifacts", - Handler: _ArtifactService_ListArtifacts_Handler, - }, - { - MethodName: "GetArtifact", - Handler: _ArtifactService_GetArtifact_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "backend/api/v2beta1/artifacts.proto", + File_artifacts_proto = out.File + file_artifacts_proto_rawDesc = nil + file_artifacts_proto_goTypes = nil + file_artifacts_proto_depIdxs = nil } diff --git a/backend/api/v2beta1/swagger/artifacts.swagger.json b/backend/api/v2beta1/swagger/artifacts.swagger.json index 3cff7100059a..83e51e8cc539 100644 --- a/backend/api/v2beta1/swagger/artifacts.swagger.json +++ b/backend/api/v2beta1/swagger/artifacts.swagger.json @@ -4,6 +4,11 @@ "title": "backend/api/v2beta1/artifacts.proto", "version": "version not set" }, + "tags": [ + { + "name": "ArtifactService" + } + ], "consumes": [ "application/json" ], @@ -25,22 +30,22 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/runtimeError" + "$ref": "#/definitions/rpcStatus" } } }, "parameters": [ { - "name": "max_result_size", - "description": "Optional.\nMax number of resources to return in the result. A value of zero or less\nwill result in the default (20).\nThe API implementation also enforces an upper-bound of 100, and picks the\nminimum between this value and the one specified here.\n[default = 20].", + "name": "maxResultSize", + "description": "Optional.\nMax number of resources to return in the result. A value of zero or less\nwill result in the default (20).\nThe API implementation also enforces an upper-bound of 100, and picks the\nminimum between this value and the one specified here.\n[default = 20]", "in": "query", "required": false, "type": "integer", "format": "int32" }, { - "name": "order_by_field", - "description": "Optional. Ordering field. [default = ID].", + "name": "orderByField", + "description": "Optional. Ordering field. [default = ID]", "in": "query", "required": false, "type": "string", @@ -53,14 +58,14 @@ "default": "FIELD_UNSPECIFIED" }, { - "name": "order_by", - "description": "Optional. Can be either \"asc\" (ascending) or \"desc\" (descending). [default = asc].", + "name": "orderBy", + "description": "Optional. Can be either \"asc\" (ascending) or \"desc\" (descending). [default = asc]", "in": "query", "required": false, "type": "string" }, { - "name": "next_page_token", + "name": "nextPageToken", "description": "Optional. The next_page_token value returned from a previous List request, if any.", "in": "query", "required": false, @@ -79,7 +84,7 @@ ] } }, - "/apis/v2beta1/artifacts/{artifact_id}": { + "/apis/v2beta1/artifacts/{artifactId}": { "get": { "summary": "Finds a specific Artifact by ID.", "operationId": "ArtifactService_GetArtifact", @@ -93,13 +98,13 @@ "default": { "description": "An unexpected error response.", "schema": { - "$ref": "#/definitions/runtimeError" + "$ref": "#/definitions/rpcStatus" } } }, "parameters": [ { - "name": "artifact_id", + "name": "artifactId", "description": "Required. The ID of the artifact to be retrieved.", "in": "path", "required": true, @@ -107,14 +112,15 @@ }, { "name": "view", - "description": "Optional. Set to \"DOWNLOAD\" to included a signed URL with\nan expiry (default 15 seconds, unless configured other wise).\nThis URL can be used to download the Artifact directly from\nthe Artifact's storage provider. Set to \"BASIC\" to exclude\nthe download_url from server responses, thus preventing the\ncreation of any signed url.\nDefaults to BASIC.\n\n - ARTIFACT_VIEW_UNSPECIFIED: Not specified, equivalent to BASIC.\n - BASIC: Server responses excludes download_url\n - DOWNLOAD: Server responses include download_url", + "description": "Optional. Set to \"DOWNLOAD\" to included a signed URL with\nan expiry (default 15 seconds, unless configured other wise).\nThis URL can be used to download the Artifact directly from\nthe Artifact's storage provider. Set to \"BASIC\" to exclude\nthe download_url from server responses, thus preventing the\ncreation of any signed url.\nDefaults to BASIC.\n\n - ARTIFACT_VIEW_UNSPECIFIED: Not specified, equivalent to BASIC.\n - BASIC: Server responses excludes download_url\n - DOWNLOAD: Server responses include download_url\n - RENDER: Server response includes a signed URL,\nallowing in-browser rendering or preview of the artifact.", "in": "query", "required": false, "type": "string", "enum": [ "ARTIFACT_VIEW_UNSPECIFIED", "BASIC", - "DOWNLOAD" + "DOWNLOAD", + "RENDER" ], "default": "ARTIFACT_VIEW_UNSPECIFIED" } @@ -131,10 +137,11 @@ "enum": [ "ARTIFACT_VIEW_UNSPECIFIED", "BASIC", - "DOWNLOAD" + "DOWNLOAD", + "RENDER" ], "default": "ARTIFACT_VIEW_UNSPECIFIED", - "title": "- ARTIFACT_VIEW_UNSPECIFIED: Not specified, equivalent to BASIC.\n - BASIC: Server responses excludes download_url\n - DOWNLOAD: Server responses include download_url" + "description": " - ARTIFACT_VIEW_UNSPECIFIED: Not specified, equivalent to BASIC.\n - BASIC: Server responses excludes download_url\n - DOWNLOAD: Server responses include download_url\n - RENDER: Server response includes a signed URL,\nallowing in-browser rendering or preview of the artifact." }, "ListArtifactRequestField": { "type": "string", @@ -146,7 +153,18 @@ ], "default": "FIELD_UNSPECIFIED" }, - "googlerpcStatus": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com. As of May 2023, there are no widely used type server\nimplementations and no plans to implement one.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics." + } + }, + "additionalProperties": {}, + "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n // or ...\n if (any.isSameTypeAs(Foo.getDefaultInstance())) {\n foo = any.unpack(Foo.getDefaultInstance());\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" + }, + "rpcStatus": { "type": "object", "properties": { "code": { @@ -161,6 +179,7 @@ "details": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/protobufAny" }, "description": "A list of messages that carry the error details. There is a common set of\nmessage types for APIs to use." @@ -168,54 +187,18 @@ }, "description": "The `Status` type defines a logical error model that is suitable for\ndifferent programming environments, including REST APIs and RPC APIs. It is\nused by [gRPC](https://github.com/grpc). Each `Status` message contains\nthree pieces of data: error code, error message, and error details.\n\nYou can find out more about this error model and how to work with it in the\n[API Design Guide](https://cloud.google.com/apis/design/errors)." }, - "protobufAny": { - "type": "object", - "properties": { - "type_url": { - "type": "string", - "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics." - }, - "value": { - "type": "string", - "format": "byte", - "description": "Must be a valid serialized protocol buffer of the above specified type." - } - }, - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := anypb.New(foo)\n if err != nil {\n ...\n }\n ...\n foo := \u0026pb.Foo{}\n if err := any.UnmarshalTo(foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" - }, - "runtimeError": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/definitions/protobufAny" - } - } - } - }, "v2beta1Artifact": { "type": "object", "properties": { - "artifact_id": { + "artifactId": { "type": "string", "description": "Unique Artifact ID. Generated by MLMD." }, - "storage_provider": { + "storageProvider": { "type": "string", "description": "Storage Provider to which this Artifact is located (e.g. S3, Minio, etc.)." }, - "storage_path": { + "storagePath": { "type": "string", "description": "The path location of this Artifact within the storage provider.\nFor example an object located at s3://my-bucket/path/a/b/c will\nresult in \"path/a/b/c\"." }, @@ -223,7 +206,7 @@ "type": "string", "title": "The Artifact URI" }, - "download_url": { + "downloadUrl": { "type": "string", "description": "Optional Output. Specifies a signed-url that can be used to\ndownload this Artifact directly from its store." }, @@ -231,28 +214,32 @@ "type": "string", "description": "The namespace associated with this Artifact. This is determined\nby the namespace of the parent PipelineRun that created this Artifact." }, - "artifact_type": { + "artifactType": { "type": "string", "title": "The MLMD type of the artifact (e.g. system.Dataset)" }, - "artifact_size": { + "artifactSize": { "type": "string", "format": "int64", "description": "The size of the artifact in bytes.\nIf the artifact does not exist in object store (e.g. Metrics)\nthen this is omitted." }, - "created_at": { + "createdAt": { "type": "string", "format": "date-time", "description": "Creation time of the artifact." }, - "last_updated_at": { + "lastUpdatedAt": { "type": "string", "format": "date-time", "description": "Last update time of the artifact." }, "error": { - "$ref": "#/definitions/googlerpcStatus", + "$ref": "#/definitions/rpcStatus", "description": "In case any error happens retrieving an artifact field, only artifact ID\nand the error message is returned. Client has the flexibility of choosing\nhow to handle the error. This is especially useful when calling ListArtifacts." + }, + "renderUrl": { + "type": "string", + "description": "Optional Output. Specifies a signed URL that can be used to\nrender this Artifact directly from its store." } } }, @@ -262,11 +249,12 @@ "artifacts": { "type": "array", "items": { + "type": "object", "$ref": "#/definitions/v2beta1Artifact" }, "description": "List of retrieved artifacts." }, - "next_page_token": { + "nextPageToken": { "type": "string", "title": "Token to retrieve the next page of results, or empty if there are none" } diff --git a/backend/src/apiserver/resource/resource_manager.go b/backend/src/apiserver/resource/resource_manager.go index 201f19d5e9ac..732a6d780d33 100644 --- a/backend/src/apiserver/resource/resource_manager.go +++ b/backend/src/apiserver/resource/resource_manager.go @@ -2052,6 +2052,14 @@ func (r *ResourceManager) GetSignedUrl(bucketConfig *objectstore.Config, secret return signedUrl, nil } +func (r *ResourceManager) GetSignedUrlWithoutContentDisposition(bucketConfig *objectstore.Config, secret *corev1.Secret, expirySeconds time.Duration, artifactURI string) (string, error) { + signedUrl, err := r.objectStore.GetSignedUrlWithoutContentDisposition(bucketConfig, secret, expirySeconds, artifactURI) + if err != nil { + return "", err + } + return signedUrl, nil +} + // GetObjectSize retrieves the size of the Artifact's object in bytes. func (r *ResourceManager) GetObjectSize(bucketConfig *objectstore.Config, secret *corev1.Secret, artifactURI string) (int64, error) { size, err := r.objectStore.GetObjectSize(bucketConfig, secret, artifactURI) diff --git a/backend/src/apiserver/resource/resource_manager_test.go b/backend/src/apiserver/resource/resource_manager_test.go index 5049a6b2bae7..b29b84a3b68d 100644 --- a/backend/src/apiserver/resource/resource_manager_test.go +++ b/backend/src/apiserver/resource/resource_manager_test.go @@ -87,6 +87,10 @@ func (m *FakeBadObjectStore) GetSignedUrl(bucketConfig *objectstore.Config, secr return "", util.NewInternalServerError(errors.New("Error"), "bad object store") } +func (m *FakeBadObjectStore) GetSignedUrlWithoutContentDisposition(bucketConfig *objectstore.Config, secret *corev1.Secret, expirySeconds time.Duration, artifactURI string) (string, error) { + return "", util.NewInternalServerError(errors.New("Error"), "bad object store") +} + func (m *FakeBadObjectStore) GetObjectSize(bucketConfig *objectstore.Config, secret *corev1.Secret, artifactURI string) (int64, error) { return 0, util.NewInternalServerError(errors.New("Error"), "bad object store") } diff --git a/backend/src/apiserver/server/artifact_server.go b/backend/src/apiserver/server/artifact_server.go index 55028c280e70..2448d37010dc 100644 --- a/backend/src/apiserver/server/artifact_server.go +++ b/backend/src/apiserver/server/artifact_server.go @@ -141,7 +141,7 @@ func (s *ArtifactServer) ListArtifacts(ctx context.Context, r *apiv2beta1.ListAr if err1 != nil || bucketConfig == nil { return nil, util.NewInternalServerError(fmt.Errorf("failed to retrieve session info error: %v", err1), artifactId) } - artifactResp, err1 := s.generateResponseArtifact(ctx, artifact, bucketConfig, namespace, false) + artifactResp, err1 := s.generateResponseArtifact(ctx, artifact, bucketConfig, namespace, false, false) if err1 != nil { return nil, util.NewInternalServerError(fmt.Errorf("encountered error parsing artifact: %v", err), artifactId) } @@ -186,12 +186,15 @@ func (s *ArtifactServer) GetArtifact(ctx context.Context, r *apiv2beta1.GetArtif return nil, util.Wrap(err, "Failed to authorize the request") } - downloadURL := false - if r.GetView() == apiv2beta1.GetArtifactRequest_DOWNLOAD { + downloadURL, renderURL := false, false + + switch r.GetView() { + case apiv2beta1.GetArtifactRequest_DOWNLOAD: downloadURL = true + case apiv2beta1.GetArtifactRequest_RENDER: + renderURL = true } - - artifactResp, err := s.generateResponseArtifact(ctx, artifact, sessionInfo, namespace, downloadURL) + artifactResp, err := s.generateResponseArtifact(ctx, artifact, sessionInfo, namespace, downloadURL, renderURL) if err != nil { return nil, util.NewInternalServerError(fmt.Errorf("encountered error parsing artifact: %v", err), r.ArtifactId) } @@ -212,6 +215,7 @@ func (s *ArtifactServer) generateResponseArtifact( bucketConfig *objectstore.Config, namespace string, includeShareUrl bool, + includeRenderUrl bool, ) (*apiv2beta1.Artifact, error) { params, err := objectstore.StructuredS3Params(bucketConfig.SessionInfo.Params) if err != nil { @@ -251,6 +255,15 @@ func (s *ArtifactServer) generateResponseArtifact( artifactResp.DownloadUrl = shareUrl } + if includeRenderUrl { + expiry := time.Second * time.Duration(common.GetSignedURLExpiryTimeSeconds()) + renderUrl, err := s.resourceManager.GetSignedUrlWithoutContentDisposition(bucketConfig, secret, expiry, *artifact.Uri) + if err != nil { + return nil, err + } + artifactResp.RenderUrl = renderUrl + } + return artifactResp, nil } diff --git a/backend/src/apiserver/storage/object_store.go b/backend/src/apiserver/storage/object_store.go index b0659abe5f36..6d2072322226 100644 --- a/backend/src/apiserver/storage/object_store.go +++ b/backend/src/apiserver/storage/object_store.go @@ -41,6 +41,7 @@ type ObjectStoreInterface interface { GetFromYamlFile(o interface{}, filePath string) error GetPipelineKey(pipelineId string) string GetSignedUrl(bucketConfig *objectstore.Config, secret *v1.Secret, expirySeconds time.Duration, artifactURI string) (string, error) + GetSignedUrlWithoutContentDisposition(bucketConfig *objectstore.Config, secret *v1.Secret, expirySeconds time.Duration, artifactURI string) (string, error) GetObjectSize(bucketConfig *objectstore.Config, secret *v1.Secret, artifactURI string) (int64, error) } @@ -151,6 +152,26 @@ func (m *MinioObjectStore) GetSignedUrl(bucketConfig *objectstore.Config, secret return signedUrl.String(), nil } +func (m *MinioObjectStore) GetSignedUrlWithoutContentDisposition(bucketConfig *objectstore.Config, secret *v1.Secret, expirySeconds time.Duration, artifactURI string) (string, error) { + s3Client, err := buildClientFromConfig(bucketConfig, secret) + if err != nil { + return "", err + } + + key, err := objectstore.ArtifactKeyFromURI(artifactURI) + if err != nil { + return "", err + } + reqParams := make(url.Values) + reqParams.Set("response-content-disposition", "inline") + signedUrl, err := s3Client.Presign("GET", bucketConfig.BucketName, key, expirySeconds, reqParams) + if err != nil { + return "", util.Wrap(err, "Failed to generate signed url") + } + + return signedUrl.String(), nil +} + // GetObjectSize Retrieves the Size of the object in bytes. // Return zero with no error if artifact URI does not exist. func (m *MinioObjectStore) GetObjectSize(bucketConfig *objectstore.Config, secret *v1.Secret, artifactURI string) (int64, error) { diff --git a/backend/src/apiserver/storage/object_store_fake.go b/backend/src/apiserver/storage/object_store_fake.go index 04d285799e1d..c04cd7948978 100644 --- a/backend/src/apiserver/storage/object_store_fake.go +++ b/backend/src/apiserver/storage/object_store_fake.go @@ -15,9 +15,10 @@ package storage import ( - "github.com/kubeflow/pipelines/backend/src/v2/objectstore" - "k8s.io/api/core/v1" "time" + + "github.com/kubeflow/pipelines/backend/src/v2/objectstore" + v1 "k8s.io/api/core/v1" ) type fakeMinioObjectStore struct { @@ -52,6 +53,10 @@ func (m *fakeMinioObjectStore) GetSignedUrl(*objectstore.Config, *v1.Secret, tim return "dummy-signed-url", nil } +func (m *fakeMinioObjectStore) GetSignedUrlWithoutContentDisposition(*objectstore.Config, *v1.Secret, time.Duration, string) (string, error) { + return "dummy-render-url", nil +} + func (m *fakeMinioObjectStore) GetObjectSize(*objectstore.Config, *v1.Secret, string) (int64, error) { return 123, nil }