From 25664a80bd8575edf1ed81ae98c0f8bc20d7e4f1 Mon Sep 17 00:00:00 2001 From: ZhangEnYao Date: Mon, 18 May 2026 19:07:08 +0800 Subject: [PATCH 1/3] feat: add UpdateRequest message and update ResourceService --- openapi/openapi.yaml | 81 ++++++ proto/resource/v1/resource.proto | 40 +++ resource/v1/resource.connect.go | 40 +++ resource/v1/resource.pb.go | 393 +++++++++++++++++++++++++--- ts/src/resource/v1/resource_pb.d.ts | 83 ++++++ ts/src/resource/v1/resource_pb.js | 17 +- 6 files changed, 619 insertions(+), 35 deletions(-) diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index a92b5bb..58d5014 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -481,6 +481,46 @@ paths: application/json: schema: $ref: '#/components/schemas/otterscale.resource.v1.SchemaResponse' + /otterscale.resource.v1.ResourceService/Update: + post: + tags: + - ResourceService + summary: Update + description: |- + Update performs a full replacement (PUT) of an existing resource using + the provided manifest. The caller is responsible for supplying any + server-required fields (such as metadata.resourceVersion) inside the + manifest. + operationId: ResourceService_Update + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/otterscale.resource.v1.UpdateRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/otterscale.resource.v1.Resource' /otterscale.resource.v1.ResourceService/Watch: post: tags: @@ -2107,6 +2147,47 @@ components: title: SchemaResponse additionalProperties: false description: SchemaResponse contains the JSON Schema for a Kubernetes resource type. + otterscale.resource.v1.UpdateRequest: + type: object + properties: + cluster: + type: string + title: cluster + description: The target Kubernetes cluster identifier. + group: + type: string + title: group + description: Kubernetes API Group (e.g., "apps" for Deployments, "" for core resources like Pods). + version: + type: string + title: version + description: Kubernetes API Version (e.g., "v1"). + resource: + type: string + title: resource + description: Kubernetes API Resource name in plural (e.g., "pods", "deployments"). + namespace: + type: string + title: namespace + description: The namespace of the resource. + name: + type: string + title: name + description: The name of the resource. + manifest: + type: string + title: manifest + format: byte + description: |- + The full YAML manifest, in JSON form, that will replace the stored object. + Server-required fields such as metadata.resourceVersion must be included. + fieldManager: + type: string + title: field_manager + description: Identifies the entity submitting the update (e.g., "otterscale-web-ui"). + title: UpdateRequest + additionalProperties: false + description: UpdateRequest defines the parameters for a full-replacement update (PUT). otterscale.resource.v1.WatchEvent: type: object properties: diff --git a/proto/resource/v1/resource.proto b/proto/resource/v1/resource.proto index c9db885..9b9c503 100644 --- a/proto/resource/v1/resource.proto +++ b/proto/resource/v1/resource.proto @@ -51,6 +51,14 @@ service ResourceService { option (otterscale.api.feature) = {name: "resource-enabled"}; } + // Update performs a full replacement (PUT) of an existing resource using + // the provided manifest. The caller is responsible for supplying any + // server-required fields (such as metadata.resourceVersion) inside the + // manifest. + rpc Update(UpdateRequest) returns (Resource) { + option (otterscale.api.feature) = {name: "resource-enabled"}; + } + // Delete removes a resource from the cluster by its name. rpc Delete(DeleteRequest) returns (google.protobuf.Empty) { option (otterscale.api.feature) = {name: "resource-enabled"}; @@ -302,6 +310,38 @@ message ApplyRequest { string field_manager = 9; } +// --------------------------------------------------------------------------- +// Update +// --------------------------------------------------------------------------- + +// UpdateRequest defines the parameters for a full-replacement update (PUT). +message UpdateRequest { + // The target Kubernetes cluster identifier. + string cluster = 1; + + // Kubernetes API Group (e.g., "apps" for Deployments, "" for core resources like Pods). + string group = 2; + + // Kubernetes API Version (e.g., "v1"). + string version = 3; + + // Kubernetes API Resource name in plural (e.g., "pods", "deployments"). + string resource = 4; + + // The namespace of the resource. + string namespace = 5; + + // The name of the resource. + string name = 6; + + // The full YAML manifest, in JSON form, that will replace the stored object. + // Server-required fields such as metadata.resourceVersion must be included. + bytes manifest = 7; + + // Identifies the entity submitting the update (e.g., "otterscale-web-ui"). + string field_manager = 8; +} + // --------------------------------------------------------------------------- // Delete // --------------------------------------------------------------------------- diff --git a/resource/v1/resource.connect.go b/resource/v1/resource.connect.go index a3e463e..a6e15bd 100644 --- a/resource/v1/resource.connect.go +++ b/resource/v1/resource.connect.go @@ -49,6 +49,8 @@ const ( ResourceServiceCreateProcedure = "/otterscale.resource.v1.ResourceService/Create" // ResourceServiceApplyProcedure is the fully-qualified name of the ResourceService's Apply RPC. ResourceServiceApplyProcedure = "/otterscale.resource.v1.ResourceService/Apply" + // ResourceServiceUpdateProcedure is the fully-qualified name of the ResourceService's Update RPC. + ResourceServiceUpdateProcedure = "/otterscale.resource.v1.ResourceService/Update" // ResourceServiceDeleteProcedure is the fully-qualified name of the ResourceService's Delete RPC. ResourceServiceDeleteProcedure = "/otterscale.resource.v1.ResourceService/Delete" // ResourceServiceWatchProcedure is the fully-qualified name of the ResourceService's Watch RPC. @@ -76,6 +78,11 @@ type ResourceServiceClient interface { // Apply performs a Server-Side Apply (SSA) to update or create a resource. // This is the recommended way to perform partial updates. Apply(context.Context, *ApplyRequest) (*Resource, error) + // Update performs a full replacement (PUT) of an existing resource using + // the provided manifest. The caller is responsible for supplying any + // server-required fields (such as metadata.resourceVersion) inside the + // manifest. + Update(context.Context, *UpdateRequest) (*Resource, error) // Delete removes a resource from the cluster by its name. Delete(context.Context, *DeleteRequest) (*emptypb.Empty, error) // Watch initiates a server-side stream to monitor resource changes in real-time. @@ -135,6 +142,12 @@ func NewResourceServiceClient(httpClient connect.HTTPClient, baseURL string, opt connect.WithSchema(resourceServiceMethods.ByName("Apply")), connect.WithClientOptions(opts...), ), + update: connect.NewClient[UpdateRequest, Resource]( + httpClient, + baseURL+ResourceServiceUpdateProcedure, + connect.WithSchema(resourceServiceMethods.ByName("Update")), + connect.WithClientOptions(opts...), + ), delete: connect.NewClient[DeleteRequest, emptypb.Empty]( httpClient, baseURL+ResourceServiceDeleteProcedure, @@ -159,6 +172,7 @@ type resourceServiceClient struct { describe *connect.Client[DescribeRequest, DescribeResponse] create *connect.Client[CreateRequest, Resource] apply *connect.Client[ApplyRequest, Resource] + update *connect.Client[UpdateRequest, Resource] delete *connect.Client[DeleteRequest, emptypb.Empty] watch *connect.Client[WatchRequest, WatchEvent] } @@ -226,6 +240,15 @@ func (c *resourceServiceClient) Apply(ctx context.Context, req *ApplyRequest) (* return nil, err } +// Update calls otterscale.resource.v1.ResourceService.Update. +func (c *resourceServiceClient) Update(ctx context.Context, req *UpdateRequest) (*Resource, error) { + response, err := c.update.CallUnary(ctx, connect.NewRequest(req)) + if response != nil { + return response.Msg, err + } + return nil, err +} + // Delete calls otterscale.resource.v1.ResourceService.Delete. func (c *resourceServiceClient) Delete(ctx context.Context, req *DeleteRequest) (*emptypb.Empty, error) { response, err := c.delete.CallUnary(ctx, connect.NewRequest(req)) @@ -262,6 +285,11 @@ type ResourceServiceHandler interface { // Apply performs a Server-Side Apply (SSA) to update or create a resource. // This is the recommended way to perform partial updates. Apply(context.Context, *ApplyRequest) (*Resource, error) + // Update performs a full replacement (PUT) of an existing resource using + // the provided manifest. The caller is responsible for supplying any + // server-required fields (such as metadata.resourceVersion) inside the + // manifest. + Update(context.Context, *UpdateRequest) (*Resource, error) // Delete removes a resource from the cluster by its name. Delete(context.Context, *DeleteRequest) (*emptypb.Empty, error) // Watch initiates a server-side stream to monitor resource changes in real-time. @@ -317,6 +345,12 @@ func NewResourceServiceHandler(svc ResourceServiceHandler, opts ...connect.Handl connect.WithSchema(resourceServiceMethods.ByName("Apply")), connect.WithHandlerOptions(opts...), ) + resourceServiceUpdateHandler := connect.NewUnaryHandlerSimple( + ResourceServiceUpdateProcedure, + svc.Update, + connect.WithSchema(resourceServiceMethods.ByName("Update")), + connect.WithHandlerOptions(opts...), + ) resourceServiceDeleteHandler := connect.NewUnaryHandlerSimple( ResourceServiceDeleteProcedure, svc.Delete, @@ -345,6 +379,8 @@ func NewResourceServiceHandler(svc ResourceServiceHandler, opts ...connect.Handl resourceServiceCreateHandler.ServeHTTP(w, r) case ResourceServiceApplyProcedure: resourceServiceApplyHandler.ServeHTTP(w, r) + case ResourceServiceUpdateProcedure: + resourceServiceUpdateHandler.ServeHTTP(w, r) case ResourceServiceDeleteProcedure: resourceServiceDeleteHandler.ServeHTTP(w, r) case ResourceServiceWatchProcedure: @@ -386,6 +422,10 @@ func (UnimplementedResourceServiceHandler) Apply(context.Context, *ApplyRequest) return nil, connect.NewError(connect.CodeUnimplemented, errors.New("otterscale.resource.v1.ResourceService.Apply is not implemented")) } +func (UnimplementedResourceServiceHandler) Update(context.Context, *UpdateRequest) (*Resource, error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("otterscale.resource.v1.ResourceService.Update is not implemented")) +} + func (UnimplementedResourceServiceHandler) Delete(context.Context, *DeleteRequest) (*emptypb.Empty, error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("otterscale.resource.v1.ResourceService.Delete is not implemented")) } diff --git a/resource/v1/resource.pb.go b/resource/v1/resource.pb.go index fea8417..4bfd25d 100644 --- a/resource/v1/resource.pb.go +++ b/resource/v1/resource.pb.go @@ -2488,6 +2488,325 @@ func (b0 ApplyRequest_builder) Build() *ApplyRequest { return m0 } +// UpdateRequest defines the parameters for a full-replacement update (PUT). +type UpdateRequest struct { + state protoimpl.MessageState `protogen:"opaque.v1"` + xxx_hidden_Cluster *string `protobuf:"bytes,1,opt,name=cluster"` + xxx_hidden_Group *string `protobuf:"bytes,2,opt,name=group"` + xxx_hidden_Version *string `protobuf:"bytes,3,opt,name=version"` + xxx_hidden_Resource *string `protobuf:"bytes,4,opt,name=resource"` + xxx_hidden_Namespace *string `protobuf:"bytes,5,opt,name=namespace"` + xxx_hidden_Name *string `protobuf:"bytes,6,opt,name=name"` + xxx_hidden_Manifest []byte `protobuf:"bytes,7,opt,name=manifest"` + xxx_hidden_FieldManager *string `protobuf:"bytes,8,opt,name=field_manager,json=fieldManager"` + XXX_raceDetectHookData protoimpl.RaceDetectHookData + XXX_presence [1]uint32 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateRequest) Reset() { + *x = UpdateRequest{} + mi := &file_resource_v1_resource_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateRequest) ProtoMessage() {} + +func (x *UpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_resource_v1_resource_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +func (x *UpdateRequest) GetCluster() string { + if x != nil { + if x.xxx_hidden_Cluster != nil { + return *x.xxx_hidden_Cluster + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetGroup() string { + if x != nil { + if x.xxx_hidden_Group != nil { + return *x.xxx_hidden_Group + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetVersion() string { + if x != nil { + if x.xxx_hidden_Version != nil { + return *x.xxx_hidden_Version + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetResource() string { + if x != nil { + if x.xxx_hidden_Resource != nil { + return *x.xxx_hidden_Resource + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetNamespace() string { + if x != nil { + if x.xxx_hidden_Namespace != nil { + return *x.xxx_hidden_Namespace + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetName() string { + if x != nil { + if x.xxx_hidden_Name != nil { + return *x.xxx_hidden_Name + } + return "" + } + return "" +} + +func (x *UpdateRequest) GetManifest() []byte { + if x != nil { + return x.xxx_hidden_Manifest + } + return nil +} + +func (x *UpdateRequest) GetFieldManager() string { + if x != nil { + if x.xxx_hidden_FieldManager != nil { + return *x.xxx_hidden_FieldManager + } + return "" + } + return "" +} + +func (x *UpdateRequest) SetCluster(v string) { + x.xxx_hidden_Cluster = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 8) +} + +func (x *UpdateRequest) SetGroup(v string) { + x.xxx_hidden_Group = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 8) +} + +func (x *UpdateRequest) SetVersion(v string) { + x.xxx_hidden_Version = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 2, 8) +} + +func (x *UpdateRequest) SetResource(v string) { + x.xxx_hidden_Resource = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 3, 8) +} + +func (x *UpdateRequest) SetNamespace(v string) { + x.xxx_hidden_Namespace = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 4, 8) +} + +func (x *UpdateRequest) SetName(v string) { + x.xxx_hidden_Name = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 5, 8) +} + +func (x *UpdateRequest) SetManifest(v []byte) { + if v == nil { + v = []byte{} + } + x.xxx_hidden_Manifest = v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 6, 8) +} + +func (x *UpdateRequest) SetFieldManager(v string) { + x.xxx_hidden_FieldManager = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 7, 8) +} + +func (x *UpdateRequest) HasCluster() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 0) +} + +func (x *UpdateRequest) HasGroup() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 1) +} + +func (x *UpdateRequest) HasVersion() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 2) +} + +func (x *UpdateRequest) HasResource() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 3) +} + +func (x *UpdateRequest) HasNamespace() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 4) +} + +func (x *UpdateRequest) HasName() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 5) +} + +func (x *UpdateRequest) HasManifest() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 6) +} + +func (x *UpdateRequest) HasFieldManager() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 7) +} + +func (x *UpdateRequest) ClearCluster() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0) + x.xxx_hidden_Cluster = nil +} + +func (x *UpdateRequest) ClearGroup() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 1) + x.xxx_hidden_Group = nil +} + +func (x *UpdateRequest) ClearVersion() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 2) + x.xxx_hidden_Version = nil +} + +func (x *UpdateRequest) ClearResource() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 3) + x.xxx_hidden_Resource = nil +} + +func (x *UpdateRequest) ClearNamespace() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 4) + x.xxx_hidden_Namespace = nil +} + +func (x *UpdateRequest) ClearName() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 5) + x.xxx_hidden_Name = nil +} + +func (x *UpdateRequest) ClearManifest() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 6) + x.xxx_hidden_Manifest = nil +} + +func (x *UpdateRequest) ClearFieldManager() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 7) + x.xxx_hidden_FieldManager = nil +} + +type UpdateRequest_builder struct { + _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. + + // The target Kubernetes cluster identifier. + Cluster *string + // Kubernetes API Group (e.g., "apps" for Deployments, "" for core resources like Pods). + Group *string + // Kubernetes API Version (e.g., "v1"). + Version *string + // Kubernetes API Resource name in plural (e.g., "pods", "deployments"). + Resource *string + // The namespace of the resource. + Namespace *string + // The name of the resource. + Name *string + // The full YAML manifest, in JSON form, that will replace the stored object. + // Server-required fields such as metadata.resourceVersion must be included. + Manifest []byte + // Identifies the entity submitting the update (e.g., "otterscale-web-ui"). + FieldManager *string +} + +func (b0 UpdateRequest_builder) Build() *UpdateRequest { + m0 := &UpdateRequest{} + b, x := &b0, m0 + _, _ = b, x + if b.Cluster != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 8) + x.xxx_hidden_Cluster = b.Cluster + } + if b.Group != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 8) + x.xxx_hidden_Group = b.Group + } + if b.Version != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 2, 8) + x.xxx_hidden_Version = b.Version + } + if b.Resource != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 3, 8) + x.xxx_hidden_Resource = b.Resource + } + if b.Namespace != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 4, 8) + x.xxx_hidden_Namespace = b.Namespace + } + if b.Name != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 5, 8) + x.xxx_hidden_Name = b.Name + } + if b.Manifest != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 6, 8) + x.xxx_hidden_Manifest = b.Manifest + } + if b.FieldManager != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 7, 8) + x.xxx_hidden_FieldManager = b.FieldManager + } + return m0 +} + // DeleteRequest defines the parameters to remove an object. type DeleteRequest struct { state protoimpl.MessageState `protogen:"opaque.v1"` @@ -2506,7 +2825,7 @@ type DeleteRequest struct { func (x *DeleteRequest) Reset() { *x = DeleteRequest{} - mi := &file_resource_v1_resource_proto_msgTypes[13] + mi := &file_resource_v1_resource_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2518,7 +2837,7 @@ func (x *DeleteRequest) String() string { func (*DeleteRequest) ProtoMessage() {} func (x *DeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_v1_resource_proto_msgTypes[13] + mi := &file_resource_v1_resource_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2790,7 +3109,7 @@ type WatchRequest struct { func (x *WatchRequest) Reset() { *x = WatchRequest{} - mi := &file_resource_v1_resource_proto_msgTypes[14] + mi := &file_resource_v1_resource_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2802,7 +3121,7 @@ func (x *WatchRequest) String() string { func (*WatchRequest) ProtoMessage() {} func (x *WatchRequest) ProtoReflect() protoreflect.Message { - mi := &file_resource_v1_resource_proto_msgTypes[14] + mi := &file_resource_v1_resource_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3103,7 +3422,7 @@ type WatchEvent struct { func (x *WatchEvent) Reset() { *x = WatchEvent{} - mi := &file_resource_v1_resource_proto_msgTypes[15] + mi := &file_resource_v1_resource_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3115,7 +3434,7 @@ func (x *WatchEvent) String() string { func (*WatchEvent) ProtoMessage() {} func (x *WatchEvent) ProtoReflect() protoreflect.Message { - mi := &file_resource_v1_resource_proto_msgTypes[15] + mi := &file_resource_v1_resource_proto_msgTypes[16] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3306,7 +3625,16 @@ const file_resource_v1_resource_proto_rawDesc = "" + "\x04name\x18\x06 \x01(\tR\x04name\x12\x1a\n" + "\bmanifest\x18\a \x01(\fR\bmanifest\x12\x14\n" + "\x05force\x18\b \x01(\bR\x05force\x12#\n" + - "\rfield_manager\x18\t \x01(\tR\ffieldManager\"\xe0\x01\n" + + "\rfield_manager\x18\t \x01(\tR\ffieldManager\"\xe8\x01\n" + + "\rUpdateRequest\x12\x18\n" + + "\acluster\x18\x01 \x01(\tR\acluster\x12\x14\n" + + "\x05group\x18\x02 \x01(\tR\x05group\x12\x18\n" + + "\aversion\x18\x03 \x01(\tR\aversion\x12\x1a\n" + + "\bresource\x18\x04 \x01(\tR\bresource\x12\x1c\n" + + "\tnamespace\x18\x05 \x01(\tR\tnamespace\x12\x12\n" + + "\x04name\x18\x06 \x01(\tR\x04name\x12\x1a\n" + + "\bmanifest\x18\a \x01(\fR\bmanifest\x12#\n" + + "\rfield_manager\x18\b \x01(\tR\ffieldManager\"\xe0\x01\n" + "\rDeleteRequest\x12\x18\n" + "\acluster\x18\x01 \x01(\tR\acluster\x12\x14\n" + "\x05group\x18\x02 \x01(\tR\x05group\x12\x18\n" + @@ -3337,7 +3665,7 @@ const file_resource_v1_resource_proto_rawDesc = "" + "\fTYPE_DELETED\x10\x03\x12\x11\n" + "\rTYPE_BOOKMARK\x10\x04\x12\x0e\n" + "\n" + - "TYPE_ERROR\x10\x052\xee\a\n" + + "TYPE_ERROR\x10\x052\xda\b\n" + "\x0fResourceService\x12y\n" + "\tDiscovery\x12(.otterscale.resource.v1.DiscoveryRequest\x1a).otterscale.resource.v1.DiscoveryResponse\"\x17\x8a\xdf\xd5\x1d\x12\n" + "\x10resource-enabled\x12p\n" + @@ -3352,6 +3680,8 @@ const file_resource_v1_resource_proto_rawDesc = "" + "\x06Create\x12%.otterscale.resource.v1.CreateRequest\x1a .otterscale.resource.v1.Resource\"\x17\x8a\xdf\xd5\x1d\x12\n" + "\x10resource-enabled\x12h\n" + "\x05Apply\x12$.otterscale.resource.v1.ApplyRequest\x1a .otterscale.resource.v1.Resource\"\x17\x8a\xdf\xd5\x1d\x12\n" + + "\x10resource-enabled\x12j\n" + + "\x06Update\x12%.otterscale.resource.v1.UpdateRequest\x1a .otterscale.resource.v1.Resource\"\x17\x8a\xdf\xd5\x1d\x12\n" + "\x10resource-enabled\x12`\n" + "\x06Delete\x12%.otterscale.resource.v1.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x17\x8a\xdf\xd5\x1d\x12\n" + "\x10resource-enabled\x12l\n" + @@ -3359,7 +3689,7 @@ const file_resource_v1_resource_proto_rawDesc = "" + "\x10resource-enabled0\x01B2Z0github.com/otterscale/api/resource/v1;resourcev1b\beditionsp\xe8\a" var file_resource_v1_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_resource_v1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_resource_v1_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_resource_v1_resource_proto_goTypes = []any{ (WatchEvent_Type)(0), // 0: otterscale.resource.v1.WatchEvent.Type (*APIResource)(nil), // 1: otterscale.resource.v1.APIResource @@ -3375,16 +3705,17 @@ var file_resource_v1_resource_proto_goTypes = []any{ (*DescribeResponse)(nil), // 11: otterscale.resource.v1.DescribeResponse (*CreateRequest)(nil), // 12: otterscale.resource.v1.CreateRequest (*ApplyRequest)(nil), // 13: otterscale.resource.v1.ApplyRequest - (*DeleteRequest)(nil), // 14: otterscale.resource.v1.DeleteRequest - (*WatchRequest)(nil), // 15: otterscale.resource.v1.WatchRequest - (*WatchEvent)(nil), // 16: otterscale.resource.v1.WatchEvent - (*structpb.Struct)(nil), // 17: google.protobuf.Struct - (*emptypb.Empty)(nil), // 18: google.protobuf.Empty + (*UpdateRequest)(nil), // 14: otterscale.resource.v1.UpdateRequest + (*DeleteRequest)(nil), // 15: otterscale.resource.v1.DeleteRequest + (*WatchRequest)(nil), // 16: otterscale.resource.v1.WatchRequest + (*WatchEvent)(nil), // 17: otterscale.resource.v1.WatchEvent + (*structpb.Struct)(nil), // 18: google.protobuf.Struct + (*emptypb.Empty)(nil), // 19: google.protobuf.Empty } var file_resource_v1_resource_proto_depIdxs = []int32{ 1, // 0: otterscale.resource.v1.DiscoveryResponse.api_resources:type_name -> otterscale.resource.v1.APIResource - 17, // 1: otterscale.resource.v1.SchemaResponse.schema:type_name -> google.protobuf.Struct - 17, // 2: otterscale.resource.v1.Resource.object:type_name -> google.protobuf.Struct + 18, // 1: otterscale.resource.v1.SchemaResponse.schema:type_name -> google.protobuf.Struct + 18, // 2: otterscale.resource.v1.Resource.object:type_name -> google.protobuf.Struct 6, // 3: otterscale.resource.v1.ListResponse.items:type_name -> otterscale.resource.v1.Resource 6, // 4: otterscale.resource.v1.DescribeResponse.resource:type_name -> otterscale.resource.v1.Resource 6, // 5: otterscale.resource.v1.DescribeResponse.events:type_name -> otterscale.resource.v1.Resource @@ -3397,19 +3728,21 @@ var file_resource_v1_resource_proto_depIdxs = []int32{ 10, // 12: otterscale.resource.v1.ResourceService.Describe:input_type -> otterscale.resource.v1.DescribeRequest 12, // 13: otterscale.resource.v1.ResourceService.Create:input_type -> otterscale.resource.v1.CreateRequest 13, // 14: otterscale.resource.v1.ResourceService.Apply:input_type -> otterscale.resource.v1.ApplyRequest - 14, // 15: otterscale.resource.v1.ResourceService.Delete:input_type -> otterscale.resource.v1.DeleteRequest - 15, // 16: otterscale.resource.v1.ResourceService.Watch:input_type -> otterscale.resource.v1.WatchRequest - 3, // 17: otterscale.resource.v1.ResourceService.Discovery:output_type -> otterscale.resource.v1.DiscoveryResponse - 5, // 18: otterscale.resource.v1.ResourceService.Schema:output_type -> otterscale.resource.v1.SchemaResponse - 8, // 19: otterscale.resource.v1.ResourceService.List:output_type -> otterscale.resource.v1.ListResponse - 6, // 20: otterscale.resource.v1.ResourceService.Get:output_type -> otterscale.resource.v1.Resource - 11, // 21: otterscale.resource.v1.ResourceService.Describe:output_type -> otterscale.resource.v1.DescribeResponse - 6, // 22: otterscale.resource.v1.ResourceService.Create:output_type -> otterscale.resource.v1.Resource - 6, // 23: otterscale.resource.v1.ResourceService.Apply:output_type -> otterscale.resource.v1.Resource - 18, // 24: otterscale.resource.v1.ResourceService.Delete:output_type -> google.protobuf.Empty - 16, // 25: otterscale.resource.v1.ResourceService.Watch:output_type -> otterscale.resource.v1.WatchEvent - 17, // [17:26] is the sub-list for method output_type - 8, // [8:17] is the sub-list for method input_type + 14, // 15: otterscale.resource.v1.ResourceService.Update:input_type -> otterscale.resource.v1.UpdateRequest + 15, // 16: otterscale.resource.v1.ResourceService.Delete:input_type -> otterscale.resource.v1.DeleteRequest + 16, // 17: otterscale.resource.v1.ResourceService.Watch:input_type -> otterscale.resource.v1.WatchRequest + 3, // 18: otterscale.resource.v1.ResourceService.Discovery:output_type -> otterscale.resource.v1.DiscoveryResponse + 5, // 19: otterscale.resource.v1.ResourceService.Schema:output_type -> otterscale.resource.v1.SchemaResponse + 8, // 20: otterscale.resource.v1.ResourceService.List:output_type -> otterscale.resource.v1.ListResponse + 6, // 21: otterscale.resource.v1.ResourceService.Get:output_type -> otterscale.resource.v1.Resource + 11, // 22: otterscale.resource.v1.ResourceService.Describe:output_type -> otterscale.resource.v1.DescribeResponse + 6, // 23: otterscale.resource.v1.ResourceService.Create:output_type -> otterscale.resource.v1.Resource + 6, // 24: otterscale.resource.v1.ResourceService.Apply:output_type -> otterscale.resource.v1.Resource + 6, // 25: otterscale.resource.v1.ResourceService.Update:output_type -> otterscale.resource.v1.Resource + 19, // 26: otterscale.resource.v1.ResourceService.Delete:output_type -> google.protobuf.Empty + 17, // 27: otterscale.resource.v1.ResourceService.Watch:output_type -> otterscale.resource.v1.WatchEvent + 18, // [18:28] is the sub-list for method output_type + 8, // [8:18] is the sub-list for method input_type 8, // [8:8] is the sub-list for extension type_name 8, // [8:8] is the sub-list for extension extendee 0, // [0:8] is the sub-list for field type_name @@ -3426,7 +3759,7 @@ func file_resource_v1_resource_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_resource_v1_resource_proto_rawDesc), len(file_resource_v1_resource_proto_rawDesc)), NumEnums: 1, - NumMessages: 16, + NumMessages: 17, NumExtensions: 0, NumServices: 1, }, diff --git a/ts/src/resource/v1/resource_pb.d.ts b/ts/src/resource/v1/resource_pb.d.ts index c50c67e..cc09547 100644 --- a/ts/src/resource/v1/resource_pb.d.ts +++ b/ts/src/resource/v1/resource_pb.d.ts @@ -581,6 +581,76 @@ export declare type ApplyRequest = Message<"otterscale.resource.v1.ApplyRequest" */ export declare const ApplyRequestSchema: GenMessage; +/** + * UpdateRequest defines the parameters for a full-replacement update (PUT). + * + * @generated from message otterscale.resource.v1.UpdateRequest + */ +export declare type UpdateRequest = Message<"otterscale.resource.v1.UpdateRequest"> & { + /** + * The target Kubernetes cluster identifier. + * + * @generated from field: string cluster = 1; + */ + cluster: string; + + /** + * Kubernetes API Group (e.g., "apps" for Deployments, "" for core resources like Pods). + * + * @generated from field: string group = 2; + */ + group: string; + + /** + * Kubernetes API Version (e.g., "v1"). + * + * @generated from field: string version = 3; + */ + version: string; + + /** + * Kubernetes API Resource name in plural (e.g., "pods", "deployments"). + * + * @generated from field: string resource = 4; + */ + resource: string; + + /** + * The namespace of the resource. + * + * @generated from field: string namespace = 5; + */ + namespace: string; + + /** + * The name of the resource. + * + * @generated from field: string name = 6; + */ + name: string; + + /** + * The full YAML manifest, in JSON form, that will replace the stored object. + * Server-required fields such as metadata.resourceVersion must be included. + * + * @generated from field: bytes manifest = 7; + */ + manifest: Uint8Array; + + /** + * Identifies the entity submitting the update (e.g., "otterscale-web-ui"). + * + * @generated from field: string field_manager = 8; + */ + fieldManager: string; +}; + +/** + * Describes the message otterscale.resource.v1.UpdateRequest. + * Use `create(UpdateRequestSchema)` to create a new message. + */ +export declare const UpdateRequestSchema: GenMessage; + /** * DeleteRequest defines the parameters to remove an object. * @@ -884,6 +954,19 @@ export declare const ResourceService: GenService<{ input: typeof ApplyRequestSchema; output: typeof ResourceSchema; }, + /** + * Update performs a full replacement (PUT) of an existing resource using + * the provided manifest. The caller is responsible for supplying any + * server-required fields (such as metadata.resourceVersion) inside the + * manifest. + * + * @generated from rpc otterscale.resource.v1.ResourceService.Update + */ + update: { + methodKind: "unary"; + input: typeof UpdateRequestSchema; + output: typeof ResourceSchema; + }, /** * Delete removes a resource from the cluster by its name. * diff --git a/ts/src/resource/v1/resource_pb.js b/ts/src/resource/v1/resource_pb.js index c0afb29..85dac52 100644 --- a/ts/src/resource/v1/resource_pb.js +++ b/ts/src/resource/v1/resource_pb.js @@ -10,7 +10,7 @@ import { file_google_protobuf_empty, file_google_protobuf_struct } from "@bufbui * Describes the file resource/v1/resource.proto. */ export const file_resource_v1_resource = /*@__PURE__*/ - fileDesc("ChpyZXNvdXJjZS92MS9yZXNvdXJjZS5wcm90bxIWb3R0ZXJzY2FsZS5yZXNvdXJjZS52MSKFAQoLQVBJUmVzb3VyY2USDQoFZ3JvdXAYASABKAkSDwoHdmVyc2lvbhgCIAEoCRIQCghyZXNvdXJjZRgDIAEoCRIMCgRraW5kGAQgASgJEhIKCm5hbWVzcGFjZWQYBSABKAgSDQoFdmVyYnMYBiADKAkSEwoLc2hvcnRfbmFtZXMYByADKAkiIwoQRGlzY292ZXJ5UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJIk8KEURpc2NvdmVyeVJlc3BvbnNlEjoKDWFwaV9yZXNvdXJjZXMYASADKAsyIy5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkFQSVJlc291cmNlIk4KDVNjaGVtYVJlcXVlc3QSDwoHY2x1c3RlchgBIAEoCRINCgVncm91cBgCIAEoCRIPCgd2ZXJzaW9uGAMgASgJEgwKBGtpbmQYBCABKAkiOQoOU2NoZW1hUmVzcG9uc2USJwoGc2NoZW1hGAEgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCIzCghSZXNvdXJjZRInCgZvYmplY3QYASABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0IrQBCgtMaXN0UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEhYKDmxhYmVsX3NlbGVjdG9yGAYgASgJEhYKDmZpZWxkX3NlbGVjdG9yGAcgASgJEg0KBWxpbWl0GAggASgDEhAKCGNvbnRpbnVlGAkgASgJIokBCgxMaXN0UmVzcG9uc2USGAoQcmVzb3VyY2VfdmVyc2lvbhgBIAEoCRIQCghjb250aW51ZRgCIAEoCRIcChRyZW1haW5pbmdfaXRlbV9jb3VudBgDIAEoAxIvCgVpdGVtcxgEIAMoCzIgLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UicAoKR2V0UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEgwKBG5hbWUYBiABKAkidQoPRGVzY3JpYmVSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCSJ4ChBEZXNjcmliZVJlc3BvbnNlEjIKCHJlc291cmNlGAEgASgLMiAub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5SZXNvdXJjZRIwCgZldmVudHMYAiADKAsyIC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlJlc291cmNlIncKDUNyZWF0ZVJlcXVlc3QSDwoHY2x1c3RlchgBIAEoCRINCgVncm91cBgCIAEoCRIPCgd2ZXJzaW9uGAMgASgJEhAKCHJlc291cmNlGAQgASgJEhEKCW5hbWVzcGFjZRgFIAEoCRIQCghtYW5pZmVzdBgGIAEoDCKqAQoMQXBwbHlSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCRIQCghtYW5pZmVzdBgHIAEoDBINCgVmb3JjZRgIIAEoCBIVCg1maWVsZF9tYW5hZ2VyGAkgASgJIpgBCg1EZWxldGVSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCRIjChRncmFjZV9wZXJpb2Rfc2Vjb25kcxgHIAEoA0IFqgECCAEirgEKDFdhdGNoUmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEhYKDmxhYmVsX3NlbGVjdG9yGAYgASgJEhYKDmZpZWxkX3NlbGVjdG9yGAcgASgJEhgKEHJlc291cmNlX3ZlcnNpb24YCCABKAkihwIKCldhdGNoRXZlbnQSNQoEdHlwZRgBIAEoDjInLm90dGVyc2NhbGUucmVzb3VyY2UudjEuV2F0Y2hFdmVudC5UeXBlEjIKCHJlc291cmNlGAIgASgLMiAub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5SZXNvdXJjZRIYChByZXNvdXJjZV92ZXJzaW9uGAMgASgJInQKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEg4KClRZUEVfQURERUQQARIRCg1UWVBFX01PRElGSUVEEAISEAoMVFlQRV9ERUxFVEVEEAMSEQoNVFlQRV9CT09LTUFSSxAEEg4KClRZUEVfRVJST1IQBTLuBwoPUmVzb3VyY2VTZXJ2aWNlEnkKCURpc2NvdmVyeRIoLm90dGVyc2NhbGUucmVzb3VyY2UudjEuRGlzY292ZXJ5UmVxdWVzdBopLm90dGVyc2NhbGUucmVzb3VyY2UudjEuRGlzY292ZXJ5UmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEnAKBlNjaGVtYRIlLm90dGVyc2NhbGUucmVzb3VyY2UudjEuU2NoZW1hUmVxdWVzdBomLm90dGVyc2NhbGUucmVzb3VyY2UudjEuU2NoZW1hUmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmoKBExpc3QSIy5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkxpc3RSZXF1ZXN0GiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5MaXN0UmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmQKA0dldBIiLm90dGVyc2NhbGUucmVzb3VyY2UudjEuR2V0UmVxdWVzdBogLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEnYKCERlc2NyaWJlEicub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5EZXNjcmliZVJlcXVlc3QaKC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkRlc2NyaWJlUmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmoKBkNyZWF0ZRIlLm90dGVyc2NhbGUucmVzb3VyY2UudjEuQ3JlYXRlUmVxdWVzdBogLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmgKBUFwcGx5EiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5BcHBseVJlcXVlc3QaIC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlJlc291cmNlIheK39UdEgoQcmVzb3VyY2UtZW5hYmxlZBJgCgZEZWxldGUSJS5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkRlbGV0ZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmwKBVdhdGNoEiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5XYXRjaFJlcXVlc3QaIi5vdHRlcnNjYWxlLnJlc291cmNlLnYxLldhdGNoRXZlbnQiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkMAFCMlowZ2l0aHViLmNvbS9vdHRlcnNjYWxlL2FwaS9yZXNvdXJjZS92MTtyZXNvdXJjZXYxYghlZGl0aW9uc3DoBw", [file_feature, file_google_protobuf_empty, file_google_protobuf_struct]); + fileDesc("ChpyZXNvdXJjZS92MS9yZXNvdXJjZS5wcm90bxIWb3R0ZXJzY2FsZS5yZXNvdXJjZS52MSKFAQoLQVBJUmVzb3VyY2USDQoFZ3JvdXAYASABKAkSDwoHdmVyc2lvbhgCIAEoCRIQCghyZXNvdXJjZRgDIAEoCRIMCgRraW5kGAQgASgJEhIKCm5hbWVzcGFjZWQYBSABKAgSDQoFdmVyYnMYBiADKAkSEwoLc2hvcnRfbmFtZXMYByADKAkiIwoQRGlzY292ZXJ5UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJIk8KEURpc2NvdmVyeVJlc3BvbnNlEjoKDWFwaV9yZXNvdXJjZXMYASADKAsyIy5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkFQSVJlc291cmNlIk4KDVNjaGVtYVJlcXVlc3QSDwoHY2x1c3RlchgBIAEoCRINCgVncm91cBgCIAEoCRIPCgd2ZXJzaW9uGAMgASgJEgwKBGtpbmQYBCABKAkiOQoOU2NoZW1hUmVzcG9uc2USJwoGc2NoZW1hGAEgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdCIzCghSZXNvdXJjZRInCgZvYmplY3QYASABKAsyFy5nb29nbGUucHJvdG9idWYuU3RydWN0IrQBCgtMaXN0UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEhYKDmxhYmVsX3NlbGVjdG9yGAYgASgJEhYKDmZpZWxkX3NlbGVjdG9yGAcgASgJEg0KBWxpbWl0GAggASgDEhAKCGNvbnRpbnVlGAkgASgJIokBCgxMaXN0UmVzcG9uc2USGAoQcmVzb3VyY2VfdmVyc2lvbhgBIAEoCRIQCghjb250aW51ZRgCIAEoCRIcChRyZW1haW5pbmdfaXRlbV9jb3VudBgDIAEoAxIvCgVpdGVtcxgEIAMoCzIgLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UicAoKR2V0UmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEgwKBG5hbWUYBiABKAkidQoPRGVzY3JpYmVSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCSJ4ChBEZXNjcmliZVJlc3BvbnNlEjIKCHJlc291cmNlGAEgASgLMiAub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5SZXNvdXJjZRIwCgZldmVudHMYAiADKAsyIC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlJlc291cmNlIncKDUNyZWF0ZVJlcXVlc3QSDwoHY2x1c3RlchgBIAEoCRINCgVncm91cBgCIAEoCRIPCgd2ZXJzaW9uGAMgASgJEhAKCHJlc291cmNlGAQgASgJEhEKCW5hbWVzcGFjZRgFIAEoCRIQCghtYW5pZmVzdBgGIAEoDCKqAQoMQXBwbHlSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCRIQCghtYW5pZmVzdBgHIAEoDBINCgVmb3JjZRgIIAEoCBIVCg1maWVsZF9tYW5hZ2VyGAkgASgJIpwBCg1VcGRhdGVSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCRIQCghtYW5pZmVzdBgHIAEoDBIVCg1maWVsZF9tYW5hZ2VyGAggASgJIpgBCg1EZWxldGVSZXF1ZXN0Eg8KB2NsdXN0ZXIYASABKAkSDQoFZ3JvdXAYAiABKAkSDwoHdmVyc2lvbhgDIAEoCRIQCghyZXNvdXJjZRgEIAEoCRIRCgluYW1lc3BhY2UYBSABKAkSDAoEbmFtZRgGIAEoCRIjChRncmFjZV9wZXJpb2Rfc2Vjb25kcxgHIAEoA0IFqgECCAEirgEKDFdhdGNoUmVxdWVzdBIPCgdjbHVzdGVyGAEgASgJEg0KBWdyb3VwGAIgASgJEg8KB3ZlcnNpb24YAyABKAkSEAoIcmVzb3VyY2UYBCABKAkSEQoJbmFtZXNwYWNlGAUgASgJEhYKDmxhYmVsX3NlbGVjdG9yGAYgASgJEhYKDmZpZWxkX3NlbGVjdG9yGAcgASgJEhgKEHJlc291cmNlX3ZlcnNpb24YCCABKAkihwIKCldhdGNoRXZlbnQSNQoEdHlwZRgBIAEoDjInLm90dGVyc2NhbGUucmVzb3VyY2UudjEuV2F0Y2hFdmVudC5UeXBlEjIKCHJlc291cmNlGAIgASgLMiAub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5SZXNvdXJjZRIYChByZXNvdXJjZV92ZXJzaW9uGAMgASgJInQKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEg4KClRZUEVfQURERUQQARIRCg1UWVBFX01PRElGSUVEEAISEAoMVFlQRV9ERUxFVEVEEAMSEQoNVFlQRV9CT09LTUFSSxAEEg4KClRZUEVfRVJST1IQBTLaCAoPUmVzb3VyY2VTZXJ2aWNlEnkKCURpc2NvdmVyeRIoLm90dGVyc2NhbGUucmVzb3VyY2UudjEuRGlzY292ZXJ5UmVxdWVzdBopLm90dGVyc2NhbGUucmVzb3VyY2UudjEuRGlzY292ZXJ5UmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEnAKBlNjaGVtYRIlLm90dGVyc2NhbGUucmVzb3VyY2UudjEuU2NoZW1hUmVxdWVzdBomLm90dGVyc2NhbGUucmVzb3VyY2UudjEuU2NoZW1hUmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmoKBExpc3QSIy5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkxpc3RSZXF1ZXN0GiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5MaXN0UmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmQKA0dldBIiLm90dGVyc2NhbGUucmVzb3VyY2UudjEuR2V0UmVxdWVzdBogLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEnYKCERlc2NyaWJlEicub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5EZXNjcmliZVJlcXVlc3QaKC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkRlc2NyaWJlUmVzcG9uc2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmoKBkNyZWF0ZRIlLm90dGVyc2NhbGUucmVzb3VyY2UudjEuQ3JlYXRlUmVxdWVzdBogLm90dGVyc2NhbGUucmVzb3VyY2UudjEuUmVzb3VyY2UiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmgKBUFwcGx5EiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5BcHBseVJlcXVlc3QaIC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlJlc291cmNlIheK39UdEgoQcmVzb3VyY2UtZW5hYmxlZBJqCgZVcGRhdGUSJS5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlVwZGF0ZVJlcXVlc3QaIC5vdHRlcnNjYWxlLnJlc291cmNlLnYxLlJlc291cmNlIheK39UdEgoQcmVzb3VyY2UtZW5hYmxlZBJgCgZEZWxldGUSJS5vdHRlcnNjYWxlLnJlc291cmNlLnYxLkRlbGV0ZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkEmwKBVdhdGNoEiQub3R0ZXJzY2FsZS5yZXNvdXJjZS52MS5XYXRjaFJlcXVlc3QaIi5vdHRlcnNjYWxlLnJlc291cmNlLnYxLldhdGNoRXZlbnQiF4rf1R0SChByZXNvdXJjZS1lbmFibGVkMAFCMlowZ2l0aHViLmNvbS9vdHRlcnNjYWxlL2FwaS9yZXNvdXJjZS92MTtyZXNvdXJjZXYxYghlZGl0aW9uc3DoBw", [file_feature, file_google_protobuf_empty, file_google_protobuf_struct]); /** * Describes the message otterscale.resource.v1.APIResource. @@ -103,32 +103,39 @@ export const CreateRequestSchema = /*@__PURE__*/ export const ApplyRequestSchema = /*@__PURE__*/ messageDesc(file_resource_v1_resource, 12); +/** + * Describes the message otterscale.resource.v1.UpdateRequest. + * Use `create(UpdateRequestSchema)` to create a new message. + */ +export const UpdateRequestSchema = /*@__PURE__*/ + messageDesc(file_resource_v1_resource, 13); + /** * Describes the message otterscale.resource.v1.DeleteRequest. * Use `create(DeleteRequestSchema)` to create a new message. */ export const DeleteRequestSchema = /*@__PURE__*/ - messageDesc(file_resource_v1_resource, 13); + messageDesc(file_resource_v1_resource, 14); /** * Describes the message otterscale.resource.v1.WatchRequest. * Use `create(WatchRequestSchema)` to create a new message. */ export const WatchRequestSchema = /*@__PURE__*/ - messageDesc(file_resource_v1_resource, 14); + messageDesc(file_resource_v1_resource, 15); /** * Describes the message otterscale.resource.v1.WatchEvent. * Use `create(WatchEventSchema)` to create a new message. */ export const WatchEventSchema = /*@__PURE__*/ - messageDesc(file_resource_v1_resource, 15); + messageDesc(file_resource_v1_resource, 16); /** * Describes the enum otterscale.resource.v1.WatchEvent.Type. */ export const WatchEvent_TypeSchema = /*@__PURE__*/ - enumDesc(file_resource_v1_resource, 15, 0); + enumDesc(file_resource_v1_resource, 16, 0); /** * Type defines the possible types of events from Kubernetes watch. From d5e9b7b2430ef0eeca0a25ffdeb22afb3dff2aed Mon Sep 17 00:00:00 2001 From: george-wu20250203 Date: Mon, 18 May 2026 21:27:19 +0800 Subject: [PATCH 2/3] refactor: update comments in CreateRequest, ApplyRequest, and UpdateRequest messages for clarity --- proto/resource/v1/resource.proto | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/proto/resource/v1/resource.proto b/proto/resource/v1/resource.proto index 9b9c503..419d2b6 100644 --- a/proto/resource/v1/resource.proto +++ b/proto/resource/v1/resource.proto @@ -272,7 +272,7 @@ message CreateRequest { // The namespace of the resource. string namespace = 5; - // The full manifest of the object to be created in YAML format. + // The manifest (YAML or JSON) describing the object to be created. bytes manifest = 6; } @@ -300,7 +300,8 @@ message ApplyRequest { // The name of the resource. string name = 6; - // A partial or YAML manifest in JSON format to be merged by the API server. + // A partial or complete manifest (YAML or JSON) to be merged by the + // API server via Server-Side Apply. bytes manifest = 7; // If true, conflicts are resolved in favour of the caller's field manager. @@ -334,7 +335,7 @@ message UpdateRequest { // The name of the resource. string name = 6; - // The full YAML manifest, in JSON form, that will replace the stored object. + // The complete manifest (YAML or JSON) that will replace the stored object. // Server-required fields such as metadata.resourceVersion must be included. bytes manifest = 7; From 35b7c08cd3b17091a6ae22874b7e1060e1d65fc3 Mon Sep 17 00:00:00 2001 From: ZhangEnYao Date: Mon, 18 May 2026 21:50:42 +0800 Subject: [PATCH 3/3] refactor: improve descriptions in CreateRequest, ApplyRequest, and UpdateRequest for clarity --- openapi/openapi.yaml | 8 +++++--- resource/v1/resource.pb.go | 7 ++++--- ts/src/resource/v1/resource_pb.d.ts | 7 ++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 58d5014..cf58877 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -1848,7 +1848,9 @@ components: type: string title: manifest format: byte - description: A partial or YAML manifest in JSON format to be merged by the API server. + description: |- + A partial or complete manifest (YAML or JSON) to be merged by the + API server via Server-Side Apply. force: type: boolean title: force @@ -1887,7 +1889,7 @@ components: type: string title: manifest format: byte - description: The full manifest of the object to be created in YAML format. + description: The manifest (YAML or JSON) describing the object to be created. title: CreateRequest additionalProperties: false description: CreateRequest defines the parameters for creating a new object. @@ -2179,7 +2181,7 @@ components: title: manifest format: byte description: |- - The full YAML manifest, in JSON form, that will replace the stored object. + The complete manifest (YAML or JSON) that will replace the stored object. Server-required fields such as metadata.resourceVersion must be included. fieldManager: type: string diff --git a/resource/v1/resource.pb.go b/resource/v1/resource.pb.go index 4bfd25d..0b4a14e 100644 --- a/resource/v1/resource.pb.go +++ b/resource/v1/resource.pb.go @@ -2104,7 +2104,7 @@ type CreateRequest_builder struct { Resource *string // The namespace of the resource. Namespace *string - // The full manifest of the object to be created in YAML format. + // The manifest (YAML or JSON) describing the object to be created. Manifest []byte } @@ -2437,7 +2437,8 @@ type ApplyRequest_builder struct { Namespace *string // The name of the resource. Name *string - // A partial or YAML manifest in JSON format to be merged by the API server. + // A partial or complete manifest (YAML or JSON) to be merged by the + // API server via Server-Side Apply. Manifest []byte // If true, conflicts are resolved in favour of the caller's field manager. Force *bool @@ -2761,7 +2762,7 @@ type UpdateRequest_builder struct { Namespace *string // The name of the resource. Name *string - // The full YAML manifest, in JSON form, that will replace the stored object. + // The complete manifest (YAML or JSON) that will replace the stored object. // Server-required fields such as metadata.resourceVersion must be included. Manifest []byte // Identifies the entity submitting the update (e.g., "otterscale-web-ui"). diff --git a/ts/src/resource/v1/resource_pb.d.ts b/ts/src/resource/v1/resource_pb.d.ts index cc09547..5a38c77 100644 --- a/ts/src/resource/v1/resource_pb.d.ts +++ b/ts/src/resource/v1/resource_pb.d.ts @@ -492,7 +492,7 @@ export declare type CreateRequest = Message<"otterscale.resource.v1.CreateReques namespace: string; /** - * The full manifest of the object to be created in YAML format. + * The manifest (YAML or JSON) describing the object to be created. * * @generated from field: bytes manifest = 6; */ @@ -554,7 +554,8 @@ export declare type ApplyRequest = Message<"otterscale.resource.v1.ApplyRequest" name: string; /** - * A partial or YAML manifest in JSON format to be merged by the API server. + * A partial or complete manifest (YAML or JSON) to be merged by the + * API server via Server-Side Apply. * * @generated from field: bytes manifest = 7; */ @@ -630,7 +631,7 @@ export declare type UpdateRequest = Message<"otterscale.resource.v1.UpdateReques name: string; /** - * The full YAML manifest, in JSON form, that will replace the stored object. + * The complete manifest (YAML or JSON) that will replace the stored object. * Server-required fields such as metadata.resourceVersion must be included. * * @generated from field: bytes manifest = 7;