feat: implement the API for reading resources and their dependency graph

Then another Tool can represent it in a nice way.
This will be a good education tool for the start, and then we can add
monitoring there too.

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
This commit is contained in:
Artem Chernyshev 2025-07-17 19:21:48 +03:00
parent e945cc7b8b
commit b0f7634310
No known key found for this signature in database
GPG Key ID: E084A2DF1143C14D
33 changed files with 2568 additions and 93 deletions

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-05-30T17:31:23Z by kres 9f64b0d.
# Generated on 2025-07-21T17:11:34Z by kres b869533-dirty.
*
!frontend/src
@ -16,6 +16,7 @@
!frontend/*.ts
!frontend/*.html
!frontend/*.ico
!frontend/public
!frontend/eslint.config.js
!internal/frontend/frontend.go
!client/go.mod

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: ${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
concurrency:
group: helm-${{ github.head_ref || github.run_id }}

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
"on":
schedule:

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-14T11:13:09Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
"on":
workflow_run:

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
"on":
schedule:

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
version: "2"

View File

@ -2,7 +2,7 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
ARG JS_TOOLCHAIN
ARG TOOLCHAIN

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
# common variables

View File

@ -1,6 +1,6 @@
# THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT.
#
# Generated on 2025-07-11T15:30:30Z by kres c691b83.
# Generated on 2025-07-18T15:48:02Z by kres b869533.
version: "2"

View File

@ -487,6 +487,9 @@ func request_ManagementService_CreateJoinToken_0(ctx context.Context, marshaler
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.CreateJoinToken(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}

View File

@ -14,6 +14,7 @@ import (
v1alpha1 "github.com/cosi-project/runtime/api/v1alpha1"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/known/emptypb"
_ "github.com/siderolabs/omni/client/api/common"
)
@ -80,6 +81,55 @@ func (EventType) EnumDescriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{0}
}
type DependencyGraphResponse_Node_Type int32
const (
DependencyGraphResponse_Node_UNKNOWN DependencyGraphResponse_Node_Type = 0
DependencyGraphResponse_Node_CONTROLLER DependencyGraphResponse_Node_Type = 1
DependencyGraphResponse_Node_RESOURCE DependencyGraphResponse_Node_Type = 2
)
// Enum value maps for DependencyGraphResponse_Node_Type.
var (
DependencyGraphResponse_Node_Type_name = map[int32]string{
0: "UNKNOWN",
1: "CONTROLLER",
2: "RESOURCE",
}
DependencyGraphResponse_Node_Type_value = map[string]int32{
"UNKNOWN": 0,
"CONTROLLER": 1,
"RESOURCE": 2,
}
)
func (x DependencyGraphResponse_Node_Type) Enum() *DependencyGraphResponse_Node_Type {
p := new(DependencyGraphResponse_Node_Type)
*p = x
return p
}
func (x DependencyGraphResponse_Node_Type) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (DependencyGraphResponse_Node_Type) Descriptor() protoreflect.EnumDescriptor {
return file_omni_resources_resources_proto_enumTypes[1].Descriptor()
}
func (DependencyGraphResponse_Node_Type) Type() protoreflect.EnumType {
return &file_omni_resources_resources_proto_enumTypes[1]
}
func (x DependencyGraphResponse_Node_Type) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use DependencyGraphResponse_Node_Type.Descriptor instead.
func (DependencyGraphResponse_Node_Type) EnumDescriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{17, 0, 0}
}
type Resource struct {
state protoimpl.MessageState `protogen:"open.v1"`
Metadata *v1alpha1.Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
@ -884,11 +934,339 @@ func (*DeleteResponse) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{13}
}
type ControllersRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ControllersRequest) Reset() {
*x = ControllersRequest{}
mi := &file_omni_resources_resources_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ControllersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ControllersRequest) ProtoMessage() {}
func (x *ControllersRequest) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[14]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ControllersRequest.ProtoReflect.Descriptor instead.
func (*ControllersRequest) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{14}
}
type ControllersResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Controllers []string `protobuf:"bytes,1,rep,name=controllers,proto3" json:"controllers,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ControllersResponse) Reset() {
*x = ControllersResponse{}
mi := &file_omni_resources_resources_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ControllersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ControllersResponse) ProtoMessage() {}
func (x *ControllersResponse) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[15]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ControllersResponse.ProtoReflect.Descriptor instead.
func (*ControllersResponse) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{15}
}
func (x *ControllersResponse) GetControllers() []string {
if x != nil {
return x.Controllers
}
return nil
}
type DependencyGraphRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
Controllers []string `protobuf:"bytes,1,rep,name=controllers,proto3" json:"controllers,omitempty"`
ShowDestroyReady bool `protobuf:"varint,2,opt,name=show_destroy_ready,json=showDestroyReady,proto3" json:"show_destroy_ready,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DependencyGraphRequest) Reset() {
*x = DependencyGraphRequest{}
mi := &file_omni_resources_resources_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DependencyGraphRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DependencyGraphRequest) ProtoMessage() {}
func (x *DependencyGraphRequest) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[16]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DependencyGraphRequest.ProtoReflect.Descriptor instead.
func (*DependencyGraphRequest) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{16}
}
func (x *DependencyGraphRequest) GetControllers() []string {
if x != nil {
return x.Controllers
}
return nil
}
func (x *DependencyGraphRequest) GetShowDestroyReady() bool {
if x != nil {
return x.ShowDestroyReady
}
return false
}
type DependencyGraphResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Nodes []*DependencyGraphResponse_Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
Edges []*DependencyGraphResponse_Edge `protobuf:"bytes,2,rep,name=edges,proto3" json:"edges,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DependencyGraphResponse) Reset() {
*x = DependencyGraphResponse{}
mi := &file_omni_resources_resources_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DependencyGraphResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DependencyGraphResponse) ProtoMessage() {}
func (x *DependencyGraphResponse) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[17]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DependencyGraphResponse.ProtoReflect.Descriptor instead.
func (*DependencyGraphResponse) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{17}
}
func (x *DependencyGraphResponse) GetNodes() []*DependencyGraphResponse_Node {
if x != nil {
return x.Nodes
}
return nil
}
func (x *DependencyGraphResponse) GetEdges() []*DependencyGraphResponse_Edge {
if x != nil {
return x.Edges
}
return nil
}
type DependencyGraphResponse_Node struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`
Type DependencyGraphResponse_Node_Type `protobuf:"varint,3,opt,name=type,proto3,enum=omni.resources.DependencyGraphResponse_Node_Type" json:"type,omitempty"`
Labels []string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty"`
Fields []string `protobuf:"bytes,5,rep,name=fields,proto3" json:"fields,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DependencyGraphResponse_Node) Reset() {
*x = DependencyGraphResponse_Node{}
mi := &file_omni_resources_resources_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DependencyGraphResponse_Node) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DependencyGraphResponse_Node) ProtoMessage() {}
func (x *DependencyGraphResponse_Node) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[18]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DependencyGraphResponse_Node.ProtoReflect.Descriptor instead.
func (*DependencyGraphResponse_Node) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{17, 0}
}
func (x *DependencyGraphResponse_Node) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *DependencyGraphResponse_Node) GetLabel() string {
if x != nil {
return x.Label
}
return ""
}
func (x *DependencyGraphResponse_Node) GetType() DependencyGraphResponse_Node_Type {
if x != nil {
return x.Type
}
return DependencyGraphResponse_Node_UNKNOWN
}
func (x *DependencyGraphResponse_Node) GetLabels() []string {
if x != nil {
return x.Labels
}
return nil
}
func (x *DependencyGraphResponse_Node) GetFields() []string {
if x != nil {
return x.Fields
}
return nil
}
type DependencyGraphResponse_Edge struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"`
Target string `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"`
EdgeType int32 `protobuf:"varint,4,opt,name=edge_type,json=edgeType,proto3" json:"edge_type,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *DependencyGraphResponse_Edge) Reset() {
*x = DependencyGraphResponse_Edge{}
mi := &file_omni_resources_resources_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *DependencyGraphResponse_Edge) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*DependencyGraphResponse_Edge) ProtoMessage() {}
func (x *DependencyGraphResponse_Edge) ProtoReflect() protoreflect.Message {
mi := &file_omni_resources_resources_proto_msgTypes[19]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use DependencyGraphResponse_Edge.ProtoReflect.Descriptor instead.
func (*DependencyGraphResponse_Edge) Descriptor() ([]byte, []int) {
return file_omni_resources_resources_proto_rawDescGZIP(), []int{17, 1}
}
func (x *DependencyGraphResponse_Edge) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *DependencyGraphResponse_Edge) GetSource() string {
if x != nil {
return x.Source
}
return ""
}
func (x *DependencyGraphResponse_Edge) GetTarget() string {
if x != nil {
return x.Target
}
return ""
}
func (x *DependencyGraphResponse_Edge) GetEdgeType() int32 {
if x != nil {
return x.EdgeType
}
return 0
}
var File_omni_resources_resources_proto protoreflect.FileDescriptor
const file_omni_resources_resources_proto_rawDesc = "" +
"\n" +
"\x1eomni/resources/resources.proto\x12\x0eomni.resources\x1a\x11common/omni.proto\x1a\x17v1alpha1/resource.proto\"S\n" +
"\x1eomni/resources/resources.proto\x12\x0eomni.resources\x1a\x1bgoogle/protobuf/empty.proto\x1a\x11common/omni.proto\x1a\x17v1alpha1/resource.proto\"S\n" +
"\bResource\x123\n" +
"\bmetadata\x18\x01 \x01(\v2\x17.cosi.resource.MetadataR\bmetadata\x12\x12\n" +
"\x04spec\x18\x02 \x01(\tR\x04spec\"N\n" +
@ -944,13 +1322,38 @@ const file_omni_resources_resources_proto_rawDesc = "" +
"\tnamespace\x18\x01 \x01(\tR\tnamespace\x12\x12\n" +
"\x04type\x18\x02 \x01(\tR\x04type\x12\x0e\n" +
"\x02id\x18\x03 \x01(\tR\x02id\"\x10\n" +
"\x0eDeleteResponse*S\n" +
"\x0eDeleteResponse\"\x14\n" +
"\x12ControllersRequest\"7\n" +
"\x13ControllersResponse\x12 \n" +
"\vcontrollers\x18\x01 \x03(\tR\vcontrollers\"h\n" +
"\x16DependencyGraphRequest\x12 \n" +
"\vcontrollers\x18\x01 \x03(\tR\vcontrollers\x12,\n" +
"\x12show_destroy_ready\x18\x02 \x01(\bR\x10showDestroyReady\"\xdf\x03\n" +
"\x17DependencyGraphResponse\x12B\n" +
"\x05nodes\x18\x01 \x03(\v2,.omni.resources.DependencyGraphResponse.NodeR\x05nodes\x12B\n" +
"\x05edges\x18\x02 \x03(\v2,.omni.resources.DependencyGraphResponse.EdgeR\x05edges\x1a\xd6\x01\n" +
"\x04Node\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" +
"\x05label\x18\x02 \x01(\tR\x05label\x12E\n" +
"\x04type\x18\x03 \x01(\x0e21.omni.resources.DependencyGraphResponse.Node.TypeR\x04type\x12\x16\n" +
"\x06labels\x18\x04 \x03(\tR\x06labels\x12\x16\n" +
"\x06fields\x18\x05 \x03(\tR\x06fields\"1\n" +
"\x04Type\x12\v\n" +
"\aUNKNOWN\x10\x00\x12\x0e\n" +
"\n" +
"CONTROLLER\x10\x01\x12\f\n" +
"\bRESOURCE\x10\x02\x1ac\n" +
"\x04Edge\x12\x0e\n" +
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" +
"\x06source\x18\x02 \x01(\tR\x06source\x12\x16\n" +
"\x06target\x18\x03 \x01(\tR\x06target\x12\x1b\n" +
"\tedge_type\x18\x04 \x01(\x05R\bedgeType*S\n" +
"\tEventType\x12\v\n" +
"\aUNKNOWN\x10\x00\x12\v\n" +
"\aCREATED\x10\x01\x12\v\n" +
"\aUPDATED\x10\x02\x12\r\n" +
"\tDESTROYED\x10\x03\x12\x10\n" +
"\fBOOTSTRAPPED\x10\x042\x82\x04\n" +
"\fBOOTSTRAPPED\x10\x042\xbe\x05\n" +
"\x0fResourceService\x12>\n" +
"\x03Get\x12\x1a.omni.resources.GetRequest\x1a\x1b.omni.resources.GetResponse\x12A\n" +
"\x04List\x12\x1b.omni.resources.ListRequest\x1a\x1c.omni.resources.ListResponse\x12G\n" +
@ -958,7 +1361,9 @@ const file_omni_resources_resources_proto_rawDesc = "" +
"\x06Update\x12\x1d.omni.resources.UpdateRequest\x1a\x1e.omni.resources.UpdateResponse\x12G\n" +
"\x06Delete\x12\x1d.omni.resources.DeleteRequest\x1a\x1e.omni.resources.DeleteResponse\x12I\n" +
"\bTeardown\x12\x1d.omni.resources.DeleteRequest\x1a\x1e.omni.resources.DeleteResponse\x12F\n" +
"\x05Watch\x12\x1c.omni.resources.WatchRequest\x1a\x1d.omni.resources.WatchResponse0\x01B6Z4github.com/siderolabs/omni/client/api/omni/resourcesb\x06proto3"
"\x05Watch\x12\x1c.omni.resources.WatchRequest\x1a\x1d.omni.resources.WatchResponse0\x01\x12V\n" +
"\vControllers\x12\".omni.resources.ControllersRequest\x1a#.omni.resources.ControllersResponse\x12b\n" +
"\x0fDependencyGraph\x12&.omni.resources.DependencyGraphRequest\x1a'.omni.resources.DependencyGraphResponseB6Z4github.com/siderolabs/omni/client/api/omni/resourcesb\x06proto3"
var (
file_omni_resources_resources_proto_rawDescOnce sync.Once
@ -972,51 +1377,65 @@ func file_omni_resources_resources_proto_rawDescGZIP() []byte {
return file_omni_resources_resources_proto_rawDescData
}
var file_omni_resources_resources_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_omni_resources_resources_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_omni_resources_resources_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_omni_resources_resources_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_omni_resources_resources_proto_goTypes = []any{
(EventType)(0), // 0: omni.resources.EventType
(*Resource)(nil), // 1: omni.resources.Resource
(*GetRequest)(nil), // 2: omni.resources.GetRequest
(*GetResponse)(nil), // 3: omni.resources.GetResponse
(*ListRequest)(nil), // 4: omni.resources.ListRequest
(*ListResponse)(nil), // 5: omni.resources.ListResponse
(*Event)(nil), // 6: omni.resources.Event
(*WatchRequest)(nil), // 7: omni.resources.WatchRequest
(*WatchResponse)(nil), // 8: omni.resources.WatchResponse
(*CreateRequest)(nil), // 9: omni.resources.CreateRequest
(*CreateResponse)(nil), // 10: omni.resources.CreateResponse
(*UpdateRequest)(nil), // 11: omni.resources.UpdateRequest
(*UpdateResponse)(nil), // 12: omni.resources.UpdateResponse
(*DeleteRequest)(nil), // 13: omni.resources.DeleteRequest
(*DeleteResponse)(nil), // 14: omni.resources.DeleteResponse
(*v1alpha1.Metadata)(nil), // 15: cosi.resource.Metadata
(EventType)(0), // 0: omni.resources.EventType
(DependencyGraphResponse_Node_Type)(0), // 1: omni.resources.DependencyGraphResponse.Node.Type
(*Resource)(nil), // 2: omni.resources.Resource
(*GetRequest)(nil), // 3: omni.resources.GetRequest
(*GetResponse)(nil), // 4: omni.resources.GetResponse
(*ListRequest)(nil), // 5: omni.resources.ListRequest
(*ListResponse)(nil), // 6: omni.resources.ListResponse
(*Event)(nil), // 7: omni.resources.Event
(*WatchRequest)(nil), // 8: omni.resources.WatchRequest
(*WatchResponse)(nil), // 9: omni.resources.WatchResponse
(*CreateRequest)(nil), // 10: omni.resources.CreateRequest
(*CreateResponse)(nil), // 11: omni.resources.CreateResponse
(*UpdateRequest)(nil), // 12: omni.resources.UpdateRequest
(*UpdateResponse)(nil), // 13: omni.resources.UpdateResponse
(*DeleteRequest)(nil), // 14: omni.resources.DeleteRequest
(*DeleteResponse)(nil), // 15: omni.resources.DeleteResponse
(*ControllersRequest)(nil), // 16: omni.resources.ControllersRequest
(*ControllersResponse)(nil), // 17: omni.resources.ControllersResponse
(*DependencyGraphRequest)(nil), // 18: omni.resources.DependencyGraphRequest
(*DependencyGraphResponse)(nil), // 19: omni.resources.DependencyGraphResponse
(*DependencyGraphResponse_Node)(nil), // 20: omni.resources.DependencyGraphResponse.Node
(*DependencyGraphResponse_Edge)(nil), // 21: omni.resources.DependencyGraphResponse.Edge
(*v1alpha1.Metadata)(nil), // 22: cosi.resource.Metadata
}
var file_omni_resources_resources_proto_depIdxs = []int32{
15, // 0: omni.resources.Resource.metadata:type_name -> cosi.resource.Metadata
22, // 0: omni.resources.Resource.metadata:type_name -> cosi.resource.Metadata
0, // 1: omni.resources.Event.event_type:type_name -> omni.resources.EventType
6, // 2: omni.resources.WatchResponse.event:type_name -> omni.resources.Event
1, // 3: omni.resources.CreateRequest.resource:type_name -> omni.resources.Resource
1, // 4: omni.resources.UpdateRequest.resource:type_name -> omni.resources.Resource
2, // 5: omni.resources.ResourceService.Get:input_type -> omni.resources.GetRequest
4, // 6: omni.resources.ResourceService.List:input_type -> omni.resources.ListRequest
9, // 7: omni.resources.ResourceService.Create:input_type -> omni.resources.CreateRequest
11, // 8: omni.resources.ResourceService.Update:input_type -> omni.resources.UpdateRequest
13, // 9: omni.resources.ResourceService.Delete:input_type -> omni.resources.DeleteRequest
13, // 10: omni.resources.ResourceService.Teardown:input_type -> omni.resources.DeleteRequest
7, // 11: omni.resources.ResourceService.Watch:input_type -> omni.resources.WatchRequest
3, // 12: omni.resources.ResourceService.Get:output_type -> omni.resources.GetResponse
5, // 13: omni.resources.ResourceService.List:output_type -> omni.resources.ListResponse
10, // 14: omni.resources.ResourceService.Create:output_type -> omni.resources.CreateResponse
12, // 15: omni.resources.ResourceService.Update:output_type -> omni.resources.UpdateResponse
14, // 16: omni.resources.ResourceService.Delete:output_type -> omni.resources.DeleteResponse
14, // 17: omni.resources.ResourceService.Teardown:output_type -> omni.resources.DeleteResponse
8, // 18: omni.resources.ResourceService.Watch:output_type -> omni.resources.WatchResponse
12, // [12:19] is the sub-list for method output_type
5, // [5:12] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
7, // 2: omni.resources.WatchResponse.event:type_name -> omni.resources.Event
2, // 3: omni.resources.CreateRequest.resource:type_name -> omni.resources.Resource
2, // 4: omni.resources.UpdateRequest.resource:type_name -> omni.resources.Resource
20, // 5: omni.resources.DependencyGraphResponse.nodes:type_name -> omni.resources.DependencyGraphResponse.Node
21, // 6: omni.resources.DependencyGraphResponse.edges:type_name -> omni.resources.DependencyGraphResponse.Edge
1, // 7: omni.resources.DependencyGraphResponse.Node.type:type_name -> omni.resources.DependencyGraphResponse.Node.Type
3, // 8: omni.resources.ResourceService.Get:input_type -> omni.resources.GetRequest
5, // 9: omni.resources.ResourceService.List:input_type -> omni.resources.ListRequest
10, // 10: omni.resources.ResourceService.Create:input_type -> omni.resources.CreateRequest
12, // 11: omni.resources.ResourceService.Update:input_type -> omni.resources.UpdateRequest
14, // 12: omni.resources.ResourceService.Delete:input_type -> omni.resources.DeleteRequest
14, // 13: omni.resources.ResourceService.Teardown:input_type -> omni.resources.DeleteRequest
8, // 14: omni.resources.ResourceService.Watch:input_type -> omni.resources.WatchRequest
16, // 15: omni.resources.ResourceService.Controllers:input_type -> omni.resources.ControllersRequest
18, // 16: omni.resources.ResourceService.DependencyGraph:input_type -> omni.resources.DependencyGraphRequest
4, // 17: omni.resources.ResourceService.Get:output_type -> omni.resources.GetResponse
6, // 18: omni.resources.ResourceService.List:output_type -> omni.resources.ListResponse
11, // 19: omni.resources.ResourceService.Create:output_type -> omni.resources.CreateResponse
13, // 20: omni.resources.ResourceService.Update:output_type -> omni.resources.UpdateResponse
15, // 21: omni.resources.ResourceService.Delete:output_type -> omni.resources.DeleteResponse
15, // 22: omni.resources.ResourceService.Teardown:output_type -> omni.resources.DeleteResponse
9, // 23: omni.resources.ResourceService.Watch:output_type -> omni.resources.WatchResponse
17, // 24: omni.resources.ResourceService.Controllers:output_type -> omni.resources.ControllersResponse
19, // 25: omni.resources.ResourceService.DependencyGraph:output_type -> omni.resources.DependencyGraphResponse
17, // [17:26] is the sub-list for method output_type
8, // [8:17] 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
}
func init() { file_omni_resources_resources_proto_init() }
@ -1029,8 +1448,8 @@ func file_omni_resources_resources_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_omni_resources_resources_proto_rawDesc), len(file_omni_resources_resources_proto_rawDesc)),
NumEnums: 1,
NumMessages: 14,
NumEnums: 2,
NumMessages: 20,
NumExtensions: 0,
NumServices: 1,
},

View File

@ -220,6 +220,60 @@ func request_ResourceService_Watch_0(ctx context.Context, marshaler runtime.Mars
return stream, metadata, nil
}
func request_ResourceService_Controllers_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ControllersRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.Controllers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_Controllers_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq ControllersRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.Controllers(ctx, &protoReq)
return msg, metadata, err
}
func request_ResourceService_DependencyGraph_0(ctx context.Context, marshaler runtime.Marshaler, client ResourceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DependencyGraphRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if req.Body != nil {
_, _ = io.Copy(io.Discard, req.Body)
}
msg, err := client.DependencyGraph(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_ResourceService_DependencyGraph_0(ctx context.Context, marshaler runtime.Marshaler, server ResourceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var (
protoReq DependencyGraphRequest
metadata runtime.ServerMetadata
)
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && !errors.Is(err, io.EOF) {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.DependencyGraph(ctx, &protoReq)
return msg, metadata, err
}
// RegisterResourceServiceHandlerServer registers the http handlers for service ResourceService to "mux".
// UnaryRPC :call ResourceServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@ -353,6 +407,46 @@ func RegisterResourceServiceHandlerServer(ctx context.Context, mux *runtime.Serv
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
})
mux.Handle(http.MethodPost, pattern_ResourceService_Controllers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/omni.resources.ResourceService/Controllers", runtime.WithHTTPPathPattern("/omni.resources.ResourceService/Controllers"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_Controllers_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_Controllers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_ResourceService_DependencyGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/omni.resources.ResourceService/DependencyGraph", runtime.WithHTTPPathPattern("/omni.resources.ResourceService/DependencyGraph"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_ResourceService_DependencyGraph_0(annotatedContext, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_DependencyGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
@ -512,25 +606,63 @@ func RegisterResourceServiceHandlerClient(ctx context.Context, mux *runtime.Serv
}
forward_ResourceService_Watch_0(annotatedContext, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_ResourceService_Controllers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/omni.resources.ResourceService/Controllers", runtime.WithHTTPPathPattern("/omni.resources.ResourceService/Controllers"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_Controllers_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_Controllers_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle(http.MethodPost, pattern_ResourceService_DependencyGraph_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/omni.resources.ResourceService/DependencyGraph", runtime.WithHTTPPathPattern("/omni.resources.ResourceService/DependencyGraph"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_ResourceService_DependencyGraph_0(annotatedContext, inboundMarshaler, client, req, pathParams)
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
if err != nil {
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
return
}
forward_ResourceService_DependencyGraph_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_ResourceService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Get"}, ""))
pattern_ResourceService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "List"}, ""))
pattern_ResourceService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Create"}, ""))
pattern_ResourceService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Update"}, ""))
pattern_ResourceService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Delete"}, ""))
pattern_ResourceService_Teardown_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Teardown"}, ""))
pattern_ResourceService_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Watch"}, ""))
pattern_ResourceService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Get"}, ""))
pattern_ResourceService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "List"}, ""))
pattern_ResourceService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Create"}, ""))
pattern_ResourceService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Update"}, ""))
pattern_ResourceService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Delete"}, ""))
pattern_ResourceService_Teardown_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Teardown"}, ""))
pattern_ResourceService_Watch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Watch"}, ""))
pattern_ResourceService_Controllers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "Controllers"}, ""))
pattern_ResourceService_DependencyGraph_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"omni.resources.ResourceService", "DependencyGraph"}, ""))
)
var (
forward_ResourceService_Get_0 = runtime.ForwardResponseMessage
forward_ResourceService_List_0 = runtime.ForwardResponseMessage
forward_ResourceService_Create_0 = runtime.ForwardResponseMessage
forward_ResourceService_Update_0 = runtime.ForwardResponseMessage
forward_ResourceService_Delete_0 = runtime.ForwardResponseMessage
forward_ResourceService_Teardown_0 = runtime.ForwardResponseMessage
forward_ResourceService_Watch_0 = runtime.ForwardResponseStream
forward_ResourceService_Get_0 = runtime.ForwardResponseMessage
forward_ResourceService_List_0 = runtime.ForwardResponseMessage
forward_ResourceService_Create_0 = runtime.ForwardResponseMessage
forward_ResourceService_Update_0 = runtime.ForwardResponseMessage
forward_ResourceService_Delete_0 = runtime.ForwardResponseMessage
forward_ResourceService_Teardown_0 = runtime.ForwardResponseMessage
forward_ResourceService_Watch_0 = runtime.ForwardResponseStream
forward_ResourceService_Controllers_0 = runtime.ForwardResponseMessage
forward_ResourceService_DependencyGraph_0 = runtime.ForwardResponseMessage
)

View File

@ -3,6 +3,7 @@ package omni.resources;
option go_package = "github.com/siderolabs/omni/client/api/omni/resources";
import "google/protobuf/empty.proto";
import "common/omni.proto";
import "v1alpha1/resource.proto";
@ -97,6 +98,43 @@ message DeleteRequest {
message DeleteResponse {
}
message ControllersRequest {}
message ControllersResponse {
repeated string controllers = 1;
}
message DependencyGraphRequest {
repeated string controllers = 1;
bool show_destroy_ready = 2;
}
message DependencyGraphResponse {
message Node {
enum Type {
UNKNOWN = 0;
CONTROLLER = 1;
RESOURCE = 2;
}
string id = 1;
string label = 2;
Type type = 3;
repeated string labels = 4;
repeated string fields = 5;
}
message Edge {
string id = 1;
string source = 2;
string target = 3;
int32 edge_type = 4;
}
repeated Node nodes = 1;
repeated Edge edges = 2;
}
service ResourceService {
rpc Get(GetRequest) returns (GetResponse);
rpc List(ListRequest) returns (ListResponse);
@ -105,4 +143,7 @@ service ResourceService {
rpc Delete(DeleteRequest) returns (DeleteResponse);
rpc Teardown(DeleteRequest) returns (DeleteResponse);
rpc Watch(WatchRequest) returns (stream WatchResponse);
rpc Controllers(ControllersRequest) returns (ControllersResponse);
rpc DependencyGraph(DependencyGraphRequest) returns (DependencyGraphResponse);
}

View File

@ -20,13 +20,15 @@ import (
const _ = grpc.SupportPackageIsVersion9
const (
ResourceService_Get_FullMethodName = "/omni.resources.ResourceService/Get"
ResourceService_List_FullMethodName = "/omni.resources.ResourceService/List"
ResourceService_Create_FullMethodName = "/omni.resources.ResourceService/Create"
ResourceService_Update_FullMethodName = "/omni.resources.ResourceService/Update"
ResourceService_Delete_FullMethodName = "/omni.resources.ResourceService/Delete"
ResourceService_Teardown_FullMethodName = "/omni.resources.ResourceService/Teardown"
ResourceService_Watch_FullMethodName = "/omni.resources.ResourceService/Watch"
ResourceService_Get_FullMethodName = "/omni.resources.ResourceService/Get"
ResourceService_List_FullMethodName = "/omni.resources.ResourceService/List"
ResourceService_Create_FullMethodName = "/omni.resources.ResourceService/Create"
ResourceService_Update_FullMethodName = "/omni.resources.ResourceService/Update"
ResourceService_Delete_FullMethodName = "/omni.resources.ResourceService/Delete"
ResourceService_Teardown_FullMethodName = "/omni.resources.ResourceService/Teardown"
ResourceService_Watch_FullMethodName = "/omni.resources.ResourceService/Watch"
ResourceService_Controllers_FullMethodName = "/omni.resources.ResourceService/Controllers"
ResourceService_DependencyGraph_FullMethodName = "/omni.resources.ResourceService/DependencyGraph"
)
// ResourceServiceClient is the client API for ResourceService service.
@ -40,6 +42,8 @@ type ResourceServiceClient interface {
Delete(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
Teardown(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error)
Watch(ctx context.Context, in *WatchRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[WatchResponse], error)
Controllers(ctx context.Context, in *ControllersRequest, opts ...grpc.CallOption) (*ControllersResponse, error)
DependencyGraph(ctx context.Context, in *DependencyGraphRequest, opts ...grpc.CallOption) (*DependencyGraphResponse, error)
}
type resourceServiceClient struct {
@ -129,6 +133,26 @@ func (c *resourceServiceClient) Watch(ctx context.Context, in *WatchRequest, opt
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ResourceService_WatchClient = grpc.ServerStreamingClient[WatchResponse]
func (c *resourceServiceClient) Controllers(ctx context.Context, in *ControllersRequest, opts ...grpc.CallOption) (*ControllersResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(ControllersResponse)
err := c.cc.Invoke(ctx, ResourceService_Controllers_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *resourceServiceClient) DependencyGraph(ctx context.Context, in *DependencyGraphRequest, opts ...grpc.CallOption) (*DependencyGraphResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(DependencyGraphResponse)
err := c.cc.Invoke(ctx, ResourceService_DependencyGraph_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// ResourceServiceServer is the server API for ResourceService service.
// All implementations must embed UnimplementedResourceServiceServer
// for forward compatibility.
@ -140,6 +164,8 @@ type ResourceServiceServer interface {
Delete(context.Context, *DeleteRequest) (*DeleteResponse, error)
Teardown(context.Context, *DeleteRequest) (*DeleteResponse, error)
Watch(*WatchRequest, grpc.ServerStreamingServer[WatchResponse]) error
Controllers(context.Context, *ControllersRequest) (*ControllersResponse, error)
DependencyGraph(context.Context, *DependencyGraphRequest) (*DependencyGraphResponse, error)
mustEmbedUnimplementedResourceServiceServer()
}
@ -171,6 +197,12 @@ func (UnimplementedResourceServiceServer) Teardown(context.Context, *DeleteReque
func (UnimplementedResourceServiceServer) Watch(*WatchRequest, grpc.ServerStreamingServer[WatchResponse]) error {
return status.Errorf(codes.Unimplemented, "method Watch not implemented")
}
func (UnimplementedResourceServiceServer) Controllers(context.Context, *ControllersRequest) (*ControllersResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method Controllers not implemented")
}
func (UnimplementedResourceServiceServer) DependencyGraph(context.Context, *DependencyGraphRequest) (*DependencyGraphResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method DependencyGraph not implemented")
}
func (UnimplementedResourceServiceServer) mustEmbedUnimplementedResourceServiceServer() {}
func (UnimplementedResourceServiceServer) testEmbeddedByValue() {}
@ -311,6 +343,42 @@ func _ResourceService_Watch_Handler(srv interface{}, stream grpc.ServerStream) e
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type ResourceService_WatchServer = grpc.ServerStreamingServer[WatchResponse]
func _ResourceService_Controllers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ControllersRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).Controllers(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_Controllers_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).Controllers(ctx, req.(*ControllersRequest))
}
return interceptor(ctx, in, info, handler)
}
func _ResourceService_DependencyGraph_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(DependencyGraphRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ResourceServiceServer).DependencyGraph(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: ResourceService_DependencyGraph_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ResourceServiceServer).DependencyGraph(ctx, req.(*DependencyGraphRequest))
}
return interceptor(ctx, in, info, handler)
}
// ResourceService_ServiceDesc is the grpc.ServiceDesc for ResourceService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@ -342,6 +410,14 @@ var ResourceService_ServiceDesc = grpc.ServiceDesc{
MethodName: "Teardown",
Handler: _ResourceService_Teardown_Handler,
},
{
MethodName: "Controllers",
Handler: _ResourceService_Controllers_Handler,
},
{
MethodName: "DependencyGraph",
Handler: _ResourceService_DependencyGraph_Handler,
},
},
Streams: []grpc.StreamDesc{
{

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@ func init() {
registry.MustRegisterResource(ClusterMachineConfigStatusType, &ClusterMachineConfigStatus{})
registry.MustRegisterResource(ClusterMachineTalosVersionType, &ClusterMachineTalosVersion{})
registry.MustRegisterResource(ClusterMachineTemplateType, &ClusterMachineTemplate{})
registry.MustRegisterResource(ClusterStatusMetricsType, &ClusterStatusMetrics{})
registry.MustRegisterResource(ClusterTaintType, &ClusterTaint{})
registry.MustRegisterResource(ConfigPatchType, &ConfigPatch{})
registry.MustRegisterResource(DiscoveryAffiliateDeleteTaskType, &DiscoveryAffiliateDeleteTask{})

View File

@ -15,6 +15,12 @@ export enum EventType {
BOOTSTRAPPED = 4,
}
export enum DependencyGraphResponseNodeType {
UNKNOWN = 0,
CONTROLLER = 1,
RESOURCE = 2,
}
export type Resource = {
metadata?: CosiResourceResource.Metadata
spec?: string
@ -94,6 +100,38 @@ export type DeleteRequest = {
export type DeleteResponse = {
}
export type ControllersRequest = {
}
export type ControllersResponse = {
controllers?: string[]
}
export type DependencyGraphRequest = {
controllers?: string[]
show_destroy_ready?: boolean
}
export type DependencyGraphResponseNode = {
id?: string
label?: string
type?: DependencyGraphResponseNodeType
labels?: string[]
fields?: string[]
}
export type DependencyGraphResponseEdge = {
id?: string
source?: string
target?: string
edge_type?: number
}
export type DependencyGraphResponse = {
nodes?: DependencyGraphResponseNode[]
edges?: DependencyGraphResponseEdge[]
}
export class ResourceService {
static Get(req: GetRequest, ...options: fm.fetchOption[]): Promise<GetResponse> {
return fm.fetchReq<GetRequest, GetResponse>("POST", `/omni.resources.ResourceService/Get`, req, ...options)
@ -116,4 +154,10 @@ export class ResourceService {
static Watch(req: WatchRequest, entityNotifier?: fm.NotifyStreamEntityArrival<WatchResponse>, ...options: fm.fetchOption[]): Promise<void> {
return fm.fetchStreamingRequest<WatchRequest, WatchResponse>("POST", `/omni.resources.ResourceService/Watch`, req, entityNotifier, ...options)
}
static Controllers(req: ControllersRequest, ...options: fm.fetchOption[]): Promise<ControllersResponse> {
return fm.fetchReq<ControllersRequest, ControllersResponse>("POST", `/omni.resources.ResourceService/Controllers`, req, ...options)
}
static DependencyGraph(req: DependencyGraphRequest, ...options: fm.fetchOption[]): Promise<DependencyGraphResponse> {
return fm.fetchReq<DependencyGraphRequest, DependencyGraphResponse>("POST", `/omni.resources.ResourceService/DependencyGraph`, req, ...options)
}
}

View File

@ -27,7 +27,6 @@ export const workloadProxyPublicKeyIdSignatureBase64Cookie = "publicKeyIdSignatu
export const DefaultKubernetesVersion = "1.33.2";
export const installDiskMinSize = 5e+09;
export const MaxJoinTokenNameLength = 16;
export const MinJoinTokenLength = 8;
export const authPublicKeyIDQueryParam = "public-key-id";
export const SecureBoot = "secureboot";
export const DefaultTalosVersion = "1.10.5";

View File

@ -0,0 +1,259 @@
// Copyright (c) 2025 Sidero Labs, Inc.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//go:build sidero.debug
package grpc
import (
"context"
"encoding/json"
"errors"
"fmt"
"maps"
"reflect"
"slices"
"strings"
"github.com/cosi-project/runtime/pkg/controller"
"github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/state"
"github.com/siderolabs/gen/xslices"
"github.com/siderolabs/talos/pkg/machinery/proto"
"github.com/siderolabs/omni/client/api/omni/resources"
"github.com/siderolabs/omni/internal/pkg/auth"
"github.com/siderolabs/omni/internal/pkg/auth/actor"
"github.com/siderolabs/omni/internal/pkg/auth/role"
)
func (s *ResourceServer) Controllers(ctx context.Context, _ *resources.ControllersRequest) (*resources.ControllersResponse, error) {
_, err := auth.CheckGRPC(ctx, auth.WithRole(role.Admin))
if err != nil {
return nil, err
}
graph, err := s.runtime.GetDependencyGraph()
if err != nil {
return nil, err
}
resp := &resources.ControllersResponse{}
visited := map[string]struct{}{}
for _, edge := range graph.Edges {
if _, ok := visited[edge.ControllerName]; ok {
continue
}
resp.Controllers = append(resp.Controllers, edge.ControllerName)
visited[edge.ControllerName] = struct{}{}
}
slices.Sort(resp.Controllers)
return resp, nil
}
func (s *ResourceServer) DependencyGraph(ctx context.Context, req *resources.DependencyGraphRequest) (*resources.DependencyGraphResponse, error) {
_, err := auth.CheckGRPC(ctx, auth.WithRole(role.Admin))
if err != nil {
return nil, err
}
graph, err := s.runtime.GetDependencyGraph()
if err != nil {
return nil, err
}
filterControllers := xslices.ToSet(req.Controllers)
res := &resources.DependencyGraphResponse{}
nodesMap := map[string]string{}
genNodeID := func(label string) {
id := fmt.Sprintf("n_%s", label)
nodesMap[label] = id
}
addNode := func(edge controller.DependencyEdge, t resources.DependencyGraphResponse_Node_Type) error {
var label string
switch t {
case resources.DependencyGraphResponse_Node_RESOURCE:
label = edge.ResourceType
case resources.DependencyGraphResponse_Node_CONTROLLER:
label = edge.ControllerName
case resources.DependencyGraphResponse_Node_UNKNOWN:
return errors.New("unknown node type")
}
id, ok := nodesMap[label]
if !ok {
return nil
}
var (
labels []string
fields []string
)
if t == resources.DependencyGraphResponse_Node_RESOURCE {
ctx := actor.MarkContextAsInternalActor(ctx)
var resources []resource.Resource
if edge.ResourceID != "" {
res, err := s.state.Get(ctx, resource.NewMetadata(edge.ResourceNamespace, edge.ResourceType, edge.ResourceID, resource.VersionUndefined))
if err != nil && !state.IsNotFoundError(err) {
return err
}
if err == nil {
resources = append(resources, res)
}
} else {
response, err := s.state.List(ctx, resource.NewMetadata(edge.ResourceNamespace, edge.ResourceType, "", resource.VersionUndefined))
if err != nil {
return err
}
resources = response.Items
}
labelsMap := map[string]struct{}{}
for _, res := range resources {
for _, key := range res.Metadata().Labels().Keys() {
labelsMap[key] = struct{}{}
}
}
labels = slices.Sorted(maps.Keys(labelsMap))
res, err := protobuf.CreateResource(edge.ResourceType)
if err != nil {
return err
}
if reflect.ValueOf(res.Spec()).Kind() == reflect.Ptr {
err = json.Unmarshal([]byte("{}"), res.Spec())
if err != nil {
return err
}
type protobufWrapper interface {
GetValue() proto.Message
}
if message, ok := res.Spec().(protobufWrapper); ok {
v := reflect.TypeOf(message.GetValue()).Elem()
for i := range v.NumField() {
field := v.Field(i)
f := field.Tag.Get("json")
if f == "" {
continue
}
fields = append(fields, strings.Split(f, ",")[0])
}
}
}
}
res.Nodes = append(res.Nodes, &resources.DependencyGraphResponse_Node{
Id: id,
Label: label,
Type: t,
Labels: labels,
Fields: fields,
})
return nil
}
addEdge := func(edge controller.DependencyEdge) error {
var (
source string
target string
edgeType controller.DependencyEdgeType
)
switch edge.EdgeType {
case controller.EdgeOutputExclusive:
source = nodesMap[edge.ControllerName]
target = nodesMap[edge.ResourceType]
edgeType = edge.EdgeType
case controller.EdgeOutputShared:
source = nodesMap[edge.ControllerName]
target = nodesMap[edge.ResourceType]
edgeType = edge.EdgeType
case controller.EdgeInputStrong, controller.EdgeInputQPrimary:
source = nodesMap[edge.ResourceType]
target = nodesMap[edge.ControllerName]
edgeType = edge.EdgeType
case controller.EdgeInputWeak, controller.EdgeInputQMapped:
source = nodesMap[edge.ResourceType]
target = nodesMap[edge.ControllerName]
edgeType = edge.EdgeType
case controller.EdgeInputDestroyReady, controller.EdgeInputQMappedDestroyReady:
if req.ShowDestroyReady {
source = nodesMap[edge.ResourceType]
target = nodesMap[edge.ControllerName]
edgeType = edge.EdgeType
}
}
if source == "" || target == "" {
return nil
}
res.Edges = append(res.Edges,
&resources.DependencyGraphResponse_Edge{
Id: fmt.Sprintf("e_%s->%s", source, target),
Source: source,
Target: target,
EdgeType: int32(edgeType),
},
)
if err = addNode(edge, resources.DependencyGraphResponse_Node_CONTROLLER); err != nil {
return err
}
if err = addNode(edge, resources.DependencyGraphResponse_Node_RESOURCE); err != nil {
return err
}
return nil
}
for _, edge := range graph.Edges {
if len(filterControllers) != 0 {
if _, ok := filterControllers[edge.ControllerName]; !ok {
continue
}
}
genNodeID(edge.ControllerName)
genNodeID(edge.ResourceType)
}
for _, edge := range graph.Edges {
if err = addEdge(edge); err != nil {
return nil, err
}
}
return res, nil
}

View File

@ -28,6 +28,7 @@ import (
"github.com/siderolabs/omni/internal/backend/imagefactory"
"github.com/siderolabs/omni/internal/backend/logging"
"github.com/siderolabs/omni/internal/backend/monitoring"
"github.com/siderolabs/omni/internal/backend/runtime/omni"
"github.com/siderolabs/omni/internal/memconn"
"github.com/siderolabs/omni/internal/pkg/compress"
"github.com/siderolabs/omni/internal/pkg/config"
@ -43,7 +44,7 @@ type ServiceServer interface {
// MakeServiceServers creates a list of service servers.
func MakeServiceServers(
state state.State,
cachedState state.State,
omniRuntime *omni.Runtime,
logHandler *siderolink.LogHandler,
oidcProvider OIDCProvider,
jwtSigningKeyProvider JWTSigningKeyProvider,
@ -60,7 +61,10 @@ func MakeServiceServers(
}
servers := []ServiceServer{
&ResourceServer{},
newResourceServer(
state,
omniRuntime.GetCOSIRuntime(),
),
&oidcServer{
provider: oidcProvider,
},
@ -79,7 +83,7 @@ func MakeServiceServers(
logger: logger.With(logging.Component("auth_server")),
},
&COSIResourceServer{
State: cachedState,
State: omniRuntime.CachedState(),
},
&machineService{},
}

View File

@ -11,6 +11,7 @@ import (
"errors"
"time"
cosiruntime "github.com/cosi-project/runtime/pkg/controller/runtime"
cosiresource "github.com/cosi-project/runtime/pkg/resource"
"github.com/cosi-project/runtime/pkg/resource/protobuf"
"github.com/cosi-project/runtime/pkg/state"
@ -29,9 +30,18 @@ import (
"github.com/siderolabs/omni/internal/backend/runtime"
)
func newResourceServer(state state.State, runtime *cosiruntime.Runtime) *ResourceServer {
return &ResourceServer{
runtime: runtime,
state: state,
}
}
// ResourceServer implements resources CRUD API.
type ResourceServer struct {
resources.UnimplementedResourceServiceServer
runtime *cosiruntime.Runtime
state state.State
}
func (s *ResourceServer) register(server grpc.ServiceRegistrar) {

View File

@ -207,7 +207,7 @@ func (s *Server) Run(ctx context.Context) error {
servicesServer := grpcomni.MakeServiceServers(
s.state.Default(),
s.omniRuntime.CachedState(),
s.omniRuntime,
s.logHandler,
oidcProvider,
oidcStorage,