Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 714320c018 | |||
| fa8ba6fac1 | |||
| f66758b92b | |||
| 09d0d197c3 | |||
| 52914d50b0 | |||
| bb4bee51ba | |||
| 4ac8a6d60b |
@@ -14,8 +14,8 @@ import (
|
||||
|
||||
func stopCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "stop <service>",
|
||||
Short: "Stop all components, set active=false",
|
||||
Use: "stop <service>[/<component>]",
|
||||
Short: "Stop components (or all), set active=false",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := config.LoadCLIConfig(cfgPath)
|
||||
@@ -23,7 +23,7 @@ func stopCmd() *cobra.Command {
|
||||
return fmt.Errorf("load config: %w", err)
|
||||
}
|
||||
|
||||
serviceName := args[0]
|
||||
serviceName, component := parseServiceArg(args[0])
|
||||
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
||||
|
||||
def, err := servicedef.Load(defPath)
|
||||
@@ -31,11 +31,14 @@ func stopCmd() *cobra.Command {
|
||||
return fmt.Errorf("load service def: %w", err)
|
||||
}
|
||||
|
||||
// Only flip active=false when stopping the whole service.
|
||||
if component == "" {
|
||||
active := false
|
||||
def.Active = &active
|
||||
if err := servicedef.Write(defPath, def); err != nil {
|
||||
return fmt.Errorf("write service def: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
address, err := findNodeAddress(cfg, def.Node)
|
||||
if err != nil {
|
||||
@@ -50,6 +53,7 @@ func stopCmd() *cobra.Command {
|
||||
|
||||
resp, err := client.StopService(context.Background(), &mcpv1.StopServiceRequest{
|
||||
Name: serviceName,
|
||||
Component: component,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("stop service: %w", err)
|
||||
@@ -63,8 +67,8 @@ func stopCmd() *cobra.Command {
|
||||
|
||||
func startCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "start <service>",
|
||||
Short: "Start all components, set active=true",
|
||||
Use: "start <service>[/<component>]",
|
||||
Short: "Start components (or all), set active=true",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := config.LoadCLIConfig(cfgPath)
|
||||
@@ -72,7 +76,7 @@ func startCmd() *cobra.Command {
|
||||
return fmt.Errorf("load config: %w", err)
|
||||
}
|
||||
|
||||
serviceName := args[0]
|
||||
serviceName, component := parseServiceArg(args[0])
|
||||
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
||||
|
||||
def, err := servicedef.Load(defPath)
|
||||
@@ -80,11 +84,14 @@ func startCmd() *cobra.Command {
|
||||
return fmt.Errorf("load service def: %w", err)
|
||||
}
|
||||
|
||||
// Only flip active=true when starting the whole service.
|
||||
if component == "" {
|
||||
active := true
|
||||
def.Active = &active
|
||||
if err := servicedef.Write(defPath, def); err != nil {
|
||||
return fmt.Errorf("write service def: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
address, err := findNodeAddress(cfg, def.Node)
|
||||
if err != nil {
|
||||
@@ -99,6 +106,7 @@ func startCmd() *cobra.Command {
|
||||
|
||||
resp, err := client.StartService(context.Background(), &mcpv1.StartServiceRequest{
|
||||
Name: serviceName,
|
||||
Component: component,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("start service: %w", err)
|
||||
@@ -112,8 +120,8 @@ func startCmd() *cobra.Command {
|
||||
|
||||
func restartCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "restart <service>",
|
||||
Short: "Restart all components",
|
||||
Use: "restart <service>[/<component>]",
|
||||
Short: "Restart components (or all)",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := config.LoadCLIConfig(cfgPath)
|
||||
@@ -121,7 +129,7 @@ func restartCmd() *cobra.Command {
|
||||
return fmt.Errorf("load config: %w", err)
|
||||
}
|
||||
|
||||
serviceName := args[0]
|
||||
serviceName, component := parseServiceArg(args[0])
|
||||
defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")
|
||||
|
||||
def, err := servicedef.Load(defPath)
|
||||
@@ -142,6 +150,7 @@ func restartCmd() *cobra.Command {
|
||||
|
||||
resp, err := client.RestartService(context.Background(), &mcpv1.RestartServiceRequest{
|
||||
Name: serviceName,
|
||||
Component: component,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("restart service: %w", err)
|
||||
|
||||
@@ -28,17 +28,26 @@ func routeCmd() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
routeMode string
|
||||
backendTLS bool
|
||||
tlsCert string
|
||||
tlsKey string
|
||||
)
|
||||
|
||||
add := &cobra.Command{
|
||||
Use: "add <listener> <hostname> <backend>",
|
||||
Short: "Add a route to mc-proxy",
|
||||
Long: "Add a route. Example: mcp route add -n rift :443 mcq.metacircular.net 100.95.252.120:443",
|
||||
Long: "Add a route. Example: mcp route add -n rift :443 mcq.svc.mcp.metacircular.net 127.0.0.1:48080 --mode l7 --tls-cert /srv/mc-proxy/certs/mcq.pem --tls-key /srv/mc-proxy/certs/mcq.key",
|
||||
Args: cobra.ExactArgs(3),
|
||||
RunE: func(_ *cobra.Command, args []string) error {
|
||||
return runRouteAdd(nodeName, args)
|
||||
return runRouteAdd(nodeName, args, routeMode, backendTLS, tlsCert, tlsKey)
|
||||
},
|
||||
}
|
||||
add.Flags().String("mode", "l4", "route mode (l4 or l7)")
|
||||
add.Flags().Bool("backend-tls", false, "re-encrypt traffic to backend")
|
||||
add.Flags().StringVar(&routeMode, "mode", "l4", "route mode (l4 or l7)")
|
||||
add.Flags().BoolVar(&backendTLS, "backend-tls", false, "re-encrypt traffic to backend")
|
||||
add.Flags().StringVar(&tlsCert, "tls-cert", "", "path to TLS cert on the node (required for l7)")
|
||||
add.Flags().StringVar(&tlsKey, "tls-key", "", "path to TLS key on the node (required for l7)")
|
||||
|
||||
remove := &cobra.Command{
|
||||
Use: "remove <listener> <hostname>",
|
||||
@@ -138,7 +147,7 @@ func printRoutes(nodeName string, resp *mcpv1.ListProxyRoutesResponse) {
|
||||
}
|
||||
}
|
||||
|
||||
func runRouteAdd(nodeName string, args []string) error {
|
||||
func runRouteAdd(nodeName string, args []string, mode string, backendTLS bool, tlsCert, tlsKey string) error {
|
||||
if nodeName == "" {
|
||||
return fmt.Errorf("--node is required")
|
||||
}
|
||||
@@ -166,12 +175,16 @@ func runRouteAdd(nodeName string, args []string) error {
|
||||
ListenerAddr: args[0],
|
||||
Hostname: args[1],
|
||||
Backend: args[2],
|
||||
Mode: mode,
|
||||
BackendTls: backendTLS,
|
||||
TlsCert: tlsCert,
|
||||
TlsKey: tlsKey,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("add route: %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf("Added route: %s → %s on %s (%s)\n", args[1], args[2], args[0], nodeName)
|
||||
fmt.Printf("Added route: %s %s → %s on %s (%s)\n", mode, args[1], args[2], args[0], nodeName)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
version = pkgs.lib.removePrefix "v" (self.gitDescribe or self.shortRev or self.dirtyShortRev or "unknown");
|
||||
version = "0.8.3";
|
||||
in
|
||||
{
|
||||
packages.${system} = {
|
||||
|
||||
@@ -211,6 +211,7 @@ type ServiceSpec struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Active bool `protobuf:"varint,2,opt,name=active,proto3" json:"active,omitempty"`
|
||||
Components []*ComponentSpec `protobuf:"bytes,3,rep,name=components,proto3" json:"components,omitempty"`
|
||||
Comment string `protobuf:"bytes,4,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -266,6 +267,13 @@ func (x *ServiceSpec) GetComponents() []*ComponentSpec {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ServiceSpec) GetComment() string {
|
||||
if x != nil {
|
||||
return x.Comment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type DeployRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Service *ServiceSpec `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
|
||||
@@ -426,6 +434,7 @@ func (x *ComponentResult) GetError() string {
|
||||
type StopServiceRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -467,6 +476,13 @@ func (x *StopServiceRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *StopServiceRequest) GetComponent() string {
|
||||
if x != nil {
|
||||
return x.Component
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type StopServiceResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Results []*ComponentResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
|
||||
@@ -514,6 +530,7 @@ func (x *StopServiceResponse) GetResults() []*ComponentResult {
|
||||
type StartServiceRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -555,6 +572,13 @@ func (x *StartServiceRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *StartServiceRequest) GetComponent() string {
|
||||
if x != nil {
|
||||
return x.Component
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type StartServiceResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Results []*ComponentResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
|
||||
@@ -602,6 +626,7 @@ func (x *StartServiceResponse) GetResults() []*ComponentResult {
|
||||
type RestartServiceRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Component string `protobuf:"bytes,2,opt,name=component,proto3" json:"component,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -643,6 +668,13 @@ func (x *RestartServiceRequest) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *RestartServiceRequest) GetComponent() string {
|
||||
if x != nil {
|
||||
return x.Component
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RestartServiceResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Results []*ComponentResult `protobuf:"bytes,1,rep,name=results,proto3" json:"results,omitempty"`
|
||||
@@ -966,6 +998,7 @@ type ServiceInfo struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Active bool `protobuf:"varint,2,opt,name=active,proto3" json:"active,omitempty"`
|
||||
Components []*ComponentInfo `protobuf:"bytes,3,rep,name=components,proto3" json:"components,omitempty"`
|
||||
Comment string `protobuf:"bytes,4,opt,name=comment,proto3" json:"comment,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -1021,6 +1054,13 @@ func (x *ServiceInfo) GetComponents() []*ComponentInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ServiceInfo) GetComment() string {
|
||||
if x != nil {
|
||||
return x.Comment
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ComponentInfo struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
@@ -2815,6 +2855,8 @@ type AddProxyRouteRequest struct {
|
||||
Backend string `protobuf:"bytes,3,opt,name=backend,proto3" json:"backend,omitempty"`
|
||||
Mode string `protobuf:"bytes,4,opt,name=mode,proto3" json:"mode,omitempty"` // "l4" or "l7"
|
||||
BackendTls bool `protobuf:"varint,5,opt,name=backend_tls,json=backendTls,proto3" json:"backend_tls,omitempty"`
|
||||
TlsCert string `protobuf:"bytes,6,opt,name=tls_cert,json=tlsCert,proto3" json:"tls_cert,omitempty"` // path to TLS cert (required for l7)
|
||||
TlsKey string `protobuf:"bytes,7,opt,name=tls_key,json=tlsKey,proto3" json:"tls_key,omitempty"` // path to TLS key (required for l7)
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -2884,6 +2926,20 @@ func (x *AddProxyRouteRequest) GetBackendTls() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *AddProxyRouteRequest) GetTlsCert() string {
|
||||
if x != nil {
|
||||
return x.TlsCert
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *AddProxyRouteRequest) GetTlsKey() string {
|
||||
if x != nil {
|
||||
return x.TlsKey
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type AddProxyRouteResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
@@ -3008,6 +3064,434 @@ func (*RemoveProxyRouteResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{52}
|
||||
}
|
||||
|
||||
type SetupEdgeRouteRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"` // public hostname (e.g. "mcq.metacircular.net")
|
||||
BackendHostname string `protobuf:"bytes,2,opt,name=backend_hostname,json=backendHostname,proto3" json:"backend_hostname,omitempty"` // internal .svc.mcp hostname
|
||||
BackendPort int32 `protobuf:"varint,3,opt,name=backend_port,json=backendPort,proto3" json:"backend_port,omitempty"` // port on worker's mc-proxy
|
||||
BackendTls bool `protobuf:"varint,4,opt,name=backend_tls,json=backendTls,proto3" json:"backend_tls,omitempty"` // MUST be true; agent rejects false
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) Reset() {
|
||||
*x = SetupEdgeRouteRequest{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[53]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetupEdgeRouteRequest) ProtoMessage() {}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[53]
|
||||
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 SetupEdgeRouteRequest.ProtoReflect.Descriptor instead.
|
||||
func (*SetupEdgeRouteRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{53}
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) GetHostname() string {
|
||||
if x != nil {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) GetBackendHostname() string {
|
||||
if x != nil {
|
||||
return x.BackendHostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) GetBackendPort() int32 {
|
||||
if x != nil {
|
||||
return x.BackendPort
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteRequest) GetBackendTls() bool {
|
||||
if x != nil {
|
||||
return x.BackendTls
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type SetupEdgeRouteResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteResponse) Reset() {
|
||||
*x = SetupEdgeRouteResponse{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[54]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *SetupEdgeRouteResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SetupEdgeRouteResponse) ProtoMessage() {}
|
||||
|
||||
func (x *SetupEdgeRouteResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[54]
|
||||
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 SetupEdgeRouteResponse.ProtoReflect.Descriptor instead.
|
||||
func (*SetupEdgeRouteResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{54}
|
||||
}
|
||||
|
||||
type RemoveEdgeRouteRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveEdgeRouteRequest) Reset() {
|
||||
*x = RemoveEdgeRouteRequest{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[55]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveEdgeRouteRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveEdgeRouteRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveEdgeRouteRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[55]
|
||||
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 RemoveEdgeRouteRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveEdgeRouteRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{55}
|
||||
}
|
||||
|
||||
func (x *RemoveEdgeRouteRequest) GetHostname() string {
|
||||
if x != nil {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type RemoveEdgeRouteResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *RemoveEdgeRouteResponse) Reset() {
|
||||
*x = RemoveEdgeRouteResponse{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[56]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *RemoveEdgeRouteResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*RemoveEdgeRouteResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RemoveEdgeRouteResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[56]
|
||||
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 RemoveEdgeRouteResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RemoveEdgeRouteResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{56}
|
||||
}
|
||||
|
||||
type ListEdgeRoutesRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListEdgeRoutesRequest) Reset() {
|
||||
*x = ListEdgeRoutesRequest{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[57]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListEdgeRoutesRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListEdgeRoutesRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListEdgeRoutesRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[57]
|
||||
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 ListEdgeRoutesRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListEdgeRoutesRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{57}
|
||||
}
|
||||
|
||||
type ListEdgeRoutesResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Routes []*EdgeRoute `protobuf:"bytes,1,rep,name=routes,proto3" json:"routes,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ListEdgeRoutesResponse) Reset() {
|
||||
*x = ListEdgeRoutesResponse{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[58]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ListEdgeRoutesResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListEdgeRoutesResponse) ProtoMessage() {}
|
||||
|
||||
func (x *ListEdgeRoutesResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[58]
|
||||
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 ListEdgeRoutesResponse.ProtoReflect.Descriptor instead.
|
||||
func (*ListEdgeRoutesResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{58}
|
||||
}
|
||||
|
||||
func (x *ListEdgeRoutesResponse) GetRoutes() []*EdgeRoute {
|
||||
if x != nil {
|
||||
return x.Routes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EdgeRoute struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Hostname string `protobuf:"bytes,1,opt,name=hostname,proto3" json:"hostname,omitempty"`
|
||||
BackendHostname string `protobuf:"bytes,2,opt,name=backend_hostname,json=backendHostname,proto3" json:"backend_hostname,omitempty"`
|
||||
BackendPort int32 `protobuf:"varint,3,opt,name=backend_port,json=backendPort,proto3" json:"backend_port,omitempty"`
|
||||
CertSerial string `protobuf:"bytes,4,opt,name=cert_serial,json=certSerial,proto3" json:"cert_serial,omitempty"`
|
||||
CertExpires string `protobuf:"bytes,5,opt,name=cert_expires,json=certExpires,proto3" json:"cert_expires,omitempty"` // RFC3339
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) Reset() {
|
||||
*x = EdgeRoute{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[59]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EdgeRoute) ProtoMessage() {}
|
||||
|
||||
func (x *EdgeRoute) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[59]
|
||||
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 EdgeRoute.ProtoReflect.Descriptor instead.
|
||||
func (*EdgeRoute) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{59}
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) GetHostname() string {
|
||||
if x != nil {
|
||||
return x.Hostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) GetBackendHostname() string {
|
||||
if x != nil {
|
||||
return x.BackendHostname
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) GetBackendPort() int32 {
|
||||
if x != nil {
|
||||
return x.BackendPort
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) GetCertSerial() string {
|
||||
if x != nil {
|
||||
return x.CertSerial
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EdgeRoute) GetCertExpires() string {
|
||||
if x != nil {
|
||||
return x.CertExpires
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type HealthCheckRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HealthCheckRequest) Reset() {
|
||||
*x = HealthCheckRequest{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[60]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *HealthCheckRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HealthCheckRequest) ProtoMessage() {}
|
||||
|
||||
func (x *HealthCheckRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[60]
|
||||
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 HealthCheckRequest.ProtoReflect.Descriptor instead.
|
||||
func (*HealthCheckRequest) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{60}
|
||||
}
|
||||
|
||||
type HealthCheckResponse struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` // "healthy" or "degraded"
|
||||
Containers int32 `protobuf:"varint,2,opt,name=containers,proto3" json:"containers,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HealthCheckResponse) Reset() {
|
||||
*x = HealthCheckResponse{}
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[61]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *HealthCheckResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HealthCheckResponse) ProtoMessage() {}
|
||||
|
||||
func (x *HealthCheckResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_proto_mcp_v1_mcp_proto_msgTypes[61]
|
||||
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 HealthCheckResponse.ProtoReflect.Descriptor instead.
|
||||
func (*HealthCheckResponse) Descriptor() ([]byte, []int) {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescGZIP(), []int{61}
|
||||
}
|
||||
|
||||
func (x *HealthCheckResponse) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HealthCheckResponse) GetContainers() int32 {
|
||||
if x != nil {
|
||||
return x.Containers
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_proto_mcp_v1_mcp_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
@@ -3029,13 +3513,14 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
"\x03cmd\x18\b \x03(\tR\x03cmd\x12)\n" +
|
||||
"\x06routes\x18\t \x03(\v2\x11.mcp.v1.RouteSpecR\x06routes\x12\x10\n" +
|
||||
"\x03env\x18\n" +
|
||||
" \x03(\tR\x03env\"p\n" +
|
||||
" \x03(\tR\x03env\"\x8a\x01\n" +
|
||||
"\vServiceSpec\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" +
|
||||
"\x06active\x18\x02 \x01(\bR\x06active\x125\n" +
|
||||
"\n" +
|
||||
"components\x18\x03 \x03(\v2\x15.mcp.v1.ComponentSpecR\n" +
|
||||
"components\"\\\n" +
|
||||
"components\x12\x18\n" +
|
||||
"\acomment\x18\x04 \x01(\tR\acomment\"\\\n" +
|
||||
"\rDeployRequest\x12-\n" +
|
||||
"\aservice\x18\x01 \x01(\v2\x13.mcp.v1.ServiceSpecR\aservice\x12\x1c\n" +
|
||||
"\tcomponent\x18\x02 \x01(\tR\tcomponent\"C\n" +
|
||||
@@ -3044,17 +3529,20 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
"\x0fComponentResult\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
|
||||
"\asuccess\x18\x02 \x01(\bR\asuccess\x12\x14\n" +
|
||||
"\x05error\x18\x03 \x01(\tR\x05error\"(\n" +
|
||||
"\x05error\x18\x03 \x01(\tR\x05error\"F\n" +
|
||||
"\x12StopServiceRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"H\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" +
|
||||
"\tcomponent\x18\x02 \x01(\tR\tcomponent\"H\n" +
|
||||
"\x13StopServiceResponse\x121\n" +
|
||||
"\aresults\x18\x01 \x03(\v2\x17.mcp.v1.ComponentResultR\aresults\")\n" +
|
||||
"\aresults\x18\x01 \x03(\v2\x17.mcp.v1.ComponentResultR\aresults\"G\n" +
|
||||
"\x13StartServiceRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"I\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" +
|
||||
"\tcomponent\x18\x02 \x01(\tR\tcomponent\"I\n" +
|
||||
"\x14StartServiceResponse\x121\n" +
|
||||
"\aresults\x18\x01 \x03(\v2\x17.mcp.v1.ComponentResultR\aresults\"+\n" +
|
||||
"\aresults\x18\x01 \x03(\v2\x17.mcp.v1.ComponentResultR\aresults\"I\n" +
|
||||
"\x15RestartServiceRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\"K\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1c\n" +
|
||||
"\tcomponent\x18\x02 \x01(\tR\tcomponent\"K\n" +
|
||||
"\x16RestartServiceResponse\x121\n" +
|
||||
"\aresults\x18\x01 \x03(\v2\x17.mcp.v1.ComponentResultR\aresults\",\n" +
|
||||
"\x16UndeployServiceRequest\x12\x12\n" +
|
||||
@@ -3069,13 +3557,14 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" +
|
||||
"\achanged\x18\x02 \x01(\bR\achanged\x12\x18\n" +
|
||||
"\asummary\x18\x03 \x01(\tR\asummary\"\x15\n" +
|
||||
"\x13ListServicesRequest\"p\n" +
|
||||
"\x13ListServicesRequest\"\x8a\x01\n" +
|
||||
"\vServiceInfo\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x16\n" +
|
||||
"\x06active\x18\x02 \x01(\bR\x06active\x125\n" +
|
||||
"\n" +
|
||||
"components\x18\x03 \x03(\v2\x15.mcp.v1.ComponentInfoR\n" +
|
||||
"components\"\xd5\x01\n" +
|
||||
"components\x12\x18\n" +
|
||||
"\acomment\x18\x04 \x01(\tR\acomment\"\xd5\x01\n" +
|
||||
"\rComponentInfo\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" +
|
||||
"\x05image\x18\x02 \x01(\tR\x05image\x12#\n" +
|
||||
@@ -3198,19 +3687,47 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
"\x11total_connections\x18\x02 \x01(\x03R\x10totalConnections\x129\n" +
|
||||
"\n" +
|
||||
"started_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tstartedAt\x127\n" +
|
||||
"\tlisteners\x18\x04 \x03(\v2\x19.mcp.v1.ProxyListenerInfoR\tlisteners\"\xa6\x01\n" +
|
||||
"\tlisteners\x18\x04 \x03(\v2\x19.mcp.v1.ProxyListenerInfoR\tlisteners\"\xda\x01\n" +
|
||||
"\x14AddProxyRouteRequest\x12#\n" +
|
||||
"\rlistener_addr\x18\x01 \x01(\tR\flistenerAddr\x12\x1a\n" +
|
||||
"\bhostname\x18\x02 \x01(\tR\bhostname\x12\x18\n" +
|
||||
"\abackend\x18\x03 \x01(\tR\abackend\x12\x12\n" +
|
||||
"\x04mode\x18\x04 \x01(\tR\x04mode\x12\x1f\n" +
|
||||
"\vbackend_tls\x18\x05 \x01(\bR\n" +
|
||||
"backendTls\"\x17\n" +
|
||||
"backendTls\x12\x19\n" +
|
||||
"\btls_cert\x18\x06 \x01(\tR\atlsCert\x12\x17\n" +
|
||||
"\atls_key\x18\a \x01(\tR\x06tlsKey\"\x17\n" +
|
||||
"\x15AddProxyRouteResponse\"Z\n" +
|
||||
"\x17RemoveProxyRouteRequest\x12#\n" +
|
||||
"\rlistener_addr\x18\x01 \x01(\tR\flistenerAddr\x12\x1a\n" +
|
||||
"\bhostname\x18\x02 \x01(\tR\bhostname\"\x1a\n" +
|
||||
"\x18RemoveProxyRouteResponse2\x92\v\n" +
|
||||
"\x18RemoveProxyRouteResponse\"\xa2\x01\n" +
|
||||
"\x15SetupEdgeRouteRequest\x12\x1a\n" +
|
||||
"\bhostname\x18\x01 \x01(\tR\bhostname\x12)\n" +
|
||||
"\x10backend_hostname\x18\x02 \x01(\tR\x0fbackendHostname\x12!\n" +
|
||||
"\fbackend_port\x18\x03 \x01(\x05R\vbackendPort\x12\x1f\n" +
|
||||
"\vbackend_tls\x18\x04 \x01(\bR\n" +
|
||||
"backendTls\"\x18\n" +
|
||||
"\x16SetupEdgeRouteResponse\"4\n" +
|
||||
"\x16RemoveEdgeRouteRequest\x12\x1a\n" +
|
||||
"\bhostname\x18\x01 \x01(\tR\bhostname\"\x19\n" +
|
||||
"\x17RemoveEdgeRouteResponse\"\x17\n" +
|
||||
"\x15ListEdgeRoutesRequest\"C\n" +
|
||||
"\x16ListEdgeRoutesResponse\x12)\n" +
|
||||
"\x06routes\x18\x01 \x03(\v2\x11.mcp.v1.EdgeRouteR\x06routes\"\xb9\x01\n" +
|
||||
"\tEdgeRoute\x12\x1a\n" +
|
||||
"\bhostname\x18\x01 \x01(\tR\bhostname\x12)\n" +
|
||||
"\x10backend_hostname\x18\x02 \x01(\tR\x0fbackendHostname\x12!\n" +
|
||||
"\fbackend_port\x18\x03 \x01(\x05R\vbackendPort\x12\x1f\n" +
|
||||
"\vcert_serial\x18\x04 \x01(\tR\n" +
|
||||
"certSerial\x12!\n" +
|
||||
"\fcert_expires\x18\x05 \x01(\tR\vcertExpires\"\x14\n" +
|
||||
"\x12HealthCheckRequest\"M\n" +
|
||||
"\x13HealthCheckResponse\x12\x16\n" +
|
||||
"\x06status\x18\x01 \x01(\tR\x06status\x12\x1e\n" +
|
||||
"\n" +
|
||||
"containers\x18\x02 \x01(\x05R\n" +
|
||||
"containers2\xd0\r\n" +
|
||||
"\x0fMcpAgentService\x127\n" +
|
||||
"\x06Deploy\x12\x15.mcp.v1.DeployRequest\x1a\x16.mcp.v1.DeployResponse\x12R\n" +
|
||||
"\x0fUndeployService\x12\x1e.mcp.v1.UndeployServiceRequest\x1a\x1f.mcp.v1.UndeployServiceResponse\x12F\n" +
|
||||
@@ -3230,7 +3747,11 @@ const file_proto_mcp_v1_mcp_proto_rawDesc = "" +
|
||||
"\x0eListDNSRecords\x12\x1d.mcp.v1.ListDNSRecordsRequest\x1a\x1e.mcp.v1.ListDNSRecordsResponse\x12R\n" +
|
||||
"\x0fListProxyRoutes\x12\x1e.mcp.v1.ListProxyRoutesRequest\x1a\x1f.mcp.v1.ListProxyRoutesResponse\x12L\n" +
|
||||
"\rAddProxyRoute\x12\x1c.mcp.v1.AddProxyRouteRequest\x1a\x1d.mcp.v1.AddProxyRouteResponse\x12U\n" +
|
||||
"\x10RemoveProxyRoute\x12\x1f.mcp.v1.RemoveProxyRouteRequest\x1a .mcp.v1.RemoveProxyRouteResponse\x123\n" +
|
||||
"\x10RemoveProxyRoute\x12\x1f.mcp.v1.RemoveProxyRouteRequest\x1a .mcp.v1.RemoveProxyRouteResponse\x12O\n" +
|
||||
"\x0eSetupEdgeRoute\x12\x1d.mcp.v1.SetupEdgeRouteRequest\x1a\x1e.mcp.v1.SetupEdgeRouteResponse\x12R\n" +
|
||||
"\x0fRemoveEdgeRoute\x12\x1e.mcp.v1.RemoveEdgeRouteRequest\x1a\x1f.mcp.v1.RemoveEdgeRouteResponse\x12O\n" +
|
||||
"\x0eListEdgeRoutes\x12\x1d.mcp.v1.ListEdgeRoutesRequest\x1a\x1e.mcp.v1.ListEdgeRoutesResponse\x12F\n" +
|
||||
"\vHealthCheck\x12\x1a.mcp.v1.HealthCheckRequest\x1a\x1b.mcp.v1.HealthCheckResponse\x123\n" +
|
||||
"\x04Logs\x12\x13.mcp.v1.LogsRequest\x1a\x14.mcp.v1.LogsResponse0\x01B*Z(git.wntrmute.dev/mc/mcp/gen/mcp/v1;mcpv1b\x06proto3"
|
||||
|
||||
var (
|
||||
@@ -3245,7 +3766,7 @@ func file_proto_mcp_v1_mcp_proto_rawDescGZIP() []byte {
|
||||
return file_proto_mcp_v1_mcp_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_proto_mcp_v1_mcp_proto_msgTypes = make([]protoimpl.MessageInfo, 53)
|
||||
var file_proto_mcp_v1_mcp_proto_msgTypes = make([]protoimpl.MessageInfo, 62)
|
||||
var file_proto_mcp_v1_mcp_proto_goTypes = []any{
|
||||
(*RouteSpec)(nil), // 0: mcp.v1.RouteSpec
|
||||
(*ComponentSpec)(nil), // 1: mcp.v1.ComponentSpec
|
||||
@@ -3300,7 +3821,16 @@ var file_proto_mcp_v1_mcp_proto_goTypes = []any{
|
||||
(*AddProxyRouteResponse)(nil), // 50: mcp.v1.AddProxyRouteResponse
|
||||
(*RemoveProxyRouteRequest)(nil), // 51: mcp.v1.RemoveProxyRouteRequest
|
||||
(*RemoveProxyRouteResponse)(nil), // 52: mcp.v1.RemoveProxyRouteResponse
|
||||
(*timestamppb.Timestamp)(nil), // 53: google.protobuf.Timestamp
|
||||
(*SetupEdgeRouteRequest)(nil), // 53: mcp.v1.SetupEdgeRouteRequest
|
||||
(*SetupEdgeRouteResponse)(nil), // 54: mcp.v1.SetupEdgeRouteResponse
|
||||
(*RemoveEdgeRouteRequest)(nil), // 55: mcp.v1.RemoveEdgeRouteRequest
|
||||
(*RemoveEdgeRouteResponse)(nil), // 56: mcp.v1.RemoveEdgeRouteResponse
|
||||
(*ListEdgeRoutesRequest)(nil), // 57: mcp.v1.ListEdgeRoutesRequest
|
||||
(*ListEdgeRoutesResponse)(nil), // 58: mcp.v1.ListEdgeRoutesResponse
|
||||
(*EdgeRoute)(nil), // 59: mcp.v1.EdgeRoute
|
||||
(*HealthCheckRequest)(nil), // 60: mcp.v1.HealthCheckRequest
|
||||
(*HealthCheckResponse)(nil), // 61: mcp.v1.HealthCheckResponse
|
||||
(*timestamppb.Timestamp)(nil), // 62: google.protobuf.Timestamp
|
||||
}
|
||||
var file_proto_mcp_v1_mcp_proto_depIdxs = []int32{
|
||||
0, // 0: mcp.v1.ComponentSpec.routes:type_name -> mcp.v1.RouteSpec
|
||||
@@ -3314,64 +3844,73 @@ var file_proto_mcp_v1_mcp_proto_depIdxs = []int32{
|
||||
2, // 8: mcp.v1.SyncDesiredStateRequest.services:type_name -> mcp.v1.ServiceSpec
|
||||
16, // 9: mcp.v1.SyncDesiredStateResponse.results:type_name -> mcp.v1.ServiceSyncResult
|
||||
19, // 10: mcp.v1.ServiceInfo.components:type_name -> mcp.v1.ComponentInfo
|
||||
53, // 11: mcp.v1.ComponentInfo.started:type_name -> google.protobuf.Timestamp
|
||||
62, // 11: mcp.v1.ComponentInfo.started:type_name -> google.protobuf.Timestamp
|
||||
18, // 12: mcp.v1.ListServicesResponse.services:type_name -> mcp.v1.ServiceInfo
|
||||
53, // 13: mcp.v1.EventInfo.timestamp:type_name -> google.protobuf.Timestamp
|
||||
62, // 13: mcp.v1.EventInfo.timestamp:type_name -> google.protobuf.Timestamp
|
||||
18, // 14: mcp.v1.GetServiceStatusResponse.services:type_name -> mcp.v1.ServiceInfo
|
||||
22, // 15: mcp.v1.GetServiceStatusResponse.drift:type_name -> mcp.v1.DriftInfo
|
||||
23, // 16: mcp.v1.GetServiceStatusResponse.recent_events:type_name -> mcp.v1.EventInfo
|
||||
18, // 17: mcp.v1.LiveCheckResponse.services:type_name -> mcp.v1.ServiceInfo
|
||||
28, // 18: mcp.v1.AdoptContainersResponse.results:type_name -> mcp.v1.AdoptResult
|
||||
53, // 19: mcp.v1.NodeStatusResponse.uptime_since:type_name -> google.protobuf.Timestamp
|
||||
62, // 19: mcp.v1.NodeStatusResponse.uptime_since:type_name -> google.protobuf.Timestamp
|
||||
38, // 20: mcp.v1.PurgeResponse.results:type_name -> mcp.v1.PurgeResult
|
||||
43, // 21: mcp.v1.DNSZone.records:type_name -> mcp.v1.DNSRecord
|
||||
42, // 22: mcp.v1.ListDNSRecordsResponse.zones:type_name -> mcp.v1.DNSZone
|
||||
46, // 23: mcp.v1.ProxyListenerInfo.routes:type_name -> mcp.v1.ProxyRouteInfo
|
||||
53, // 24: mcp.v1.ListProxyRoutesResponse.started_at:type_name -> google.protobuf.Timestamp
|
||||
62, // 24: mcp.v1.ListProxyRoutesResponse.started_at:type_name -> google.protobuf.Timestamp
|
||||
47, // 25: mcp.v1.ListProxyRoutesResponse.listeners:type_name -> mcp.v1.ProxyListenerInfo
|
||||
3, // 26: mcp.v1.McpAgentService.Deploy:input_type -> mcp.v1.DeployRequest
|
||||
12, // 27: mcp.v1.McpAgentService.UndeployService:input_type -> mcp.v1.UndeployServiceRequest
|
||||
6, // 28: mcp.v1.McpAgentService.StopService:input_type -> mcp.v1.StopServiceRequest
|
||||
8, // 29: mcp.v1.McpAgentService.StartService:input_type -> mcp.v1.StartServiceRequest
|
||||
10, // 30: mcp.v1.McpAgentService.RestartService:input_type -> mcp.v1.RestartServiceRequest
|
||||
14, // 31: mcp.v1.McpAgentService.SyncDesiredState:input_type -> mcp.v1.SyncDesiredStateRequest
|
||||
17, // 32: mcp.v1.McpAgentService.ListServices:input_type -> mcp.v1.ListServicesRequest
|
||||
21, // 33: mcp.v1.McpAgentService.GetServiceStatus:input_type -> mcp.v1.GetServiceStatusRequest
|
||||
25, // 34: mcp.v1.McpAgentService.LiveCheck:input_type -> mcp.v1.LiveCheckRequest
|
||||
27, // 35: mcp.v1.McpAgentService.AdoptContainers:input_type -> mcp.v1.AdoptContainersRequest
|
||||
36, // 36: mcp.v1.McpAgentService.PurgeComponent:input_type -> mcp.v1.PurgeRequest
|
||||
30, // 37: mcp.v1.McpAgentService.PushFile:input_type -> mcp.v1.PushFileRequest
|
||||
32, // 38: mcp.v1.McpAgentService.PullFile:input_type -> mcp.v1.PullFileRequest
|
||||
34, // 39: mcp.v1.McpAgentService.NodeStatus:input_type -> mcp.v1.NodeStatusRequest
|
||||
41, // 40: mcp.v1.McpAgentService.ListDNSRecords:input_type -> mcp.v1.ListDNSRecordsRequest
|
||||
45, // 41: mcp.v1.McpAgentService.ListProxyRoutes:input_type -> mcp.v1.ListProxyRoutesRequest
|
||||
49, // 42: mcp.v1.McpAgentService.AddProxyRoute:input_type -> mcp.v1.AddProxyRouteRequest
|
||||
51, // 43: mcp.v1.McpAgentService.RemoveProxyRoute:input_type -> mcp.v1.RemoveProxyRouteRequest
|
||||
39, // 44: mcp.v1.McpAgentService.Logs:input_type -> mcp.v1.LogsRequest
|
||||
4, // 45: mcp.v1.McpAgentService.Deploy:output_type -> mcp.v1.DeployResponse
|
||||
13, // 46: mcp.v1.McpAgentService.UndeployService:output_type -> mcp.v1.UndeployServiceResponse
|
||||
7, // 47: mcp.v1.McpAgentService.StopService:output_type -> mcp.v1.StopServiceResponse
|
||||
9, // 48: mcp.v1.McpAgentService.StartService:output_type -> mcp.v1.StartServiceResponse
|
||||
11, // 49: mcp.v1.McpAgentService.RestartService:output_type -> mcp.v1.RestartServiceResponse
|
||||
15, // 50: mcp.v1.McpAgentService.SyncDesiredState:output_type -> mcp.v1.SyncDesiredStateResponse
|
||||
20, // 51: mcp.v1.McpAgentService.ListServices:output_type -> mcp.v1.ListServicesResponse
|
||||
24, // 52: mcp.v1.McpAgentService.GetServiceStatus:output_type -> mcp.v1.GetServiceStatusResponse
|
||||
26, // 53: mcp.v1.McpAgentService.LiveCheck:output_type -> mcp.v1.LiveCheckResponse
|
||||
29, // 54: mcp.v1.McpAgentService.AdoptContainers:output_type -> mcp.v1.AdoptContainersResponse
|
||||
37, // 55: mcp.v1.McpAgentService.PurgeComponent:output_type -> mcp.v1.PurgeResponse
|
||||
31, // 56: mcp.v1.McpAgentService.PushFile:output_type -> mcp.v1.PushFileResponse
|
||||
33, // 57: mcp.v1.McpAgentService.PullFile:output_type -> mcp.v1.PullFileResponse
|
||||
35, // 58: mcp.v1.McpAgentService.NodeStatus:output_type -> mcp.v1.NodeStatusResponse
|
||||
44, // 59: mcp.v1.McpAgentService.ListDNSRecords:output_type -> mcp.v1.ListDNSRecordsResponse
|
||||
48, // 60: mcp.v1.McpAgentService.ListProxyRoutes:output_type -> mcp.v1.ListProxyRoutesResponse
|
||||
50, // 61: mcp.v1.McpAgentService.AddProxyRoute:output_type -> mcp.v1.AddProxyRouteResponse
|
||||
52, // 62: mcp.v1.McpAgentService.RemoveProxyRoute:output_type -> mcp.v1.RemoveProxyRouteResponse
|
||||
40, // 63: mcp.v1.McpAgentService.Logs:output_type -> mcp.v1.LogsResponse
|
||||
45, // [45:64] is the sub-list for method output_type
|
||||
26, // [26:45] is the sub-list for method input_type
|
||||
26, // [26:26] is the sub-list for extension type_name
|
||||
26, // [26:26] is the sub-list for extension extendee
|
||||
0, // [0:26] is the sub-list for field type_name
|
||||
59, // 26: mcp.v1.ListEdgeRoutesResponse.routes:type_name -> mcp.v1.EdgeRoute
|
||||
3, // 27: mcp.v1.McpAgentService.Deploy:input_type -> mcp.v1.DeployRequest
|
||||
12, // 28: mcp.v1.McpAgentService.UndeployService:input_type -> mcp.v1.UndeployServiceRequest
|
||||
6, // 29: mcp.v1.McpAgentService.StopService:input_type -> mcp.v1.StopServiceRequest
|
||||
8, // 30: mcp.v1.McpAgentService.StartService:input_type -> mcp.v1.StartServiceRequest
|
||||
10, // 31: mcp.v1.McpAgentService.RestartService:input_type -> mcp.v1.RestartServiceRequest
|
||||
14, // 32: mcp.v1.McpAgentService.SyncDesiredState:input_type -> mcp.v1.SyncDesiredStateRequest
|
||||
17, // 33: mcp.v1.McpAgentService.ListServices:input_type -> mcp.v1.ListServicesRequest
|
||||
21, // 34: mcp.v1.McpAgentService.GetServiceStatus:input_type -> mcp.v1.GetServiceStatusRequest
|
||||
25, // 35: mcp.v1.McpAgentService.LiveCheck:input_type -> mcp.v1.LiveCheckRequest
|
||||
27, // 36: mcp.v1.McpAgentService.AdoptContainers:input_type -> mcp.v1.AdoptContainersRequest
|
||||
36, // 37: mcp.v1.McpAgentService.PurgeComponent:input_type -> mcp.v1.PurgeRequest
|
||||
30, // 38: mcp.v1.McpAgentService.PushFile:input_type -> mcp.v1.PushFileRequest
|
||||
32, // 39: mcp.v1.McpAgentService.PullFile:input_type -> mcp.v1.PullFileRequest
|
||||
34, // 40: mcp.v1.McpAgentService.NodeStatus:input_type -> mcp.v1.NodeStatusRequest
|
||||
41, // 41: mcp.v1.McpAgentService.ListDNSRecords:input_type -> mcp.v1.ListDNSRecordsRequest
|
||||
45, // 42: mcp.v1.McpAgentService.ListProxyRoutes:input_type -> mcp.v1.ListProxyRoutesRequest
|
||||
49, // 43: mcp.v1.McpAgentService.AddProxyRoute:input_type -> mcp.v1.AddProxyRouteRequest
|
||||
51, // 44: mcp.v1.McpAgentService.RemoveProxyRoute:input_type -> mcp.v1.RemoveProxyRouteRequest
|
||||
53, // 45: mcp.v1.McpAgentService.SetupEdgeRoute:input_type -> mcp.v1.SetupEdgeRouteRequest
|
||||
55, // 46: mcp.v1.McpAgentService.RemoveEdgeRoute:input_type -> mcp.v1.RemoveEdgeRouteRequest
|
||||
57, // 47: mcp.v1.McpAgentService.ListEdgeRoutes:input_type -> mcp.v1.ListEdgeRoutesRequest
|
||||
60, // 48: mcp.v1.McpAgentService.HealthCheck:input_type -> mcp.v1.HealthCheckRequest
|
||||
39, // 49: mcp.v1.McpAgentService.Logs:input_type -> mcp.v1.LogsRequest
|
||||
4, // 50: mcp.v1.McpAgentService.Deploy:output_type -> mcp.v1.DeployResponse
|
||||
13, // 51: mcp.v1.McpAgentService.UndeployService:output_type -> mcp.v1.UndeployServiceResponse
|
||||
7, // 52: mcp.v1.McpAgentService.StopService:output_type -> mcp.v1.StopServiceResponse
|
||||
9, // 53: mcp.v1.McpAgentService.StartService:output_type -> mcp.v1.StartServiceResponse
|
||||
11, // 54: mcp.v1.McpAgentService.RestartService:output_type -> mcp.v1.RestartServiceResponse
|
||||
15, // 55: mcp.v1.McpAgentService.SyncDesiredState:output_type -> mcp.v1.SyncDesiredStateResponse
|
||||
20, // 56: mcp.v1.McpAgentService.ListServices:output_type -> mcp.v1.ListServicesResponse
|
||||
24, // 57: mcp.v1.McpAgentService.GetServiceStatus:output_type -> mcp.v1.GetServiceStatusResponse
|
||||
26, // 58: mcp.v1.McpAgentService.LiveCheck:output_type -> mcp.v1.LiveCheckResponse
|
||||
29, // 59: mcp.v1.McpAgentService.AdoptContainers:output_type -> mcp.v1.AdoptContainersResponse
|
||||
37, // 60: mcp.v1.McpAgentService.PurgeComponent:output_type -> mcp.v1.PurgeResponse
|
||||
31, // 61: mcp.v1.McpAgentService.PushFile:output_type -> mcp.v1.PushFileResponse
|
||||
33, // 62: mcp.v1.McpAgentService.PullFile:output_type -> mcp.v1.PullFileResponse
|
||||
35, // 63: mcp.v1.McpAgentService.NodeStatus:output_type -> mcp.v1.NodeStatusResponse
|
||||
44, // 64: mcp.v1.McpAgentService.ListDNSRecords:output_type -> mcp.v1.ListDNSRecordsResponse
|
||||
48, // 65: mcp.v1.McpAgentService.ListProxyRoutes:output_type -> mcp.v1.ListProxyRoutesResponse
|
||||
50, // 66: mcp.v1.McpAgentService.AddProxyRoute:output_type -> mcp.v1.AddProxyRouteResponse
|
||||
52, // 67: mcp.v1.McpAgentService.RemoveProxyRoute:output_type -> mcp.v1.RemoveProxyRouteResponse
|
||||
54, // 68: mcp.v1.McpAgentService.SetupEdgeRoute:output_type -> mcp.v1.SetupEdgeRouteResponse
|
||||
56, // 69: mcp.v1.McpAgentService.RemoveEdgeRoute:output_type -> mcp.v1.RemoveEdgeRouteResponse
|
||||
58, // 70: mcp.v1.McpAgentService.ListEdgeRoutes:output_type -> mcp.v1.ListEdgeRoutesResponse
|
||||
61, // 71: mcp.v1.McpAgentService.HealthCheck:output_type -> mcp.v1.HealthCheckResponse
|
||||
40, // 72: mcp.v1.McpAgentService.Logs:output_type -> mcp.v1.LogsResponse
|
||||
50, // [50:73] is the sub-list for method output_type
|
||||
27, // [27:50] is the sub-list for method input_type
|
||||
27, // [27:27] is the sub-list for extension type_name
|
||||
27, // [27:27] is the sub-list for extension extendee
|
||||
0, // [0:27] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_proto_mcp_v1_mcp_proto_init() }
|
||||
@@ -3385,7 +3924,7 @@ func file_proto_mcp_v1_mcp_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_mcp_v1_mcp_proto_rawDesc), len(file_proto_mcp_v1_mcp_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 53,
|
||||
NumMessages: 62,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -37,6 +37,10 @@ const (
|
||||
McpAgentService_ListProxyRoutes_FullMethodName = "/mcp.v1.McpAgentService/ListProxyRoutes"
|
||||
McpAgentService_AddProxyRoute_FullMethodName = "/mcp.v1.McpAgentService/AddProxyRoute"
|
||||
McpAgentService_RemoveProxyRoute_FullMethodName = "/mcp.v1.McpAgentService/RemoveProxyRoute"
|
||||
McpAgentService_SetupEdgeRoute_FullMethodName = "/mcp.v1.McpAgentService/SetupEdgeRoute"
|
||||
McpAgentService_RemoveEdgeRoute_FullMethodName = "/mcp.v1.McpAgentService/RemoveEdgeRoute"
|
||||
McpAgentService_ListEdgeRoutes_FullMethodName = "/mcp.v1.McpAgentService/ListEdgeRoutes"
|
||||
McpAgentService_HealthCheck_FullMethodName = "/mcp.v1.McpAgentService/HealthCheck"
|
||||
McpAgentService_Logs_FullMethodName = "/mcp.v1.McpAgentService/Logs"
|
||||
)
|
||||
|
||||
@@ -71,6 +75,12 @@ type McpAgentServiceClient interface {
|
||||
ListProxyRoutes(ctx context.Context, in *ListProxyRoutesRequest, opts ...grpc.CallOption) (*ListProxyRoutesResponse, error)
|
||||
AddProxyRoute(ctx context.Context, in *AddProxyRouteRequest, opts ...grpc.CallOption) (*AddProxyRouteResponse, error)
|
||||
RemoveProxyRoute(ctx context.Context, in *RemoveProxyRouteRequest, opts ...grpc.CallOption) (*RemoveProxyRouteResponse, error)
|
||||
// Edge routing (called by master on edge nodes)
|
||||
SetupEdgeRoute(ctx context.Context, in *SetupEdgeRouteRequest, opts ...grpc.CallOption) (*SetupEdgeRouteResponse, error)
|
||||
RemoveEdgeRoute(ctx context.Context, in *RemoveEdgeRouteRequest, opts ...grpc.CallOption) (*RemoveEdgeRouteResponse, error)
|
||||
ListEdgeRoutes(ctx context.Context, in *ListEdgeRoutesRequest, opts ...grpc.CallOption) (*ListEdgeRoutesResponse, error)
|
||||
// Health (called by master on missed heartbeats)
|
||||
HealthCheck(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error)
|
||||
// Logs
|
||||
Logs(ctx context.Context, in *LogsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[LogsResponse], error)
|
||||
}
|
||||
@@ -263,6 +273,46 @@ func (c *mcpAgentServiceClient) RemoveProxyRoute(ctx context.Context, in *Remove
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mcpAgentServiceClient) SetupEdgeRoute(ctx context.Context, in *SetupEdgeRouteRequest, opts ...grpc.CallOption) (*SetupEdgeRouteResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(SetupEdgeRouteResponse)
|
||||
err := c.cc.Invoke(ctx, McpAgentService_SetupEdgeRoute_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mcpAgentServiceClient) RemoveEdgeRoute(ctx context.Context, in *RemoveEdgeRouteRequest, opts ...grpc.CallOption) (*RemoveEdgeRouteResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(RemoveEdgeRouteResponse)
|
||||
err := c.cc.Invoke(ctx, McpAgentService_RemoveEdgeRoute_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mcpAgentServiceClient) ListEdgeRoutes(ctx context.Context, in *ListEdgeRoutesRequest, opts ...grpc.CallOption) (*ListEdgeRoutesResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(ListEdgeRoutesResponse)
|
||||
err := c.cc.Invoke(ctx, McpAgentService_ListEdgeRoutes_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mcpAgentServiceClient) HealthCheck(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(HealthCheckResponse)
|
||||
err := c.cc.Invoke(ctx, McpAgentService_HealthCheck_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *mcpAgentServiceClient) Logs(ctx context.Context, in *LogsRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[LogsResponse], error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
stream, err := c.cc.NewStream(ctx, &McpAgentService_ServiceDesc.Streams[0], McpAgentService_Logs_FullMethodName, cOpts...)
|
||||
@@ -313,6 +363,12 @@ type McpAgentServiceServer interface {
|
||||
ListProxyRoutes(context.Context, *ListProxyRoutesRequest) (*ListProxyRoutesResponse, error)
|
||||
AddProxyRoute(context.Context, *AddProxyRouteRequest) (*AddProxyRouteResponse, error)
|
||||
RemoveProxyRoute(context.Context, *RemoveProxyRouteRequest) (*RemoveProxyRouteResponse, error)
|
||||
// Edge routing (called by master on edge nodes)
|
||||
SetupEdgeRoute(context.Context, *SetupEdgeRouteRequest) (*SetupEdgeRouteResponse, error)
|
||||
RemoveEdgeRoute(context.Context, *RemoveEdgeRouteRequest) (*RemoveEdgeRouteResponse, error)
|
||||
ListEdgeRoutes(context.Context, *ListEdgeRoutesRequest) (*ListEdgeRoutesResponse, error)
|
||||
// Health (called by master on missed heartbeats)
|
||||
HealthCheck(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error)
|
||||
// Logs
|
||||
Logs(*LogsRequest, grpc.ServerStreamingServer[LogsResponse]) error
|
||||
mustEmbedUnimplementedMcpAgentServiceServer()
|
||||
@@ -379,6 +435,18 @@ func (UnimplementedMcpAgentServiceServer) AddProxyRoute(context.Context, *AddPro
|
||||
func (UnimplementedMcpAgentServiceServer) RemoveProxyRoute(context.Context, *RemoveProxyRouteRequest) (*RemoveProxyRouteResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveProxyRoute not implemented")
|
||||
}
|
||||
func (UnimplementedMcpAgentServiceServer) SetupEdgeRoute(context.Context, *SetupEdgeRouteRequest) (*SetupEdgeRouteResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method SetupEdgeRoute not implemented")
|
||||
}
|
||||
func (UnimplementedMcpAgentServiceServer) RemoveEdgeRoute(context.Context, *RemoveEdgeRouteRequest) (*RemoveEdgeRouteResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method RemoveEdgeRoute not implemented")
|
||||
}
|
||||
func (UnimplementedMcpAgentServiceServer) ListEdgeRoutes(context.Context, *ListEdgeRoutesRequest) (*ListEdgeRoutesResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method ListEdgeRoutes not implemented")
|
||||
}
|
||||
func (UnimplementedMcpAgentServiceServer) HealthCheck(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "method HealthCheck not implemented")
|
||||
}
|
||||
func (UnimplementedMcpAgentServiceServer) Logs(*LogsRequest, grpc.ServerStreamingServer[LogsResponse]) error {
|
||||
return status.Error(codes.Unimplemented, "method Logs not implemented")
|
||||
}
|
||||
@@ -727,6 +795,78 @@ func _McpAgentService_RemoveProxyRoute_Handler(srv interface{}, ctx context.Cont
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _McpAgentService_SetupEdgeRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetupEdgeRouteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(McpAgentServiceServer).SetupEdgeRoute(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: McpAgentService_SetupEdgeRoute_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(McpAgentServiceServer).SetupEdgeRoute(ctx, req.(*SetupEdgeRouteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _McpAgentService_RemoveEdgeRoute_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(RemoveEdgeRouteRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(McpAgentServiceServer).RemoveEdgeRoute(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: McpAgentService_RemoveEdgeRoute_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(McpAgentServiceServer).RemoveEdgeRoute(ctx, req.(*RemoveEdgeRouteRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _McpAgentService_ListEdgeRoutes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListEdgeRoutesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(McpAgentServiceServer).ListEdgeRoutes(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: McpAgentService_ListEdgeRoutes_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(McpAgentServiceServer).ListEdgeRoutes(ctx, req.(*ListEdgeRoutesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _McpAgentService_HealthCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(HealthCheckRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(McpAgentServiceServer).HealthCheck(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: McpAgentService_HealthCheck_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(McpAgentServiceServer).HealthCheck(ctx, req.(*HealthCheckRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _McpAgentService_Logs_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(LogsRequest)
|
||||
if err := stream.RecvMsg(m); err != nil {
|
||||
@@ -817,6 +957,22 @@ var McpAgentService_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "RemoveProxyRoute",
|
||||
Handler: _McpAgentService_RemoveProxyRoute_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetupEdgeRoute",
|
||||
Handler: _McpAgentService_SetupEdgeRoute_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "RemoveEdgeRoute",
|
||||
Handler: _McpAgentService_RemoveEdgeRoute_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListEdgeRoutes",
|
||||
Handler: _McpAgentService_ListEdgeRoutes_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "HealthCheck",
|
||||
Handler: _McpAgentService_HealthCheck_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
|
||||
196
internal/agent/edge_rpc.go
Normal file
196
internal/agent/edge_rpc.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
mcpv1 "git.wntrmute.dev/mc/mcp/gen/mcp/v1"
|
||||
mcproxy "git.wntrmute.dev/mc/mc-proxy/client/mcproxy"
|
||||
"git.wntrmute.dev/mc/mcp/internal/registry"
|
||||
)
|
||||
|
||||
// SetupEdgeRoute provisions a TLS cert and registers an mc-proxy route for a
|
||||
// public hostname. Called by the master on edge nodes.
|
||||
func (a *Agent) SetupEdgeRoute(ctx context.Context, req *mcpv1.SetupEdgeRouteRequest) (*mcpv1.SetupEdgeRouteResponse, error) {
|
||||
a.Logger.Info("SetupEdgeRoute", "hostname", req.GetHostname(),
|
||||
"backend_hostname", req.GetBackendHostname(), "backend_port", req.GetBackendPort())
|
||||
|
||||
// Validate required fields.
|
||||
if req.GetHostname() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "hostname is required")
|
||||
}
|
||||
if req.GetBackendHostname() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "backend_hostname is required")
|
||||
}
|
||||
if req.GetBackendPort() == 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "backend_port is required")
|
||||
}
|
||||
if !req.GetBackendTls() {
|
||||
return nil, status.Error(codes.InvalidArgument, "backend_tls must be true")
|
||||
}
|
||||
|
||||
if a.Proxy == nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, "mc-proxy not configured")
|
||||
}
|
||||
|
||||
// Resolve the backend hostname to a Tailnet IP.
|
||||
ips, err := net.LookupHost(req.GetBackendHostname())
|
||||
if err != nil || len(ips) == 0 {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "cannot resolve backend_hostname %q: %v", req.GetBackendHostname(), err)
|
||||
}
|
||||
backendIP := ips[0]
|
||||
|
||||
// Validate the resolved IP is a Tailnet address (100.64.0.0/10).
|
||||
ip := net.ParseIP(backendIP)
|
||||
if ip == nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "resolved IP %q is not valid", backendIP)
|
||||
}
|
||||
_, tailnet, _ := net.ParseCIDR("100.64.0.0/10")
|
||||
if !tailnet.Contains(ip) {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "resolved IP %s is not a Tailnet address", backendIP)
|
||||
}
|
||||
|
||||
backend := fmt.Sprintf("%s:%d", backendIP, req.GetBackendPort())
|
||||
|
||||
// Provision TLS cert for the public hostname if cert provisioner is available.
|
||||
certPath := ""
|
||||
keyPath := ""
|
||||
if a.Certs != nil {
|
||||
if err := a.Certs.EnsureCert(ctx, req.GetHostname(), []string{req.GetHostname()}); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "provision cert for %s: %v", req.GetHostname(), err)
|
||||
}
|
||||
certPath = a.Proxy.CertPath(req.GetHostname())
|
||||
keyPath = a.Proxy.KeyPath(req.GetHostname())
|
||||
} else {
|
||||
// No cert provisioner — check if certs already exist on disk.
|
||||
certPath = a.Proxy.CertPath(req.GetHostname())
|
||||
keyPath = a.Proxy.KeyPath(req.GetHostname())
|
||||
if _, err := os.Stat(certPath); err != nil {
|
||||
return nil, status.Errorf(codes.FailedPrecondition, "no cert provisioner and cert not found at %s", certPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Register the L7 route in mc-proxy.
|
||||
route := mcproxy.Route{
|
||||
Hostname: req.GetHostname(),
|
||||
Backend: backend,
|
||||
Mode: "l7",
|
||||
TLSCert: certPath,
|
||||
TLSKey: keyPath,
|
||||
BackendTLS: true,
|
||||
}
|
||||
if err := a.Proxy.AddRoute(ctx, ":443", route); err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "add mc-proxy route: %v", err)
|
||||
}
|
||||
|
||||
// Persist the edge route in the registry.
|
||||
if err := registry.CreateEdgeRoute(a.DB, req.GetHostname(), req.GetBackendHostname(), int(req.GetBackendPort()), certPath, keyPath); err != nil {
|
||||
a.Logger.Warn("failed to persist edge route", "hostname", req.GetHostname(), "err", err)
|
||||
}
|
||||
|
||||
a.Logger.Info("edge route established",
|
||||
"hostname", req.GetHostname(), "backend", backend, "cert", certPath)
|
||||
|
||||
return &mcpv1.SetupEdgeRouteResponse{}, nil
|
||||
}
|
||||
|
||||
// RemoveEdgeRoute removes an mc-proxy route and cleans up the TLS cert for a
|
||||
// public hostname. Called by the master on edge nodes.
|
||||
func (a *Agent) RemoveEdgeRoute(ctx context.Context, req *mcpv1.RemoveEdgeRouteRequest) (*mcpv1.RemoveEdgeRouteResponse, error) {
|
||||
a.Logger.Info("RemoveEdgeRoute", "hostname", req.GetHostname())
|
||||
|
||||
if req.GetHostname() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "hostname is required")
|
||||
}
|
||||
|
||||
if a.Proxy == nil {
|
||||
return nil, status.Error(codes.FailedPrecondition, "mc-proxy not configured")
|
||||
}
|
||||
|
||||
// Remove the mc-proxy route.
|
||||
if err := a.Proxy.RemoveRoute(ctx, ":443", req.GetHostname()); err != nil {
|
||||
a.Logger.Warn("remove mc-proxy route", "hostname", req.GetHostname(), "err", err)
|
||||
// Continue — clean up cert and registry even if route removal fails.
|
||||
}
|
||||
|
||||
// Remove the TLS cert.
|
||||
if a.Certs != nil {
|
||||
if err := a.Certs.RemoveCert(req.GetHostname()); err != nil {
|
||||
a.Logger.Warn("remove cert", "hostname", req.GetHostname(), "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from registry.
|
||||
if err := registry.DeleteEdgeRoute(a.DB, req.GetHostname()); err != nil {
|
||||
a.Logger.Warn("delete edge route from registry", "hostname", req.GetHostname(), "err", err)
|
||||
}
|
||||
|
||||
a.Logger.Info("edge route removed", "hostname", req.GetHostname())
|
||||
return &mcpv1.RemoveEdgeRouteResponse{}, nil
|
||||
}
|
||||
|
||||
// ListEdgeRoutes returns all edge routes managed by this agent.
|
||||
func (a *Agent) ListEdgeRoutes(_ context.Context, _ *mcpv1.ListEdgeRoutesRequest) (*mcpv1.ListEdgeRoutesResponse, error) {
|
||||
a.Logger.Debug("ListEdgeRoutes called")
|
||||
|
||||
routes, err := registry.ListEdgeRoutes(a.DB)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "list edge routes: %v", err)
|
||||
}
|
||||
|
||||
resp := &mcpv1.ListEdgeRoutesResponse{}
|
||||
for _, r := range routes {
|
||||
er := &mcpv1.EdgeRoute{
|
||||
Hostname: r.Hostname,
|
||||
BackendHostname: r.BackendHostname,
|
||||
BackendPort: int32(r.BackendPort), //nolint:gosec // port is a small positive integer
|
||||
}
|
||||
|
||||
// Read cert metadata if available.
|
||||
if r.TLSCert != "" {
|
||||
if certData, readErr := os.ReadFile(r.TLSCert); readErr == nil { //nolint:gosec // path from registry, not user input
|
||||
if block, _ := pem.Decode(certData); block != nil {
|
||||
if cert, parseErr := x509.ParseCertificate(block.Bytes); parseErr == nil {
|
||||
er.CertSerial = cert.SerialNumber.String()
|
||||
er.CertExpires = cert.NotAfter.UTC().Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resp.Routes = append(resp.Routes, er)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// HealthCheck returns the agent's health status. Called by the master when
|
||||
// heartbeats are missed.
|
||||
func (a *Agent) HealthCheck(_ context.Context, _ *mcpv1.HealthCheckRequest) (*mcpv1.HealthCheckResponse, error) {
|
||||
a.Logger.Debug("HealthCheck called")
|
||||
|
||||
st := "healthy"
|
||||
containers := int32(0)
|
||||
|
||||
// Count running containers if the runtime is available.
|
||||
if a.Runtime != nil {
|
||||
if list, err := a.Runtime.List(context.Background()); err == nil {
|
||||
containers = int32(len(list)) //nolint:gosec // container count is small
|
||||
} else {
|
||||
st = "degraded"
|
||||
}
|
||||
}
|
||||
|
||||
return &mcpv1.HealthCheckResponse{
|
||||
Status: st,
|
||||
Containers: containers,
|
||||
}, nil
|
||||
}
|
||||
@@ -12,9 +12,9 @@ import (
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// StopService stops all components of a service.
|
||||
// StopService stops all components of a service, or a single component if specified.
|
||||
func (a *Agent) StopService(ctx context.Context, req *mcpv1.StopServiceRequest) (*mcpv1.StopServiceResponse, error) {
|
||||
a.Logger.Info("StopService", "service", req.GetName())
|
||||
a.Logger.Info("StopService", "service", req.GetName(), "component", req.GetComponent())
|
||||
|
||||
if req.GetName() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "service name is required")
|
||||
@@ -25,6 +25,13 @@ func (a *Agent) StopService(ctx context.Context, req *mcpv1.StopServiceRequest)
|
||||
return nil, status.Errorf(codes.Internal, "list components: %v", err)
|
||||
}
|
||||
|
||||
if target := req.GetComponent(); target != "" {
|
||||
components, err = filterComponents(components, req.GetName(), target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var results []*mcpv1.ComponentResult
|
||||
for _, c := range components {
|
||||
containerName := ContainerNameFor(req.GetName(), c.Name)
|
||||
@@ -59,10 +66,10 @@ func (a *Agent) StopService(ctx context.Context, req *mcpv1.StopServiceRequest)
|
||||
return &mcpv1.StopServiceResponse{Results: results}, nil
|
||||
}
|
||||
|
||||
// StartService starts all components of a service. If a container already
|
||||
// exists but is stopped, it is removed first so a fresh one can be created.
|
||||
// StartService starts all components of a service, or a single component if specified.
|
||||
// If a container already exists but is stopped, it is removed first so a fresh one can be created.
|
||||
func (a *Agent) StartService(ctx context.Context, req *mcpv1.StartServiceRequest) (*mcpv1.StartServiceResponse, error) {
|
||||
a.Logger.Info("StartService", "service", req.GetName())
|
||||
a.Logger.Info("StartService", "service", req.GetName(), "component", req.GetComponent())
|
||||
|
||||
if req.GetName() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "service name is required")
|
||||
@@ -73,6 +80,13 @@ func (a *Agent) StartService(ctx context.Context, req *mcpv1.StartServiceRequest
|
||||
return nil, status.Errorf(codes.Internal, "list components: %v", err)
|
||||
}
|
||||
|
||||
if target := req.GetComponent(); target != "" {
|
||||
components, err = filterComponents(components, req.GetName(), target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var results []*mcpv1.ComponentResult
|
||||
for _, c := range components {
|
||||
r := startComponent(ctx, a, req.GetName(), &c)
|
||||
@@ -82,10 +96,10 @@ func (a *Agent) StartService(ctx context.Context, req *mcpv1.StartServiceRequest
|
||||
return &mcpv1.StartServiceResponse{Results: results}, nil
|
||||
}
|
||||
|
||||
// RestartService restarts all components of a service by stopping, removing,
|
||||
// and re-creating each container. The desired_state is not changed.
|
||||
// RestartService restarts all components of a service, or a single component if specified,
|
||||
// by stopping, removing, and re-creating each container. The desired_state is not changed.
|
||||
func (a *Agent) RestartService(ctx context.Context, req *mcpv1.RestartServiceRequest) (*mcpv1.RestartServiceResponse, error) {
|
||||
a.Logger.Info("RestartService", "service", req.GetName())
|
||||
a.Logger.Info("RestartService", "service", req.GetName(), "component", req.GetComponent())
|
||||
|
||||
if req.GetName() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "service name is required")
|
||||
@@ -96,6 +110,13 @@ func (a *Agent) RestartService(ctx context.Context, req *mcpv1.RestartServiceReq
|
||||
return nil, status.Errorf(codes.Internal, "list components: %v", err)
|
||||
}
|
||||
|
||||
if target := req.GetComponent(); target != "" {
|
||||
components, err = filterComponents(components, req.GetName(), target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var results []*mcpv1.ComponentResult
|
||||
for _, c := range components {
|
||||
r := restartComponent(ctx, a, req.GetName(), &c)
|
||||
@@ -167,6 +188,16 @@ func componentToSpec(service string, c *registry.Component) runtime.ContainerSpe
|
||||
}
|
||||
}
|
||||
|
||||
// filterComponents returns only the component matching target, or an error if not found.
|
||||
func filterComponents(components []registry.Component, service, target string) ([]registry.Component, error) {
|
||||
for _, c := range components {
|
||||
if c.Name == target {
|
||||
return []registry.Component{c}, nil
|
||||
}
|
||||
}
|
||||
return nil, status.Errorf(codes.NotFound, "component %q not found in service %q", target, service)
|
||||
}
|
||||
|
||||
// componentExists checks whether a component already exists in the registry.
|
||||
func componentExists(db *sql.DB, service, name string) bool {
|
||||
_, err := registry.GetComponent(db, service, name)
|
||||
|
||||
@@ -48,6 +48,16 @@ func (p *ProxyRouter) Close() error {
|
||||
return p.client.Close()
|
||||
}
|
||||
|
||||
// CertPath returns the expected TLS certificate path for a given name.
|
||||
func (p *ProxyRouter) CertPath(name string) string {
|
||||
return filepath.Join(p.certDir, name+".pem")
|
||||
}
|
||||
|
||||
// KeyPath returns the expected TLS key path for a given name.
|
||||
func (p *ProxyRouter) KeyPath(name string) string {
|
||||
return filepath.Join(p.certDir, name+".key")
|
||||
}
|
||||
|
||||
// GetStatus returns the mc-proxy server status.
|
||||
func (p *ProxyRouter) GetStatus(ctx context.Context) (*mcproxy.Status, error) {
|
||||
if p == nil {
|
||||
|
||||
@@ -69,6 +69,8 @@ func (a *Agent) AddProxyRoute(ctx context.Context, req *mcpv1.AddProxyRouteReque
|
||||
Backend: req.GetBackend(),
|
||||
Mode: req.GetMode(),
|
||||
BackendTLS: req.GetBackendTls(),
|
||||
TLSCert: req.GetTlsCert(),
|
||||
TLSKey: req.GetTlsKey(),
|
||||
}
|
||||
|
||||
if err := a.Proxy.AddRoute(ctx, req.GetListenerAddr(), route); err != nil {
|
||||
|
||||
@@ -142,4 +142,18 @@ var migrations = []string{
|
||||
FOREIGN KEY (service, component) REFERENCES components(service, name) ON DELETE CASCADE
|
||||
);
|
||||
`,
|
||||
|
||||
// Migration 3: service comment
|
||||
`ALTER TABLE services ADD COLUMN comment TEXT NOT NULL DEFAULT '';`,
|
||||
|
||||
// Migration 4: edge routes (v2 — public routes managed by the master)
|
||||
`CREATE TABLE IF NOT EXISTS edge_routes (
|
||||
hostname TEXT NOT NULL PRIMARY KEY,
|
||||
backend_hostname TEXT NOT NULL,
|
||||
backend_port INTEGER NOT NULL,
|
||||
tls_cert TEXT NOT NULL DEFAULT '',
|
||||
tls_key TEXT NOT NULL DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);`,
|
||||
}
|
||||
|
||||
93
internal/registry/edge_routes.go
Normal file
93
internal/registry/edge_routes.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package registry
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EdgeRoute represents a public edge route managed by the master.
|
||||
type EdgeRoute struct {
|
||||
Hostname string
|
||||
BackendHostname string
|
||||
BackendPort int
|
||||
TLSCert string
|
||||
TLSKey string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// CreateEdgeRoute inserts or replaces an edge route.
|
||||
func CreateEdgeRoute(db *sql.DB, hostname, backendHostname string, backendPort int, tlsCert, tlsKey string) error {
|
||||
_, err := db.Exec(`
|
||||
INSERT INTO edge_routes (hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, datetime('now'), datetime('now'))
|
||||
ON CONFLICT(hostname) DO UPDATE SET
|
||||
backend_hostname = excluded.backend_hostname,
|
||||
backend_port = excluded.backend_port,
|
||||
tls_cert = excluded.tls_cert,
|
||||
tls_key = excluded.tls_key,
|
||||
updated_at = datetime('now')
|
||||
`, hostname, backendHostname, backendPort, tlsCert, tlsKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create edge route %s: %w", hostname, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetEdgeRoute returns a single edge route by hostname.
|
||||
func GetEdgeRoute(db *sql.DB, hostname string) (*EdgeRoute, error) {
|
||||
var r EdgeRoute
|
||||
var createdAt, updatedAt string
|
||||
err := db.QueryRow(`
|
||||
SELECT hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at
|
||||
FROM edge_routes WHERE hostname = ?
|
||||
`, hostname).Scan(&r.Hostname, &r.BackendHostname, &r.BackendPort, &r.TLSCert, &r.TLSKey, &createdAt, &updatedAt)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get edge route %s: %w", hostname, err)
|
||||
}
|
||||
r.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt)
|
||||
r.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||
return &r, nil
|
||||
}
|
||||
|
||||
// ListEdgeRoutes returns all edge routes.
|
||||
func ListEdgeRoutes(db *sql.DB) ([]*EdgeRoute, error) {
|
||||
rows, err := db.Query(`
|
||||
SELECT hostname, backend_hostname, backend_port, tls_cert, tls_key, created_at, updated_at
|
||||
FROM edge_routes ORDER BY hostname
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list edge routes: %w", err)
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
var routes []*EdgeRoute
|
||||
for rows.Next() {
|
||||
var r EdgeRoute
|
||||
var createdAt, updatedAt string
|
||||
if err := rows.Scan(&r.Hostname, &r.BackendHostname, &r.BackendPort, &r.TLSCert, &r.TLSKey, &createdAt, &updatedAt); err != nil {
|
||||
return nil, fmt.Errorf("scan edge route: %w", err)
|
||||
}
|
||||
r.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", createdAt)
|
||||
r.UpdatedAt, _ = time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||
routes = append(routes, &r)
|
||||
}
|
||||
return routes, rows.Err()
|
||||
}
|
||||
|
||||
// DeleteEdgeRoute removes an edge route by hostname.
|
||||
func DeleteEdgeRoute(db *sql.DB, hostname string) error {
|
||||
result, err := db.Exec(`DELETE FROM edge_routes WHERE hostname = ?`, hostname)
|
||||
if err != nil {
|
||||
return fmt.Errorf("delete edge route %s: %w", hostname, err)
|
||||
}
|
||||
n, _ := result.RowsAffected()
|
||||
if n == 0 {
|
||||
return fmt.Errorf("edge route %s not found", hostname)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -42,6 +42,14 @@ service McpAgentService {
|
||||
rpc AddProxyRoute(AddProxyRouteRequest) returns (AddProxyRouteResponse);
|
||||
rpc RemoveProxyRoute(RemoveProxyRouteRequest) returns (RemoveProxyRouteResponse);
|
||||
|
||||
// Edge routing (called by master on edge nodes)
|
||||
rpc SetupEdgeRoute(SetupEdgeRouteRequest) returns (SetupEdgeRouteResponse);
|
||||
rpc RemoveEdgeRoute(RemoveEdgeRouteRequest) returns (RemoveEdgeRouteResponse);
|
||||
rpc ListEdgeRoutes(ListEdgeRoutesRequest) returns (ListEdgeRoutesResponse);
|
||||
|
||||
// Health (called by master on missed heartbeats)
|
||||
rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);
|
||||
|
||||
// Logs
|
||||
rpc Logs(LogsRequest) returns (stream LogsResponse);
|
||||
}
|
||||
@@ -72,6 +80,7 @@ message ServiceSpec {
|
||||
string name = 1;
|
||||
bool active = 2;
|
||||
repeated ComponentSpec components = 3;
|
||||
string comment = 4;
|
||||
}
|
||||
|
||||
message DeployRequest {
|
||||
@@ -92,6 +101,7 @@ message ComponentResult {
|
||||
|
||||
message StopServiceRequest {
|
||||
string name = 1;
|
||||
string component = 2;
|
||||
}
|
||||
|
||||
message StopServiceResponse {
|
||||
@@ -100,6 +110,7 @@ message StopServiceResponse {
|
||||
|
||||
message StartServiceRequest {
|
||||
string name = 1;
|
||||
string component = 2;
|
||||
}
|
||||
|
||||
message StartServiceResponse {
|
||||
@@ -108,6 +119,7 @@ message StartServiceResponse {
|
||||
|
||||
message RestartServiceRequest {
|
||||
string name = 1;
|
||||
string component = 2;
|
||||
}
|
||||
|
||||
message RestartServiceResponse {
|
||||
@@ -148,6 +160,7 @@ message ServiceInfo {
|
||||
string name = 1;
|
||||
bool active = 2;
|
||||
repeated ComponentInfo components = 3;
|
||||
string comment = 4;
|
||||
}
|
||||
|
||||
message ComponentInfo {
|
||||
@@ -362,6 +375,8 @@ message AddProxyRouteRequest {
|
||||
string backend = 3;
|
||||
string mode = 4; // "l4" or "l7"
|
||||
bool backend_tls = 5;
|
||||
string tls_cert = 6; // path to TLS cert (required for l7)
|
||||
string tls_key = 7; // path to TLS key (required for l7)
|
||||
}
|
||||
|
||||
message AddProxyRouteResponse {}
|
||||
@@ -372,3 +387,43 @@ message RemoveProxyRouteRequest {
|
||||
}
|
||||
|
||||
message RemoveProxyRouteResponse {}
|
||||
|
||||
// --- Edge routes (v2) ---
|
||||
|
||||
message SetupEdgeRouteRequest {
|
||||
string hostname = 1; // public hostname (e.g. "mcq.metacircular.net")
|
||||
string backend_hostname = 2; // internal .svc.mcp hostname
|
||||
int32 backend_port = 3; // port on worker's mc-proxy
|
||||
bool backend_tls = 4; // MUST be true; agent rejects false
|
||||
}
|
||||
|
||||
message SetupEdgeRouteResponse {}
|
||||
|
||||
message RemoveEdgeRouteRequest {
|
||||
string hostname = 1;
|
||||
}
|
||||
|
||||
message RemoveEdgeRouteResponse {}
|
||||
|
||||
message ListEdgeRoutesRequest {}
|
||||
|
||||
message ListEdgeRoutesResponse {
|
||||
repeated EdgeRoute routes = 1;
|
||||
}
|
||||
|
||||
message EdgeRoute {
|
||||
string hostname = 1;
|
||||
string backend_hostname = 2;
|
||||
int32 backend_port = 3;
|
||||
string cert_serial = 4;
|
||||
string cert_expires = 5; // RFC3339
|
||||
}
|
||||
|
||||
// --- Health check (v2) ---
|
||||
|
||||
message HealthCheckRequest {}
|
||||
|
||||
message HealthCheckResponse {
|
||||
string status = 1; // "healthy" or "degraded"
|
||||
int32 containers = 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user