From b44f964d3fc6306e4b8df01af3d01441f4b585ab Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Mon, 27 Jul 2026 15:36:50 +1200 Subject: [PATCH 1/5] Endpoint for details about the cluster --- cluster.proto | 34 +++++ pb/cluster.pb.go | 314 ++++++++++++++++++++++++++++++++++++++++++ pb/cluster_grpc.pb.go | 105 ++++++++++++++ 3 files changed, 453 insertions(+) create mode 100644 cluster.proto create mode 100644 pb/cluster.pb.go create mode 100644 pb/cluster_grpc.pb.go diff --git a/cluster.proto b/cluster.proto new file mode 100644 index 0000000..61983dd --- /dev/null +++ b/cluster.proto @@ -0,0 +1,34 @@ +/** Service responsible for cluster information */ +syntax = "proto3"; + +package workflow; + +option go_package = "./pb"; + +service cluster { + rpc Get (ClusterGetRequest) returns (ClusterGetResponse) {} +} + +/** + * Get the cluster status + */ +message ClusterGetRequest { +} + +/** + * Returns the cluster status + */ +message ClusterGetResponse { + enum ClusterStatus { + None = 0; + Operational = 1; + Degraded = 2; + PartialOutage = 3; + MajorOutage = 4; + } + ClusterStatus Status = 1; // Status of the cluster + string Version = 2; // Version number + string BuildDate = 3; // When this version was built + string UiBaseUri = 4; // Base URI for the UI + string SshBaseUri = 5; // URI for SSH connections +} diff --git a/pb/cluster.pb.go b/pb/cluster.pb.go new file mode 100644 index 0000000..cb9ea65 --- /dev/null +++ b/pb/cluster.pb.go @@ -0,0 +1,314 @@ +//* Service responsible for cluster information + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc v3.21.12 +// source: cluster.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ClusterGetResponse_ClusterStatus int32 + +const ( + ClusterGetResponse_None ClusterGetResponse_ClusterStatus = 0 + ClusterGetResponse_Operational ClusterGetResponse_ClusterStatus = 1 + ClusterGetResponse_Degraded ClusterGetResponse_ClusterStatus = 2 + ClusterGetResponse_PartialOutage ClusterGetResponse_ClusterStatus = 3 + ClusterGetResponse_MajorOutage ClusterGetResponse_ClusterStatus = 4 +) + +// Enum value maps for ClusterGetResponse_ClusterStatus. +var ( + ClusterGetResponse_ClusterStatus_name = map[int32]string{ + 0: "None", + 1: "Operational", + 2: "Degraded", + 3: "PartialOutage", + 4: "MajorOutage", + } + ClusterGetResponse_ClusterStatus_value = map[string]int32{ + "None": 0, + "Operational": 1, + "Degraded": 2, + "PartialOutage": 3, + "MajorOutage": 4, + } +) + +func (x ClusterGetResponse_ClusterStatus) Enum() *ClusterGetResponse_ClusterStatus { + p := new(ClusterGetResponse_ClusterStatus) + *p = x + return p +} + +func (x ClusterGetResponse_ClusterStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ClusterGetResponse_ClusterStatus) Descriptor() protoreflect.EnumDescriptor { + return file_cluster_proto_enumTypes[0].Descriptor() +} + +func (ClusterGetResponse_ClusterStatus) Type() protoreflect.EnumType { + return &file_cluster_proto_enumTypes[0] +} + +func (x ClusterGetResponse_ClusterStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ClusterGetResponse_ClusterStatus.Descriptor instead. +func (ClusterGetResponse_ClusterStatus) EnumDescriptor() ([]byte, []int) { + return file_cluster_proto_rawDescGZIP(), []int{1, 0} +} + +// * +// Get the cluster status +type ClusterGetRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ClusterGetRequest) Reset() { + *x = ClusterGetRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cluster_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClusterGetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClusterGetRequest) ProtoMessage() {} + +func (x *ClusterGetRequest) ProtoReflect() protoreflect.Message { + mi := &file_cluster_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClusterGetRequest.ProtoReflect.Descriptor instead. +func (*ClusterGetRequest) Descriptor() ([]byte, []int) { + return file_cluster_proto_rawDescGZIP(), []int{0} +} + +// * +// Returns the cluster status +type ClusterGetResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Status ClusterGetResponse_ClusterStatus `protobuf:"varint,1,opt,name=Status,proto3,enum=workflow.ClusterGetResponse_ClusterStatus" json:"Status,omitempty"` // Status of the cluster + Version string `protobuf:"bytes,2,opt,name=Version,proto3" json:"Version,omitempty"` // Version number + BuildDate string `protobuf:"bytes,3,opt,name=BuildDate,proto3" json:"BuildDate,omitempty"` // When this version was built + UiBaseUri string `protobuf:"bytes,4,opt,name=UiBaseUri,proto3" json:"UiBaseUri,omitempty"` // Base URI for the UI + SshBaseUri string `protobuf:"bytes,5,opt,name=SshBaseUri,proto3" json:"SshBaseUri,omitempty"` // URI for SSH connections +} + +func (x *ClusterGetResponse) Reset() { + *x = ClusterGetResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cluster_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClusterGetResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClusterGetResponse) ProtoMessage() {} + +func (x *ClusterGetResponse) ProtoReflect() protoreflect.Message { + mi := &file_cluster_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClusterGetResponse.ProtoReflect.Descriptor instead. +func (*ClusterGetResponse) Descriptor() ([]byte, []int) { + return file_cluster_proto_rawDescGZIP(), []int{1} +} + +func (x *ClusterGetResponse) GetStatus() ClusterGetResponse_ClusterStatus { + if x != nil { + return x.Status + } + return ClusterGetResponse_None +} + +func (x *ClusterGetResponse) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ClusterGetResponse) GetBuildDate() string { + if x != nil { + return x.BuildDate + } + return "" +} + +func (x *ClusterGetResponse) GetUiBaseUri() string { + if x != nil { + return x.UiBaseUri + } + return "" +} + +func (x *ClusterGetResponse) GetSshBaseUri() string { + if x != nil { + return x.SshBaseUri + } + return "" +} + +var File_cluster_proto protoreflect.FileDescriptor + +var file_cluster_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x13, 0x0a, 0x11, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xac, + 0x02, 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x12, + 0x1e, 0x0a, 0x0a, 0x53, 0x73, 0x68, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x53, 0x73, 0x68, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x22, + 0x5c, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, + 0x65, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, + 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x04, 0x32, 0x4d, 0x0a, + 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, + 0x1b, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, + 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x06, 0x5a, 0x04, + 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cluster_proto_rawDescOnce sync.Once + file_cluster_proto_rawDescData = file_cluster_proto_rawDesc +) + +func file_cluster_proto_rawDescGZIP() []byte { + file_cluster_proto_rawDescOnce.Do(func() { + file_cluster_proto_rawDescData = protoimpl.X.CompressGZIP(file_cluster_proto_rawDescData) + }) + return file_cluster_proto_rawDescData +} + +var file_cluster_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cluster_proto_goTypes = []interface{}{ + (ClusterGetResponse_ClusterStatus)(0), // 0: workflow.ClusterGetResponse.ClusterStatus + (*ClusterGetRequest)(nil), // 1: workflow.ClusterGetRequest + (*ClusterGetResponse)(nil), // 2: workflow.ClusterGetResponse +} +var file_cluster_proto_depIdxs = []int32{ + 0, // 0: workflow.ClusterGetResponse.Status:type_name -> workflow.ClusterGetResponse.ClusterStatus + 1, // 1: workflow.cluster.Get:input_type -> workflow.ClusterGetRequest + 2, // 2: workflow.cluster.Get:output_type -> workflow.ClusterGetResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_cluster_proto_init() } +func file_cluster_proto_init() { + if File_cluster_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_cluster_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClusterGetRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cluster_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClusterGetResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_cluster_proto_rawDesc, + NumEnums: 1, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cluster_proto_goTypes, + DependencyIndexes: file_cluster_proto_depIdxs, + EnumInfos: file_cluster_proto_enumTypes, + MessageInfos: file_cluster_proto_msgTypes, + }.Build() + File_cluster_proto = out.File + file_cluster_proto_rawDesc = nil + file_cluster_proto_goTypes = nil + file_cluster_proto_depIdxs = nil +} diff --git a/pb/cluster_grpc.pb.go b/pb/cluster_grpc.pb.go new file mode 100644 index 0000000..e9f0b39 --- /dev/null +++ b/pb/cluster_grpc.pb.go @@ -0,0 +1,105 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.12 +// source: cluster.proto + +package pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// ClusterClient is the client API for Cluster service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ClusterClient interface { + Get(ctx context.Context, in *ClusterGetRequest, opts ...grpc.CallOption) (*ClusterGetResponse, error) +} + +type clusterClient struct { + cc grpc.ClientConnInterface +} + +func NewClusterClient(cc grpc.ClientConnInterface) ClusterClient { + return &clusterClient{cc} +} + +func (c *clusterClient) Get(ctx context.Context, in *ClusterGetRequest, opts ...grpc.CallOption) (*ClusterGetResponse, error) { + out := new(ClusterGetResponse) + err := c.cc.Invoke(ctx, "/workflow.cluster/Get", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ClusterServer is the server API for Cluster service. +// All implementations must embed UnimplementedClusterServer +// for forward compatibility +type ClusterServer interface { + Get(context.Context, *ClusterGetRequest) (*ClusterGetResponse, error) + mustEmbedUnimplementedClusterServer() +} + +// UnimplementedClusterServer must be embedded to have forward compatible implementations. +type UnimplementedClusterServer struct { +} + +func (UnimplementedClusterServer) Get(context.Context, *ClusterGetRequest) (*ClusterGetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") +} +func (UnimplementedClusterServer) mustEmbedUnimplementedClusterServer() {} + +// UnsafeClusterServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ClusterServer will +// result in compilation errors. +type UnsafeClusterServer interface { + mustEmbedUnimplementedClusterServer() +} + +func RegisterClusterServer(s grpc.ServiceRegistrar, srv ClusterServer) { + s.RegisterService(&Cluster_ServiceDesc, srv) +} + +func _Cluster_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ClusterGetRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ClusterServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/workflow.cluster/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ClusterServer).Get(ctx, req.(*ClusterGetRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Cluster_ServiceDesc is the grpc.ServiceDesc for Cluster service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Cluster_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "workflow.cluster", + HandlerType: (*ClusterServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Get", + Handler: _Cluster_Get_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cluster.proto", +} From 039ef592c41f3ba0e7507ee26899f6ba47e8a157 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Mon, 27 Jul 2026 15:38:14 +1200 Subject: [PATCH 2/5] Rename SSH endpoint --- cluster.proto | 2 +- pb/cluster.pb.go | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cluster.proto b/cluster.proto index 61983dd..e6e7442 100644 --- a/cluster.proto +++ b/cluster.proto @@ -30,5 +30,5 @@ message ClusterGetResponse { string Version = 2; // Version number string BuildDate = 3; // When this version was built string UiBaseUri = 4; // Base URI for the UI - string SshBaseUri = 5; // URI for SSH connections + string SshUri = 5; // URI for SSH connections } diff --git a/pb/cluster.pb.go b/pb/cluster.pb.go index cb9ea65..8d36b37 100644 --- a/pb/cluster.pb.go +++ b/pb/cluster.pb.go @@ -124,11 +124,11 @@ type ClusterGetResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Status ClusterGetResponse_ClusterStatus `protobuf:"varint,1,opt,name=Status,proto3,enum=workflow.ClusterGetResponse_ClusterStatus" json:"Status,omitempty"` // Status of the cluster - Version string `protobuf:"bytes,2,opt,name=Version,proto3" json:"Version,omitempty"` // Version number - BuildDate string `protobuf:"bytes,3,opt,name=BuildDate,proto3" json:"BuildDate,omitempty"` // When this version was built - UiBaseUri string `protobuf:"bytes,4,opt,name=UiBaseUri,proto3" json:"UiBaseUri,omitempty"` // Base URI for the UI - SshBaseUri string `protobuf:"bytes,5,opt,name=SshBaseUri,proto3" json:"SshBaseUri,omitempty"` // URI for SSH connections + Status ClusterGetResponse_ClusterStatus `protobuf:"varint,1,opt,name=Status,proto3,enum=workflow.ClusterGetResponse_ClusterStatus" json:"Status,omitempty"` // Status of the cluster + Version string `protobuf:"bytes,2,opt,name=Version,proto3" json:"Version,omitempty"` // Version number + BuildDate string `protobuf:"bytes,3,opt,name=BuildDate,proto3" json:"BuildDate,omitempty"` // When this version was built + UiBaseUri string `protobuf:"bytes,4,opt,name=UiBaseUri,proto3" json:"UiBaseUri,omitempty"` // Base URI for the UI + SshUri string `protobuf:"bytes,5,opt,name=SshUri,proto3" json:"SshUri,omitempty"` // URI for SSH connections } func (x *ClusterGetResponse) Reset() { @@ -191,9 +191,9 @@ func (x *ClusterGetResponse) GetUiBaseUri() string { return "" } -func (x *ClusterGetResponse) GetSshBaseUri() string { +func (x *ClusterGetResponse) GetSshUri() string { if x != nil { - return x.SshBaseUri + return x.SshUri } return "" } @@ -203,7 +203,7 @@ var File_cluster_proto protoreflect.FileDescriptor var file_cluster_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x13, 0x0a, 0x11, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xac, + 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa4, 0x02, 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, @@ -215,20 +215,20 @@ var file_cluster_proto_rawDesc = []byte{ 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x12, - 0x1e, 0x0a, 0x0a, 0x53, 0x73, 0x68, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x53, 0x73, 0x68, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x22, - 0x5c, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x70, - 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, - 0x65, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, - 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x04, 0x32, 0x4d, 0x0a, - 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, - 0x1b, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, - 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, - 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x06, 0x5a, 0x04, - 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x16, 0x0a, 0x06, 0x53, 0x73, 0x68, 0x55, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x53, 0x73, 0x68, 0x55, 0x72, 0x69, 0x22, 0x5c, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x10, + 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x61, + 0x67, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x4f, 0x75, 0x74, + 0x61, 0x67, 0x65, 0x10, 0x04, 0x32, 0x4d, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, + 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x1b, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( From bdc51eff1ae323d48656dc85c1d7742613c982ef Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 10:49:51 +1200 Subject: [PATCH 3/5] Refactoring and renaming endpoints --- cluster.proto | 14 +++-- pb/cluster.pb.go | 129 +++++++++++++++++++++++++++++++++++------------ 2 files changed, 106 insertions(+), 37 deletions(-) diff --git a/cluster.proto b/cluster.proto index e6e7442..8cfe54b 100644 --- a/cluster.proto +++ b/cluster.proto @@ -26,9 +26,13 @@ message ClusterGetResponse { PartialOutage = 3; MajorOutage = 4; } - ClusterStatus Status = 1; // Status of the cluster - string Version = 2; // Version number - string BuildDate = 3; // When this version was built - string UiBaseUri = 4; // Base URI for the UI - string SshUri = 5; // URI for SSH connections + ClusterStatus Status = 1; // Status of the cluster + string Version = 2; // Version number + string BuildDate = 3; // When this version was built + ClusterEndpoints Endpoints = 4; // Endpoints for the cluster } + +message ClusterEndpoints { + string Console = 1; // Base URI for the UI + string SSH = 2; // URI for SSH connections +} \ No newline at end of file diff --git a/pb/cluster.pb.go b/pb/cluster.pb.go index 8d36b37..2e4a262 100644 --- a/pb/cluster.pb.go +++ b/pb/cluster.pb.go @@ -127,8 +127,7 @@ type ClusterGetResponse struct { Status ClusterGetResponse_ClusterStatus `protobuf:"varint,1,opt,name=Status,proto3,enum=workflow.ClusterGetResponse_ClusterStatus" json:"Status,omitempty"` // Status of the cluster Version string `protobuf:"bytes,2,opt,name=Version,proto3" json:"Version,omitempty"` // Version number BuildDate string `protobuf:"bytes,3,opt,name=BuildDate,proto3" json:"BuildDate,omitempty"` // When this version was built - UiBaseUri string `protobuf:"bytes,4,opt,name=UiBaseUri,proto3" json:"UiBaseUri,omitempty"` // Base URI for the UI - SshUri string `protobuf:"bytes,5,opt,name=SshUri,proto3" json:"SshUri,omitempty"` // URI for SSH connections + Endpoints *ClusterEndpoints `protobuf:"bytes,4,opt,name=Endpoints,proto3" json:"Endpoints,omitempty"` // Endpoints for the cluster } func (x *ClusterGetResponse) Reset() { @@ -184,16 +183,64 @@ func (x *ClusterGetResponse) GetBuildDate() string { return "" } -func (x *ClusterGetResponse) GetUiBaseUri() string { +func (x *ClusterGetResponse) GetEndpoints() *ClusterEndpoints { if x != nil { - return x.UiBaseUri + return x.Endpoints + } + return nil +} + +type ClusterEndpoints struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Console string `protobuf:"bytes,1,opt,name=Console,proto3" json:"Console,omitempty"` // Base URI for the UI + SSH string `protobuf:"bytes,2,opt,name=SSH,proto3" json:"SSH,omitempty"` // URI for SSH connections +} + +func (x *ClusterEndpoints) Reset() { + *x = ClusterEndpoints{} + if protoimpl.UnsafeEnabled { + mi := &file_cluster_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClusterEndpoints) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClusterEndpoints) ProtoMessage() {} + +func (x *ClusterEndpoints) ProtoReflect() protoreflect.Message { + mi := &file_cluster_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClusterEndpoints.ProtoReflect.Descriptor instead. +func (*ClusterEndpoints) Descriptor() ([]byte, []int) { + return file_cluster_proto_rawDescGZIP(), []int{2} +} + +func (x *ClusterEndpoints) GetConsole() string { + if x != nil { + return x.Console } return "" } -func (x *ClusterGetResponse) GetSshUri() string { +func (x *ClusterEndpoints) GetSSH() string { if x != nil { - return x.SshUri + return x.SSH } return "" } @@ -203,7 +250,7 @@ var File_cluster_proto protoreflect.FileDescriptor var file_cluster_proto_rawDesc = []byte{ 0x0a, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x22, 0x13, 0x0a, 0x11, 0x43, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa4, + 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa8, 0x02, 0x0a, 0x12, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, @@ -213,22 +260,26 @@ var file_cluster_proto_rawDesc = []byte{ 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x61, 0x74, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x55, 0x69, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x69, 0x12, - 0x16, 0x0a, 0x06, 0x53, 0x73, 0x68, 0x55, 0x72, 0x69, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x53, 0x73, 0x68, 0x55, 0x72, 0x69, 0x22, 0x5c, 0x0a, 0x0d, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x6f, 0x6e, 0x65, - 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65, 0x67, 0x72, 0x61, 0x64, 0x65, 0x64, 0x10, - 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x61, - 0x67, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x6a, 0x6f, 0x72, 0x4f, 0x75, 0x74, - 0x61, 0x67, 0x65, 0x10, 0x04, 0x32, 0x4d, 0x0a, 0x07, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x1b, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, - 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, - 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x12, 0x38, 0x0a, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x52, 0x09, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x5c, 0x0a, 0x0d, 0x43, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x08, 0x0a, 0x04, + 0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x65, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x64, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, + 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x6a, 0x6f, + 0x72, 0x4f, 0x75, 0x74, 0x61, 0x67, 0x65, 0x10, 0x04, 0x22, 0x3e, 0x0a, 0x10, 0x43, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x18, 0x0a, + 0x07, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x53, 0x48, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x53, 0x53, 0x48, 0x32, 0x4d, 0x0a, 0x07, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x1b, 0x2e, 0x77, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x2e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x65, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x06, 0x5a, 0x04, 0x2e, 0x2f, 0x70, 0x62, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -244,21 +295,23 @@ func file_cluster_proto_rawDescGZIP() []byte { } var file_cluster_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cluster_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_cluster_proto_goTypes = []interface{}{ (ClusterGetResponse_ClusterStatus)(0), // 0: workflow.ClusterGetResponse.ClusterStatus (*ClusterGetRequest)(nil), // 1: workflow.ClusterGetRequest (*ClusterGetResponse)(nil), // 2: workflow.ClusterGetResponse + (*ClusterEndpoints)(nil), // 3: workflow.ClusterEndpoints } var file_cluster_proto_depIdxs = []int32{ 0, // 0: workflow.ClusterGetResponse.Status:type_name -> workflow.ClusterGetResponse.ClusterStatus - 1, // 1: workflow.cluster.Get:input_type -> workflow.ClusterGetRequest - 2, // 2: workflow.cluster.Get:output_type -> workflow.ClusterGetResponse - 2, // [2:3] is the sub-list for method output_type - 1, // [1:2] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 3, // 1: workflow.ClusterGetResponse.Endpoints:type_name -> workflow.ClusterEndpoints + 1, // 2: workflow.cluster.Get:input_type -> workflow.ClusterGetRequest + 2, // 3: workflow.cluster.Get:output_type -> workflow.ClusterGetResponse + 3, // [3:4] is the sub-list for method output_type + 2, // [2:3] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_cluster_proto_init() } @@ -291,6 +344,18 @@ func file_cluster_proto_init() { return nil } } + file_cluster_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClusterEndpoints); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -298,7 +363,7 @@ func file_cluster_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cluster_proto_rawDesc, NumEnums: 1, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 1, }, From e1696cbad4d08b97ba4b8361f0bfbdce616914b5 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 10:51:30 +1200 Subject: [PATCH 4/5] EOF --- cluster.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cluster.proto b/cluster.proto index 8cfe54b..ae0bf56 100644 --- a/cluster.proto +++ b/cluster.proto @@ -35,4 +35,4 @@ message ClusterGetResponse { message ClusterEndpoints { string Console = 1; // Base URI for the UI string SSH = 2; // URI for SSH connections -} \ No newline at end of file +} From 375c0b58d01ac5b255a315ace96dc18b8b975da1 Mon Sep 17 00:00:00 2001 From: Nathan ter Bogt Date: Wed, 29 Jul 2026 13:59:44 +1200 Subject: [PATCH 5/5] Concrete implementation of the mock --- cmd/apiserver-mock/main.go | 4 ++++ internal/server/mock/cluster/server.go | 27 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 internal/server/mock/cluster/server.go diff --git a/cmd/apiserver-mock/main.go b/cmd/apiserver-mock/main.go index 6800545..b68cf2c 100644 --- a/cmd/apiserver-mock/main.go +++ b/cmd/apiserver-mock/main.go @@ -16,6 +16,7 @@ import ( "github.com/skpr/api/internal/model" "github.com/skpr/api/internal/server/mock/backup" + "github.com/skpr/api/internal/server/mock/cluster" "github.com/skpr/api/internal/server/mock/config" "github.com/skpr/api/internal/server/mock/cron" "github.com/skpr/api/internal/server/mock/environment" @@ -78,6 +79,9 @@ func main() { Model: globalModel, }) + log.Println("Registering service: Cluster") + pb.RegisterClusterServer(server, &cluster.Server{}) + log.Println("Registering service: Trace") pb.RegisterTraceServer(server, &trace.Server{}) diff --git a/internal/server/mock/cluster/server.go b/internal/server/mock/cluster/server.go new file mode 100644 index 0000000..a0d81b3 --- /dev/null +++ b/internal/server/mock/cluster/server.go @@ -0,0 +1,27 @@ +package cluster + +import ( + "context" + + "github.com/skpr/api/pb" +) + +// Server implements the GRPC "cluster" definition. +type Server struct { + pb.UnimplementedClusterServer +} + +// Get the cluster status from the server. +func (s *Server) Get(ctx context.Context, req *pb.ClusterGetRequest) (*pb.ClusterGetResponse, error) { + resp := &pb.ClusterGetResponse{ + Status: pb.ClusterGetResponse_Operational, + Version: "0.34.5-mock", + BuildDate: "2025-05-06", + Endpoints: &pb.ClusterEndpoints{ + Console: "https://console.mock.localhost", + SSH: "console.mock.localhost:5000", + }, + } + + return resp, nil +}