mirror of
https://github.com/MizuchiLabs/mantrae.git
synced 2026-02-11 16:58:45 -06:00
simplify agents
This commit is contained in:
@@ -1,176 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/mizuchilabs/mantrae/pkg/meta"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
"github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1/mantraev1connect"
|
||||
)
|
||||
|
||||
const tokenFile = "data/.mantrae-token"
|
||||
|
||||
type TokenSource struct {
|
||||
mu sync.Mutex
|
||||
client mantraev1connect.AgentServiceClient
|
||||
token string
|
||||
fallback bool
|
||||
}
|
||||
|
||||
func NewTokenSource() *TokenSource {
|
||||
return &TokenSource{fallback: false}
|
||||
}
|
||||
|
||||
// SetToken loads the token from disk or env
|
||||
func (ts *TokenSource) SetToken(ctx context.Context) error {
|
||||
ts.mu.Lock()
|
||||
if ts.token != "" {
|
||||
ts.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Try to load from disk
|
||||
data, err := os.ReadFile(tokenFile)
|
||||
if err == nil {
|
||||
ts.token = strings.TrimSpace(string(data))
|
||||
}
|
||||
|
||||
// Fallback to env
|
||||
if ts.token == "" {
|
||||
ts.token = strings.TrimSpace(os.Getenv("TOKEN"))
|
||||
}
|
||||
if ts.token == "" {
|
||||
ts.mu.Unlock()
|
||||
return errors.New("no token found in environment or file")
|
||||
}
|
||||
|
||||
// Write it back
|
||||
_ = os.MkdirAll("data", 0o755)
|
||||
if err := os.WriteFile(tokenFile, []byte(ts.token), 0o600); err != nil {
|
||||
slog.Warn("could not write token file", "error", err)
|
||||
}
|
||||
ts.mu.Unlock()
|
||||
|
||||
return ts.SetClient()
|
||||
}
|
||||
|
||||
// SetClient initializes the client
|
||||
func (ts *TokenSource) SetClient() error {
|
||||
ts.mu.Lock()
|
||||
if ts.token == "" {
|
||||
ts.mu.Unlock()
|
||||
return errors.New("no token")
|
||||
}
|
||||
|
||||
claims, err := DecodeJWT(ts.token)
|
||||
if err != nil {
|
||||
ts.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
|
||||
ts.client = mantraev1connect.NewAgentServiceClient(
|
||||
http.DefaultClient,
|
||||
claims.ServerURL,
|
||||
connect.WithInterceptors(ts.Interceptor()),
|
||||
)
|
||||
ts.mu.Unlock()
|
||||
|
||||
return ts.Refresh(context.Background()) // Check health
|
||||
}
|
||||
|
||||
// Refresh calls HealthCheck and handles token rotation
|
||||
func (ts *TokenSource) Refresh(ctx context.Context) error {
|
||||
if ts.client == nil {
|
||||
return errors.New("no client")
|
||||
}
|
||||
|
||||
req := connect.NewRequest(&mantraev1.HealthCheckRequest{})
|
||||
req.Header().Set("Authorization", "Bearer "+ts.token)
|
||||
if claims, err := DecodeJWT(ts.token); err == nil {
|
||||
req.Header().Set(meta.HeaderAgentID, claims.AgentID)
|
||||
}
|
||||
|
||||
resp, err := ts.client.HealthCheck(ctx, req)
|
||||
if err != nil {
|
||||
// Try fallback to env after removing token
|
||||
if connect.CodeOf(err) == connect.CodeUnauthenticated {
|
||||
if err := os.Remove(tokenFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if !ts.fallback {
|
||||
ts.fallback = true
|
||||
return ts.SetToken(ctx)
|
||||
}
|
||||
return errors.New("unauthenticated and no fallback $TOKEN available")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown on agent deletion
|
||||
if !resp.Msg.Ok {
|
||||
return errors.New("agent deleted")
|
||||
}
|
||||
|
||||
// Handle token rotation
|
||||
if newToken := resp.Msg.GetToken(); newToken != "" && newToken != ts.token {
|
||||
ts.mu.Lock()
|
||||
ts.token = newToken
|
||||
ts.fallback = false
|
||||
_ = os.WriteFile(tokenFile, []byte(newToken), 0o600)
|
||||
ts.mu.Unlock()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Interceptor injects Authorization header, auto-refreshing on 401.
|
||||
func (ts *TokenSource) Interceptor() connect.UnaryInterceptorFunc {
|
||||
return func(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
||||
if err := ts.SetToken(ctx); err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, err)
|
||||
}
|
||||
req.Header().Set("Authorization", "Bearer "+ts.token)
|
||||
if claims, err := DecodeJWT(ts.token); err == nil {
|
||||
req.Header().Set(meta.HeaderAgentID, claims.AgentID)
|
||||
}
|
||||
|
||||
resp, err := next(ctx, req)
|
||||
if connect.CodeOf(err) == connect.CodeUnauthenticated {
|
||||
ts.mu.Lock()
|
||||
ts.token = ""
|
||||
ts.mu.Unlock()
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TokenSource) GetToken() string {
|
||||
ts.mu.Lock()
|
||||
defer ts.mu.Unlock()
|
||||
return ts.token
|
||||
}
|
||||
|
||||
func (ts *TokenSource) GetClient() mantraev1connect.AgentServiceClient {
|
||||
ts.mu.Lock()
|
||||
defer ts.mu.Unlock()
|
||||
return ts.client
|
||||
}
|
||||
|
||||
func (ts *TokenSource) PrintConnection() {
|
||||
ts.mu.Lock()
|
||||
defer ts.mu.Unlock()
|
||||
if ts.client != nil {
|
||||
claims, err := DecodeJWT(ts.token)
|
||||
if err == nil {
|
||||
slog.Info("Connected", "server", claims.ServerURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
"github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1/mantraev1connect"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
var (
|
||||
tokenDir = "data"
|
||||
tokenPath = tokenDir + "/.mantrae-token"
|
||||
)
|
||||
|
||||
func Client(quit chan os.Signal) {
|
||||
ts := NewTokenSource()
|
||||
if err := ts.SetToken(context.Background()); err != nil {
|
||||
slog.Error("Failed to connect to server", "error", err)
|
||||
return
|
||||
}
|
||||
ts.PrintConnection()
|
||||
|
||||
// Prepare tickers
|
||||
healthTicker := time.NewTicker(15 * time.Second)
|
||||
defer healthTicker.Stop()
|
||||
containerTicker := time.NewTicker(10 * time.Second)
|
||||
defer containerTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-healthTicker.C:
|
||||
if err := ts.Refresh(context.Background()); err != nil {
|
||||
slog.Error("Failed to refresh token", "error", err)
|
||||
return
|
||||
}
|
||||
case <-containerTicker.C:
|
||||
doContainer(ts.client, quit)
|
||||
case <-quit:
|
||||
slog.Info("Shutting down agent...")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doContainer invokes GetContainer using current token/claims
|
||||
func doContainer(
|
||||
client mantraev1connect.AgentServiceClient,
|
||||
quit chan os.Signal,
|
||||
) {
|
||||
// build payload
|
||||
req := sendContainerRequest()
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
_, err := client.GetContainer(context.Background(), req)
|
||||
|
||||
switch connect.CodeOf(err) {
|
||||
case connect.CodeNotFound:
|
||||
slog.Warn("Agent deleted by server, shutting down")
|
||||
quit <- os.Interrupt
|
||||
case connect.CodeInternal:
|
||||
slog.Error("GetContainer server error", "error", err)
|
||||
case connect.CodeUnauthenticated:
|
||||
slog.Warn("Token invalid, will pick up on next health tick")
|
||||
default:
|
||||
if err != nil {
|
||||
slog.Warn("GetContainer error", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendContainer creates a GetContainerRequest with information about the local machine
|
||||
func sendContainerRequest() *connect.Request[mantraev1.GetContainerRequest] {
|
||||
var request mantraev1.GetContainerRequest
|
||||
|
||||
// Get hostname
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
request.Hostname = "unknown"
|
||||
}
|
||||
request.Hostname = hostname
|
||||
request.PublicIp, err = GetPublicIP()
|
||||
if err != nil {
|
||||
slog.Error("Failed to get public IP", "error", err)
|
||||
}
|
||||
request.PrivateIps, err = GetPrivateIP()
|
||||
if err != nil {
|
||||
slog.Error("Failed to get local IP", "error", err)
|
||||
}
|
||||
request.Containers, err = getContainers()
|
||||
if err != nil {
|
||||
slog.Error("Failed to get containers", "error", err)
|
||||
}
|
||||
request.Updated = timestamppb.New(time.Now())
|
||||
|
||||
req := connect.NewRequest(&request)
|
||||
return req
|
||||
}
|
||||
|
||||
// getContainers retrieves all containers and their info on the local machine
|
||||
func getContainers() ([]*mantraev1.Container, error) {
|
||||
// Create a new Docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create Docker client")
|
||||
}
|
||||
|
||||
// Get all containers
|
||||
containers, err := cli.ContainerList(context.Background(), container.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to list containers")
|
||||
}
|
||||
|
||||
var result []*mantraev1.Container
|
||||
portMap := make(map[int32]int32)
|
||||
|
||||
// Iterate over each container and populate the Container struct
|
||||
for _, c := range containers {
|
||||
// Retrieve the container details
|
||||
containerJSON, err := cli.ContainerInspect(context.Background(), c.ID)
|
||||
if err != nil {
|
||||
slog.Error("Failed to inspect container", "container", c.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip Traefik
|
||||
skipTraefik := os.Getenv("SKIP_TRAEFIK")
|
||||
if skipTraefik == "true" {
|
||||
if strings.Contains(strings.ToLower(containerJSON.Config.Image), "traefik") ||
|
||||
(len(c.Names) > 0 && strings.Contains(strings.ToLower(c.Names[0]), "traefik")) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Populate PortInfo
|
||||
for port, bindings := range containerJSON.NetworkSettings.Ports {
|
||||
for _, binding := range bindings {
|
||||
// Get external port
|
||||
externalPort, err := strconv.ParseInt(binding.HostPort, 10, 32)
|
||||
if err != nil {
|
||||
slog.Error(
|
||||
"Failed to parse external port",
|
||||
"port",
|
||||
binding.HostPort,
|
||||
"error",
|
||||
err,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
// Get internal port from the port key
|
||||
internalPort, err := strconv.ParseInt(
|
||||
port.Port(),
|
||||
10,
|
||||
32,
|
||||
) // port is of type nat.Port
|
||||
if err != nil {
|
||||
slog.Error("Failed to parse internal port", "port", port.Port(), "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Map internal port to external port
|
||||
portMap[int32(internalPort)] = int32(externalPort)
|
||||
}
|
||||
}
|
||||
|
||||
created, err := time.Parse(time.RFC3339, containerJSON.Created)
|
||||
if err != nil {
|
||||
slog.Error("Failed to parse created time", "time", containerJSON.Created, "error", err)
|
||||
}
|
||||
|
||||
// Populate the Container struct
|
||||
container := &mantraev1.Container{
|
||||
Id: c.ID,
|
||||
Name: c.Names[0], // Take the first name if multiple exist
|
||||
Labels: containerJSON.Config.Labels,
|
||||
Image: containerJSON.Config.Image,
|
||||
Portmap: portMap,
|
||||
Status: containerJSON.State.Status,
|
||||
Created: timestamppb.New(created),
|
||||
}
|
||||
|
||||
result = append(result, container)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// Public IP APIs
|
||||
var ipAPIs = []string{
|
||||
"https://api.ipify.org?format=text",
|
||||
"https://ifconfig.co/ip",
|
||||
"https://checkip.amazonaws.com",
|
||||
"https://ipinfo.io/ip",
|
||||
}
|
||||
|
||||
func getIP(url string) (string, error) {
|
||||
client := &http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
}
|
||||
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return "", errors.New("non-200 response from API")
|
||||
}
|
||||
|
||||
ip, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(ip), nil
|
||||
}
|
||||
|
||||
func isValidPublicIP(ip string) bool {
|
||||
if ip == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
parsedIP := net.ParseIP(ip)
|
||||
if parsedIP == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if it's a private or loopback IP
|
||||
if parsedIP.IsLoopback() || parsedIP.IsPrivate() {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func GetPublicIP() (string, error) {
|
||||
for _, api := range ipAPIs {
|
||||
ip, err := getIP(api)
|
||||
if err == nil && isValidPublicIP(ip) {
|
||||
return ip, nil
|
||||
}
|
||||
slog.Warn("Failed to query API", "API", api, "Error", err)
|
||||
}
|
||||
return "", fmt.Errorf("failed to get public IP")
|
||||
}
|
||||
|
||||
func GetPrivateIP() ([]string, error) {
|
||||
var ips []string
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
excluded := []string{"lo", "docker", "br-", "veth", "kube", "cni"}
|
||||
for _, iface := range interfaces {
|
||||
if slices.ContainsFunc(excluded, func(s string) bool {
|
||||
return strings.Contains(iface.Name, s)
|
||||
}) || iface.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
} else {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||
if ipnet.IP.To4() != nil {
|
||||
ips = append(ips, ipnet.IP.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ips) == 0 {
|
||||
return nil, errors.New("no private IP addresses found")
|
||||
}
|
||||
|
||||
return ips, nil
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
type Claims struct {
|
||||
AgentID string `json:"agentId,omitempty"`
|
||||
ProfileID int64 `json:"profileId,omitempty"`
|
||||
ServerURL string `json:"serverUrl,omitempty"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func DecodeJWT(tokenString string) (*Claims, error) {
|
||||
// Decode without verifying
|
||||
claims := &Claims{}
|
||||
parser := &jwt.Parser{}
|
||||
_, _, err := parser.ParseUnverified(tokenString, claims)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decode JWT without verification: %w", err)
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
@@ -8,7 +9,7 @@ import (
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/mizuchilabs/mantrae/agent/client"
|
||||
"github.com/mizuchilabs/mantrae/agent/internal/client"
|
||||
"github.com/mizuchilabs/mantrae/pkg/build"
|
||||
"github.com/mizuchilabs/mantrae/pkg/logger"
|
||||
)
|
||||
@@ -29,5 +30,10 @@ func main() {
|
||||
|
||||
logger.Setup()
|
||||
slog.Info("Starting agent...")
|
||||
client.Client(quit)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
go client.Client(ctx, quit)
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
||||
188
agent/internal/client/auth.go
Normal file
188
agent/internal/client/auth.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/mizuchilabs/mantrae/agent/internal/collector"
|
||||
"github.com/mizuchilabs/mantrae/pkg/meta"
|
||||
"github.com/mizuchilabs/mantrae/pkg/util"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
"github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1/mantraev1connect"
|
||||
)
|
||||
|
||||
const tokenFile = "data/.mantrae-token"
|
||||
|
||||
type TokenSource struct {
|
||||
mu sync.Mutex
|
||||
client mantraev1connect.AgentServiceClient
|
||||
token string
|
||||
claims *meta.AgentClaims
|
||||
activeIP string
|
||||
fallback bool
|
||||
}
|
||||
|
||||
func NewTokenSource() *TokenSource {
|
||||
return &TokenSource{fallback: false}
|
||||
}
|
||||
|
||||
// SetToken loads the token from disk or env
|
||||
func (t *TokenSource) SetToken(ctx context.Context) error {
|
||||
t.mu.Lock()
|
||||
if t.token != "" {
|
||||
t.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Try to load from disk
|
||||
data, err := os.ReadFile(tokenFile)
|
||||
if err == nil {
|
||||
t.token = strings.TrimSpace(string(data))
|
||||
}
|
||||
|
||||
// Fallback to env
|
||||
if t.token == "" {
|
||||
t.token = strings.TrimSpace(os.Getenv("TOKEN"))
|
||||
}
|
||||
if t.token == "" {
|
||||
t.mu.Unlock()
|
||||
return errors.New("no token found in environment or file")
|
||||
}
|
||||
|
||||
// Write it back
|
||||
_ = os.MkdirAll("data", 0o755)
|
||||
if err := os.WriteFile(tokenFile, []byte(t.token), 0o600); err != nil {
|
||||
slog.Warn("could not write token file", "error", err)
|
||||
}
|
||||
t.mu.Unlock()
|
||||
|
||||
return t.SetClient()
|
||||
}
|
||||
|
||||
// SetClient initializes the client
|
||||
func (t *TokenSource) SetClient() error {
|
||||
t.mu.Lock()
|
||||
if t.token == "" {
|
||||
t.mu.Unlock()
|
||||
return errors.New("no token")
|
||||
}
|
||||
|
||||
claims, err := util.DecodeUnsafeJWT[*meta.AgentClaims](t.token)
|
||||
if err != nil {
|
||||
t.mu.Unlock()
|
||||
return err
|
||||
}
|
||||
t.claims = claims
|
||||
|
||||
t.client = mantraev1connect.NewAgentServiceClient(
|
||||
http.DefaultClient,
|
||||
claims.ServerURL,
|
||||
connect.WithInterceptors(t.Interceptor()),
|
||||
)
|
||||
t.mu.Unlock()
|
||||
|
||||
return t.Refresh(context.Background()) // Check health
|
||||
}
|
||||
|
||||
// Refresh calls HealthCheck and handles token rotation
|
||||
func (t *TokenSource) Refresh(ctx context.Context) error {
|
||||
if t.client == nil {
|
||||
return errors.New("no client")
|
||||
}
|
||||
|
||||
info := collector.GetMachineInfo()
|
||||
|
||||
req := connect.NewRequest(&mantraev1.HealthCheckRequest{
|
||||
PublicIp: info.PublicIPs.IPv4,
|
||||
PrivateIp: info.PrivateIPs.IPv4,
|
||||
})
|
||||
req.Header().Set("Authorization", "Bearer "+t.token)
|
||||
req.Header().Set(meta.HeaderAgentID, t.claims.AgentID)
|
||||
|
||||
resp, err := t.client.HealthCheck(ctx, req)
|
||||
if err != nil {
|
||||
// Try fallback to env after removing token
|
||||
if connect.CodeOf(err) == connect.CodeUnauthenticated {
|
||||
if err := os.Remove(tokenFile); err != nil {
|
||||
return err
|
||||
}
|
||||
if !t.fallback {
|
||||
t.fallback = true
|
||||
return t.SetToken(ctx)
|
||||
}
|
||||
return errors.New("unauthenticated and no fallback $TOKEN available")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown on agent deletion
|
||||
if resp.Msg.Agent == nil {
|
||||
return errors.New("agent deleted")
|
||||
}
|
||||
|
||||
// Handle token rotation
|
||||
newToken := resp.Msg.Agent.Token
|
||||
if newToken != "" && newToken != t.token {
|
||||
t.mu.Lock()
|
||||
t.token = newToken
|
||||
t.fallback = false
|
||||
_ = os.WriteFile(tokenFile, []byte(newToken), 0o600)
|
||||
t.mu.Unlock()
|
||||
}
|
||||
|
||||
// Handle active IP rotation
|
||||
newIP := resp.Msg.Agent.ActiveIp
|
||||
if newIP != "" && newIP != t.activeIP {
|
||||
t.mu.Lock()
|
||||
t.activeIP = newIP
|
||||
t.mu.Unlock()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Interceptor injects Authorization header, auto-refreshing on 401.
|
||||
func (t *TokenSource) Interceptor() connect.UnaryInterceptorFunc {
|
||||
return func(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
||||
if err := t.SetToken(ctx); err != nil {
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, err)
|
||||
}
|
||||
req.Header().Set("Authorization", "Bearer "+t.token)
|
||||
req.Header().Set(meta.HeaderAgentID, t.claims.AgentID)
|
||||
|
||||
resp, err := next(ctx, req)
|
||||
if connect.CodeOf(err) == connect.CodeUnauthenticated {
|
||||
t.mu.Lock()
|
||||
t.token = ""
|
||||
t.mu.Unlock()
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TokenSource) GetToken() string {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
return t.token
|
||||
}
|
||||
|
||||
func (t *TokenSource) GetClient() mantraev1connect.AgentServiceClient {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
return t.client
|
||||
}
|
||||
|
||||
func (t *TokenSource) PrintConnection() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
if t.client != nil {
|
||||
slog.Info("Connected", "server", t.claims.ServerURL)
|
||||
}
|
||||
}
|
||||
260
agent/internal/client/client.go
Normal file
260
agent/internal/client/client.go
Normal file
@@ -0,0 +1,260 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/mizuchilabs/mantrae/agent/internal/collector"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
"github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1/mantraev1connect"
|
||||
"github.com/traefik/paerser/parser"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
func Client(ctx context.Context, quit chan os.Signal) {
|
||||
t := NewTokenSource()
|
||||
if err := t.SetToken(ctx); err != nil {
|
||||
slog.Error("Failed to connect to server", "error", err)
|
||||
return
|
||||
}
|
||||
t.PrintConnection()
|
||||
|
||||
// Prepare tickers
|
||||
healthTicker := time.NewTicker(15 * time.Second)
|
||||
defer healthTicker.Stop()
|
||||
containerTicker := time.NewTicker(10 * time.Second)
|
||||
defer containerTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-healthTicker.C:
|
||||
if err := t.Refresh(ctx); err != nil {
|
||||
slog.Error("Failed to refresh token", "error", err)
|
||||
return
|
||||
}
|
||||
case <-containerTicker.C:
|
||||
t.Update(ctx)
|
||||
case <-quit:
|
||||
slog.Info("Shutting down agent...")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TokenSource) Update(ctx context.Context) error {
|
||||
containers, err := collector.GetContainers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
routerClient := mantraev1connect.NewRouterServiceClient(
|
||||
http.DefaultClient,
|
||||
t.claims.ServerURL,
|
||||
connect.WithInterceptors(t.Interceptor()),
|
||||
)
|
||||
serviceClient := mantraev1connect.NewServiceServiceClient(
|
||||
http.DefaultClient,
|
||||
t.claims.ServerURL,
|
||||
connect.WithInterceptors(t.Interceptor()),
|
||||
)
|
||||
middlewareClient := mantraev1connect.NewMiddlewareServiceClient(
|
||||
http.DefaultClient,
|
||||
t.claims.ServerURL,
|
||||
connect.WithInterceptors(t.Interceptor()),
|
||||
)
|
||||
|
||||
for _, container := range containers {
|
||||
dynConfig := &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{},
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
UDP: &dynamic.UDPConfiguration{},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
}
|
||||
|
||||
err := parser.Decode(
|
||||
container.Labels,
|
||||
dynConfig,
|
||||
parser.DefaultRootName,
|
||||
"traefik.http",
|
||||
"traefik.tcp",
|
||||
"traefik.udp",
|
||||
"traefik.tls.stores.default",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use the first public port
|
||||
publicPort := container.Ports[0].PublicPort
|
||||
|
||||
// Routers ------------------------------------------------------------
|
||||
for name, config := range dynConfig.HTTP.Routers {
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateRouterRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.RouterType_ROUTER_TYPE_HTTP,
|
||||
})
|
||||
if _, err := routerClient.CreateRouter(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for name, config := range dynConfig.TCP.Routers {
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateRouterRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.RouterType_ROUTER_TYPE_TCP,
|
||||
})
|
||||
if _, err := routerClient.CreateRouter(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for name, config := range dynConfig.UDP.Routers {
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateRouterRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.RouterType_ROUTER_TYPE_UDP,
|
||||
})
|
||||
if _, err := routerClient.CreateRouter(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Services -----------------------------------------------------------
|
||||
for name, config := range dynConfig.HTTP.Services {
|
||||
config.LoadBalancer.Servers = []dynamic.Server{{
|
||||
URL: t.activeIP,
|
||||
Port: strconv.Itoa(int(publicPort)),
|
||||
}}
|
||||
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateServiceRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.ServiceType_SERVICE_TYPE_HTTP,
|
||||
})
|
||||
if _, err := serviceClient.CreateService(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for name, config := range dynConfig.TCP.Services {
|
||||
config.LoadBalancer.Servers = []dynamic.TCPServer{{
|
||||
Address: t.activeIP,
|
||||
Port: strconv.Itoa(int(publicPort)),
|
||||
}}
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateServiceRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.ServiceType_SERVICE_TYPE_TCP,
|
||||
})
|
||||
if _, err := serviceClient.CreateService(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for name, config := range dynConfig.UDP.Services {
|
||||
config.LoadBalancer.Servers = []dynamic.UDPServer{{
|
||||
Address: t.activeIP,
|
||||
Port: strconv.Itoa(int(publicPort)),
|
||||
}}
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateServiceRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.ServiceType_SERVICE_TYPE_UDP,
|
||||
})
|
||||
if _, err := serviceClient.CreateService(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Middlewares --------------------------------------------------------
|
||||
for name, config := range dynConfig.HTTP.Middlewares {
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateMiddlewareRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.MiddlewareType_MIDDLEWARE_TYPE_HTTP,
|
||||
})
|
||||
if _, err := middlewareClient.CreateMiddleware(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for name, config := range dynConfig.TCP.Middlewares {
|
||||
wrapped, err := ToProtoStruct(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := connect.NewRequest(&mantraev1.CreateMiddlewareRequest{
|
||||
Name: name,
|
||||
Config: wrapped,
|
||||
ProfileId: t.claims.ProfileID,
|
||||
AgentId: t.claims.AgentID,
|
||||
Type: mantraev1.MiddlewareType_MIDDLEWARE_TYPE_TCP,
|
||||
})
|
||||
if _, err := middlewareClient.CreateMiddleware(ctx, req); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToProtoStruct converts any Go struct to *structpb.Struct
|
||||
func ToProtoStruct(v any) (*structpb.Struct, error) {
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var mapData map[string]interface{}
|
||||
if err := json.Unmarshal(data, &mapData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return structpb.NewStruct(mapData)
|
||||
}
|
||||
48
agent/internal/collector/docker.go
Normal file
48
agent/internal/collector/docker.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
// GetContainers retrieves all local containers
|
||||
func GetContainers() ([]types.Container, error) {
|
||||
// Create a new Docker client
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to create Docker client")
|
||||
}
|
||||
|
||||
// Get all containers
|
||||
containers, err := cli.ContainerList(context.Background(), container.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to list containers")
|
||||
}
|
||||
|
||||
var result []types.Container
|
||||
// portMap := make(map[int32]int32)
|
||||
|
||||
// Iterate over each container and populate the Container struct
|
||||
for _, c := range containers {
|
||||
// Skip Traefik
|
||||
for _, name := range c.Names {
|
||||
if strings.Contains(strings.ToLower(name), "traefik") {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Populate PortInfo
|
||||
// for _, p := range c.Ports {
|
||||
// fmt.Printf("%s:%d -> %d/%s\n", p.IP, p.PublicPort, p.PrivatePort, p.Type)
|
||||
// // portMap[int32(p.PublicPort)] = int32(p.PrivatePort)
|
||||
// }
|
||||
result = append(result, c)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
50
agent/internal/collector/machine.go
Normal file
50
agent/internal/collector/machine.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/mizuchilabs/mantrae/pkg/util"
|
||||
)
|
||||
|
||||
type Machine struct {
|
||||
MachineID string
|
||||
Hostname string
|
||||
PrivateIPs util.IPAddresses
|
||||
PublicIPs util.IPAddresses
|
||||
}
|
||||
|
||||
// GetMachineInfo retrieves information about the local machine
|
||||
func GetMachineInfo() *Machine {
|
||||
var result Machine
|
||||
var err error
|
||||
|
||||
id, err := os.ReadFile("/etc/machine-id")
|
||||
if err != nil {
|
||||
id, err = os.ReadFile("/var/lib/dbus/machine-id")
|
||||
if err != nil {
|
||||
slog.Error("Failed to read machine ID", "error", err)
|
||||
}
|
||||
}
|
||||
if len(id) > 0 {
|
||||
result.MachineID = string(id)
|
||||
}
|
||||
|
||||
result.Hostname, err = os.Hostname()
|
||||
if err != nil {
|
||||
result.Hostname = "unknown"
|
||||
slog.Error("Failed to get hostname", "error", err)
|
||||
}
|
||||
|
||||
result.PrivateIPs, err = util.GetPrivateIPs()
|
||||
if err != nil {
|
||||
slog.Error("Failed to get local IP", "error", err)
|
||||
}
|
||||
|
||||
result.PublicIPs, err = util.GetPublicIPs()
|
||||
if err != nil {
|
||||
slog.Error("Failed to get public IP", "error", err)
|
||||
}
|
||||
|
||||
return &result
|
||||
}
|
||||
6
buf.lock
Normal file
6
buf.lock
Normal file
@@ -0,0 +1,6 @@
|
||||
# Generated by buf. DO NOT EDIT.
|
||||
version: v2
|
||||
deps:
|
||||
- name: buf.build/bufbuild/protovalidate
|
||||
commit: 9f2d3c737feb481a83375159c0733275
|
||||
digest: b5:19d3b83f7df2d284ff5935f4622d7f27e7464a93c210edb536e92a52bcc69b2a18da1312e96b5461601eba7b3764d5e90321bd62e6966870e7dbc2e4dedd98d6
|
||||
@@ -152,7 +152,6 @@ func (s *Server) registerServices() {
|
||||
mantraev1connect.SettingServiceName,
|
||||
mantraev1connect.DnsProviderServiceName,
|
||||
mantraev1connect.AgentServiceName,
|
||||
mantraev1connect.AgentManagementServiceName,
|
||||
mantraev1connect.RouterServiceName,
|
||||
mantraev1connect.ServiceServiceName,
|
||||
mantraev1connect.MiddlewareServiceName,
|
||||
@@ -205,10 +204,6 @@ func (s *Server) registerServices() {
|
||||
service.NewAgentService(s.app),
|
||||
opts...,
|
||||
))
|
||||
s.mux.Handle(mantraev1connect.NewAgentManagementServiceHandler(
|
||||
service.NewAgentManagementService(s.app),
|
||||
opts...,
|
||||
))
|
||||
s.mux.Handle(mantraev1connect.NewRouterServiceHandler(
|
||||
service.NewRouterService(s.app),
|
||||
opts...,
|
||||
|
||||
@@ -9,16 +9,13 @@ import (
|
||||
"connectrpc.com/connect"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/mizuchilabs/mantrae/internal/api/middlewares"
|
||||
"github.com/google/uuid"
|
||||
"github.com/mizuchilabs/mantrae/internal/config"
|
||||
"github.com/mizuchilabs/mantrae/internal/settings"
|
||||
"github.com/mizuchilabs/mantrae/internal/store/db"
|
||||
"github.com/mizuchilabs/mantrae/internal/store/schema"
|
||||
"github.com/mizuchilabs/mantrae/internal/util"
|
||||
"github.com/mizuchilabs/mantrae/pkg/meta"
|
||||
"github.com/mizuchilabs/mantrae/pkg/util"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
"github.com/traefik/paerser/parser"
|
||||
"github.com/traefik/traefik/v3/pkg/config/dynamic"
|
||||
)
|
||||
|
||||
type AgentService struct {
|
||||
@@ -29,88 +26,291 @@ func NewAgentService(app *config.App) *AgentService {
|
||||
return &AgentService{app: app}
|
||||
}
|
||||
|
||||
func (s *AgentService) GetAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.GetAgentRequest],
|
||||
) (*connect.Response[mantraev1.GetAgentResponse], error) {
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
// var containers []*mantraev1.Container
|
||||
// err = json.Unmarshal(containers, &agent.Containers)
|
||||
// if err != nil {
|
||||
// return nil, connect.NewError(connect.CodeInternal, err)
|
||||
// }
|
||||
|
||||
return connect.NewResponse(&mantraev1.GetAgentResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
PrivateIp: SafeString(agent.PrivateIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
// Containers: containers,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) CreateAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.CreateAgentRequest],
|
||||
) (*connect.Response[mantraev1.CreateAgentResponse], error) {
|
||||
if req.Msg.ProfileId == 0 {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("profile id is required"),
|
||||
)
|
||||
}
|
||||
|
||||
id, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
serverUrl, err := s.app.Conn.GetQuery().GetSetting(ctx, settings.KeyServerURL)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
if serverUrl.Value == "" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("server url is required, check your settings"),
|
||||
)
|
||||
}
|
||||
|
||||
token, err := s.createToken(ctx, id.String())
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
agent, err := s.app.Conn.GetQuery().CreateAgent(ctx, db.CreateAgentParams{
|
||||
ID: id.String(),
|
||||
ProfileID: req.Msg.ProfileId,
|
||||
Token: *token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.CreateAgentResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Token: agent.Token,
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) UpdateAgentIP(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.UpdateAgentIPRequest],
|
||||
) (*connect.Response[mantraev1.UpdateAgentIPResponse], error) {
|
||||
if err := s.app.Conn.GetQuery().UpdateAgentIP(ctx, db.UpdateAgentIPParams{
|
||||
ID: req.Msg.Id,
|
||||
ActiveIp: &req.Msg.Ip,
|
||||
}); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.UpdateAgentIPResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
PrivateIp: SafeString(agent.PrivateIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) DeleteAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.DeleteAgentRequest],
|
||||
) (*connect.Response[mantraev1.DeleteAgentResponse], error) {
|
||||
if err := s.app.Conn.GetQuery().DeleteAgent(ctx, req.Msg.Id); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.DeleteAgentResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) ListAgents(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.ListAgentsRequest],
|
||||
) (*connect.Response[mantraev1.ListAgentsResponse], error) {
|
||||
if req.Msg.ProfileId == 0 {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("profile id is required"),
|
||||
)
|
||||
}
|
||||
|
||||
var params db.ListAgentsParams
|
||||
params.ProfileID = req.Msg.ProfileId
|
||||
if req.Msg.Limit == nil {
|
||||
params.Limit = 100
|
||||
} else {
|
||||
params.Limit = *req.Msg.Limit
|
||||
}
|
||||
if req.Msg.Offset == nil {
|
||||
params.Offset = 0
|
||||
} else {
|
||||
params.Offset = *req.Msg.Offset
|
||||
}
|
||||
|
||||
dbAgents, err := s.app.Conn.GetQuery().ListAgents(ctx, params)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
totalCount, err := s.app.Conn.GetQuery().CountAgents(ctx)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
var agents []*mantraev1.Agent
|
||||
for _, agent := range dbAgents {
|
||||
agents = append(agents, &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
PrivateIp: SafeString(agent.PrivateIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
})
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.ListAgentsResponse{
|
||||
Agents: agents,
|
||||
TotalCount: totalCount,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) HealthCheck(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.HealthCheckRequest],
|
||||
) (*connect.Response[mantraev1.HealthCheckResponse], error) {
|
||||
// Rotate Token
|
||||
token, err := s.updateToken(ctx, req.Header().Get(meta.HeaderAgentID))
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Header().Get(meta.HeaderAgentID))
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
util.Broadcast <- util.EventMessage{
|
||||
Type: util.EventTypeUpdate,
|
||||
Category: util.EventCategoryAgent,
|
||||
|
||||
// Rotate Token if it's close to expiring
|
||||
if _, err := s.updateToken(ctx, &agent); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.HealthCheckResponse{Ok: true, Token: *token}), nil
|
||||
|
||||
// Update Agent
|
||||
var params db.UpdateAgentParams
|
||||
params.ID = agent.ID
|
||||
if req.Msg.PublicIp != "" {
|
||||
params.PublicIp = &req.Msg.PublicIp
|
||||
}
|
||||
if req.Msg.PrivateIp != "" {
|
||||
params.PrivateIp = &req.Msg.PrivateIp
|
||||
}
|
||||
|
||||
agentNew, err := s.app.Conn.GetQuery().UpdateAgent(ctx, params)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.HealthCheckResponse{Agent: &mantraev1.Agent{
|
||||
Id: agentNew.ID,
|
||||
ProfileId: agentNew.ProfileID,
|
||||
ActiveIp: SafeString(agentNew.ActiveIp),
|
||||
Token: agentNew.Token,
|
||||
}}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) GetContainer(
|
||||
func (s *AgentService) RotateAgentToken(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.GetContainerRequest],
|
||||
) (*connect.Response[mantraev1.GetContainerResponse], error) {
|
||||
agentID, ok := middlewares.GetAgentIDFromContext(ctx)
|
||||
if !ok {
|
||||
return nil, connect.NewError(connect.CodeInternal, errors.New("agent context missing"))
|
||||
}
|
||||
|
||||
// Upsert agent
|
||||
params := db.UpdateAgentParams{
|
||||
ID: agentID,
|
||||
Hostname: &req.Msg.Hostname,
|
||||
PublicIp: &req.Msg.PublicIp,
|
||||
}
|
||||
// if agent.ActiveIp == nil {
|
||||
// params.ActiveIp = &req.Msg.PublicIp
|
||||
// }
|
||||
|
||||
privateIPs := schema.AgentPrivateIPs{
|
||||
IPs: make([]string, len(req.Msg.PrivateIps)),
|
||||
}
|
||||
privateIPs.IPs = req.Msg.PrivateIps
|
||||
params.PrivateIps = &privateIPs
|
||||
|
||||
var containers schema.AgentContainers
|
||||
for _, container := range req.Msg.Containers {
|
||||
created := container.Created.AsTime()
|
||||
containers = append(containers, schema.AgentContainer{
|
||||
ID: container.Id,
|
||||
Name: container.Name,
|
||||
Labels: container.Labels,
|
||||
Image: container.Image,
|
||||
Portmap: container.Portmap,
|
||||
Status: container.Status,
|
||||
Created: &created,
|
||||
})
|
||||
}
|
||||
params.Containers = &containers
|
||||
|
||||
q := s.app.Conn.GetQuery()
|
||||
updatedAgent, err := q.UpdateAgent(ctx, params)
|
||||
req *connect.Request[mantraev1.RotateAgentTokenRequest],
|
||||
) (*connect.Response[mantraev1.RotateAgentTokenResponse], error) {
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
// Update dynamic config
|
||||
if err = s.DecodeAgentConfig(updatedAgent); err != nil {
|
||||
_, err = s.updateToken(ctx, &agent)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
util.Broadcast <- util.EventMessage{
|
||||
Type: util.EventTypeUpdate,
|
||||
Category: util.EventCategoryAgent,
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.GetContainerResponse{}), nil
|
||||
return connect.NewResponse(&mantraev1.RotateAgentTokenResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) updateToken(ctx context.Context, id string) (*string, error) {
|
||||
q := s.app.Conn.GetQuery()
|
||||
agent, err := q.GetAgent(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (s *AgentService) BootstrapAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.BootstrapAgentRequest],
|
||||
) (*connect.Response[mantraev1.BootstrapAgentResponse], error) {
|
||||
enabled, ok := s.app.SM.Get(settings.KeyAgentBootstrapEnabled)
|
||||
if !ok {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("failed to get agent bootstrap enabled setting"),
|
||||
)
|
||||
}
|
||||
if enabled != "true" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("agent bootstrap is disabled, check your settings"),
|
||||
)
|
||||
}
|
||||
if req.Msg.Token == "" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("token is required"),
|
||||
)
|
||||
}
|
||||
|
||||
claims, err := DecodeJWT(agent.Token, s.app.Secret)
|
||||
// Check if token is valid
|
||||
bootstrapToken, ok := s.app.SM.Get(settings.KeyAgentBootstrapToken)
|
||||
if !ok {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("failed to get agent bootstrap token setting"),
|
||||
)
|
||||
}
|
||||
if bootstrapToken != req.Msg.Token {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("invalid token"),
|
||||
)
|
||||
}
|
||||
|
||||
// Token is valid, create agent
|
||||
agent, err := s.app.Conn.GetQuery().CreateAgent(ctx, db.CreateAgentParams{
|
||||
ProfileID: req.Msg.ProfileId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
token, err := s.updateToken(ctx, &agent)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.BootstrapAgentResponse{Token: *token}), nil
|
||||
}
|
||||
|
||||
func (s *AgentService) updateToken(ctx context.Context, agent *db.Agent) (*string, error) {
|
||||
claims, err := util.DecodeJWT[*meta.AgentClaims](agent.Token, s.app.Secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -119,7 +319,34 @@ func (s *AgentService) updateToken(ctx context.Context, id string) (*string, err
|
||||
lifetime := claims.ExpiresAt.Sub(claims.IssuedAt.Time)
|
||||
remaining := time.Until(claims.ExpiresAt.Time)
|
||||
if remaining > lifetime/4 {
|
||||
return &agent.Token, nil // Still valid
|
||||
return &agent.Token, nil // Token is still valid
|
||||
}
|
||||
|
||||
token, err := s.createToken(ctx, agent.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = s.app.Conn.GetQuery().UpdateAgentToken(ctx, db.UpdateAgentTokenParams{
|
||||
ID: agent.ID,
|
||||
Token: *token,
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slog.Info("Rotating agent token", "agentID", agent.ID, "token", token)
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (s *AgentService) createToken(ctx context.Context, id string) (*string, error) {
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, id)
|
||||
if err != nil {
|
||||
return nil, errors.New("agent not found")
|
||||
}
|
||||
|
||||
serverUrl, ok := s.app.SM.Get(settings.KeyServerURL)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to get server url setting")
|
||||
}
|
||||
|
||||
agentInterval, ok := s.app.SM.Get(settings.KeyAgentCleanupInterval)
|
||||
@@ -127,161 +354,19 @@ func (s *AgentService) updateToken(ctx context.Context, id string) (*string, err
|
||||
return nil, errors.New("failed to get agent cleanup interval setting")
|
||||
}
|
||||
|
||||
token, err := claims.EncodeJWT(s.app.Secret, settings.AsDuration(agentInterval))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = q.UpdateAgentToken(ctx, db.UpdateAgentTokenParams{ID: agent.ID, Token: token})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
slog.Info("Rotating agent token", "agentID", agent.ID, "token", token)
|
||||
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
// Helpers --------------------------------------------------------------------
|
||||
type AgentClaims struct {
|
||||
AgentID string `json:"agentId,omitempty"`
|
||||
ProfileID int64 `json:"profileId,omitempty"`
|
||||
ServerURL string `json:"serverUrl,omitempty"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// EncodeJWT generates a JWT for agents
|
||||
func (a *AgentClaims) EncodeJWT(secret string, expirationTime time.Duration) (string, error) {
|
||||
if a.ServerURL == "" || a.ProfileID == 0 {
|
||||
return "", errors.New("serverUrl and profileID cannot be empty")
|
||||
}
|
||||
|
||||
if expirationTime == 0 {
|
||||
expirationTime = time.Hour * 24
|
||||
}
|
||||
|
||||
claims := &AgentClaims{
|
||||
AgentID: a.AgentID,
|
||||
ProfileID: a.ProfileID,
|
||||
ServerURL: a.ServerURL,
|
||||
claims := &meta.AgentClaims{
|
||||
AgentID: agent.ID,
|
||||
ProfileID: agent.ProfileID,
|
||||
ServerURL: serverUrl,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(expirationTime)),
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(settings.AsDuration(agentInterval))),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(secret))
|
||||
}
|
||||
|
||||
// DecodeJWT decodes the agent token and returns claims if valid
|
||||
func DecodeJWT(tokenString, secret string) (*AgentClaims, error) {
|
||||
claims := &AgentClaims{}
|
||||
token, err := jwt.ParseWithClaims(
|
||||
tokenString,
|
||||
claims,
|
||||
func(token *jwt.Token) (any, error) {
|
||||
return []byte(secret), nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
token, err := util.EncodeJWT[*meta.AgentClaims](claims, s.app.Secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func (s *AgentService) DecodeAgentConfig(agent db.Agent) error {
|
||||
ctx := context.Background()
|
||||
|
||||
q := s.app.Conn.GetQuery()
|
||||
for _, container := range *agent.Containers {
|
||||
dynConfig := &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{},
|
||||
TCP: &dynamic.TCPConfiguration{},
|
||||
UDP: &dynamic.UDPConfiguration{},
|
||||
TLS: &dynamic.TLSConfiguration{},
|
||||
}
|
||||
|
||||
err := parser.Decode(
|
||||
container.Labels,
|
||||
dynConfig,
|
||||
parser.DefaultRootName,
|
||||
"traefik.http",
|
||||
"traefik.tcp",
|
||||
"traefik.udp",
|
||||
"traefik.tls.stores.default",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for k, r := range dynConfig.HTTP.Routers {
|
||||
q.CreateHttpRouter(ctx, db.CreateHttpRouterParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapRouter(r),
|
||||
})
|
||||
}
|
||||
for k, r := range dynConfig.TCP.Routers {
|
||||
q.CreateTcpRouter(ctx, db.CreateTcpRouterParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapTCPRouter(r),
|
||||
})
|
||||
}
|
||||
for k, r := range dynConfig.UDP.Routers {
|
||||
q.CreateUdpRouter(ctx, db.CreateUdpRouterParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapUDPRouter(r),
|
||||
})
|
||||
}
|
||||
|
||||
for k, r := range dynConfig.HTTP.Services {
|
||||
q.CreateHttpService(ctx, db.CreateHttpServiceParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapService(r),
|
||||
})
|
||||
}
|
||||
for k, r := range dynConfig.TCP.Services {
|
||||
q.CreateTcpService(ctx, db.CreateTcpServiceParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapTCPService(r),
|
||||
})
|
||||
}
|
||||
for k, r := range dynConfig.UDP.Services {
|
||||
q.CreateUdpService(ctx, db.CreateUdpServiceParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapUDPService(r),
|
||||
})
|
||||
}
|
||||
|
||||
for k, r := range dynConfig.HTTP.Middlewares {
|
||||
q.CreateHttpMiddleware(ctx, db.CreateHttpMiddlewareParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapMiddleware(r),
|
||||
})
|
||||
}
|
||||
for k, r := range dynConfig.TCP.Middlewares {
|
||||
q.CreateTcpMiddleware(ctx, db.CreateTcpMiddlewareParams{
|
||||
ProfileID: agent.ProfileID,
|
||||
AgentID: &agent.ID,
|
||||
Name: k,
|
||||
Config: schema.WrapTCPMiddleware(r),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
@@ -1,318 +0,0 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/mizuchilabs/mantrae/internal/config"
|
||||
"github.com/mizuchilabs/mantrae/internal/settings"
|
||||
"github.com/mizuchilabs/mantrae/internal/store/db"
|
||||
mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
)
|
||||
|
||||
type AgentManagementService struct {
|
||||
app *config.App
|
||||
}
|
||||
|
||||
func NewAgentManagementService(app *config.App) *AgentManagementService {
|
||||
return &AgentManagementService{app: app}
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) GetAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.GetAgentRequest],
|
||||
) (*connect.Response[mantraev1.GetAgentResponse], error) {
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
// var containers []*mantraev1.Container
|
||||
// err = json.Unmarshal(containers, &agent.Containers)
|
||||
// if err != nil {
|
||||
// return nil, connect.NewError(connect.CodeInternal, err)
|
||||
// }
|
||||
|
||||
return connect.NewResponse(&mantraev1.GetAgentResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
PrivateIps: agent.PrivateIps.IPs,
|
||||
// Containers: containers,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) CreateAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.CreateAgentRequest],
|
||||
) (*connect.Response[mantraev1.CreateAgentResponse], error) {
|
||||
if req.Msg.ProfileId == 0 {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("profile id is required"),
|
||||
)
|
||||
}
|
||||
|
||||
id, err := uuid.NewV7()
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
serverUrl, err := s.app.Conn.GetQuery().GetSetting(ctx, settings.KeyServerURL)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
if serverUrl.Value == "" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("server url is required, check your settings"),
|
||||
)
|
||||
}
|
||||
|
||||
claims := &AgentClaims{
|
||||
AgentID: id.String(),
|
||||
ProfileID: req.Msg.ProfileId,
|
||||
ServerURL: serverUrl.Value,
|
||||
}
|
||||
token, err := claims.EncodeJWT(s.app.Secret, time.Hour*72)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
agent, err := s.app.Conn.GetQuery().CreateAgent(ctx, db.CreateAgentParams{
|
||||
ID: claims.AgentID,
|
||||
ProfileID: claims.ProfileID,
|
||||
Token: token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.CreateAgentResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Token: agent.Token,
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) UpdateAgentIP(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.UpdateAgentIPRequest],
|
||||
) (*connect.Response[mantraev1.UpdateAgentIPResponse], error) {
|
||||
if err := s.app.Conn.GetQuery().UpdateAgentIP(ctx, db.UpdateAgentIPParams{
|
||||
ID: req.Msg.Id,
|
||||
ActiveIp: &req.Msg.Ip,
|
||||
}); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.UpdateAgentIPResponse{
|
||||
Agent: &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
PrivateIps: agent.PrivateIps.IPs,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
},
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) DeleteAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.DeleteAgentRequest],
|
||||
) (*connect.Response[mantraev1.DeleteAgentResponse], error) {
|
||||
if err := s.app.Conn.GetQuery().DeleteAgent(ctx, req.Msg.Id); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.DeleteAgentResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) ListAgents(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.ListAgentsRequest],
|
||||
) (*connect.Response[mantraev1.ListAgentsResponse], error) {
|
||||
if req.Msg.ProfileId == 0 {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("profile id is required"),
|
||||
)
|
||||
}
|
||||
|
||||
var params db.ListAgentsParams
|
||||
params.ProfileID = req.Msg.ProfileId
|
||||
if req.Msg.Limit == nil {
|
||||
params.Limit = 100
|
||||
} else {
|
||||
params.Limit = *req.Msg.Limit
|
||||
}
|
||||
if req.Msg.Offset == nil {
|
||||
params.Offset = 0
|
||||
} else {
|
||||
params.Offset = *req.Msg.Offset
|
||||
}
|
||||
|
||||
dbAgents, err := s.app.Conn.GetQuery().ListAgents(ctx, params)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
totalCount, err := s.app.Conn.GetQuery().CountAgents(ctx)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
var agents []*mantraev1.Agent
|
||||
for _, agent := range dbAgents {
|
||||
agents = append(agents, &mantraev1.Agent{
|
||||
Id: agent.ID,
|
||||
ProfileId: agent.ProfileID,
|
||||
Hostname: SafeString(agent.Hostname),
|
||||
PublicIp: SafeString(agent.PublicIp),
|
||||
ActiveIp: SafeString(agent.ActiveIp),
|
||||
Token: agent.Token,
|
||||
CreatedAt: SafeTimestamp(agent.CreatedAt),
|
||||
UpdatedAt: SafeTimestamp(agent.UpdatedAt),
|
||||
})
|
||||
if agent.PrivateIps != nil {
|
||||
for _, ip := range agent.PrivateIps.IPs {
|
||||
agents[len(agents)-1].PrivateIps = append(agents[len(agents)-1].PrivateIps, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
return connect.NewResponse(&mantraev1.ListAgentsResponse{
|
||||
Agents: agents,
|
||||
TotalCount: totalCount,
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) RotateAgentToken(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.RotateAgentTokenRequest],
|
||||
) (*connect.Response[mantraev1.RotateAgentTokenResponse], error) {
|
||||
agent, err := s.app.Conn.GetQuery().GetAgent(ctx, req.Msg.Id)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
serverUrl, err := s.app.Conn.GetQuery().GetSetting(ctx, settings.KeyServerURL)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
claims := &AgentClaims{
|
||||
AgentID: agent.ID,
|
||||
ProfileID: agent.ProfileID,
|
||||
ServerURL: serverUrl.Value,
|
||||
}
|
||||
token, err := claims.EncodeJWT(s.app.Secret, time.Hour*72)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
if err := s.app.Conn.GetQuery().UpdateAgentToken(ctx, db.UpdateAgentTokenParams{
|
||||
ID: agent.ID,
|
||||
Token: token,
|
||||
}); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.RotateAgentTokenResponse{}), nil
|
||||
}
|
||||
|
||||
func (s *AgentManagementService) BootstrapAgent(
|
||||
ctx context.Context,
|
||||
req *connect.Request[mantraev1.BootstrapAgentRequest],
|
||||
) (*connect.Response[mantraev1.BootstrapAgentResponse], error) {
|
||||
enabled, ok := s.app.SM.Get(settings.KeyAgentBootstrapEnabled)
|
||||
if !ok {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("failed to get agent bootstrap enabled setting"),
|
||||
)
|
||||
}
|
||||
if enabled != "true" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("agent bootstrap is disabled, check your settings"),
|
||||
)
|
||||
}
|
||||
if req.Msg.Token == "" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("token is required"),
|
||||
)
|
||||
}
|
||||
|
||||
// Check if token is valid
|
||||
bootstrapToken, ok := s.app.SM.Get(settings.KeyAgentBootstrapToken)
|
||||
if !ok {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("failed to get agent bootstrap token setting"),
|
||||
)
|
||||
}
|
||||
if bootstrapToken != req.Msg.Token {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("invalid token"),
|
||||
)
|
||||
}
|
||||
|
||||
// Toke is valid, create agent
|
||||
agent, err := s.app.Conn.GetQuery().CreateAgent(ctx, db.CreateAgentParams{
|
||||
ProfileID: req.Msg.ProfileId,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
serverUrl, err := s.app.Conn.GetQuery().GetSetting(ctx, settings.KeyServerURL)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
if serverUrl.Value == "" {
|
||||
return nil, connect.NewError(
|
||||
connect.CodeInvalidArgument,
|
||||
errors.New("server url is required, check your settings"),
|
||||
)
|
||||
}
|
||||
|
||||
claims := &AgentClaims{
|
||||
AgentID: agent.ID,
|
||||
ProfileID: agent.ProfileID,
|
||||
ServerURL: serverUrl.Value,
|
||||
}
|
||||
token, err := claims.EncodeJWT(s.app.Secret, time.Hour*72)
|
||||
if err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
if err := s.app.Conn.GetQuery().UpdateAgentToken(ctx, db.UpdateAgentTokenParams{
|
||||
ID: agent.ID,
|
||||
Token: token,
|
||||
}); err != nil {
|
||||
return nil, connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
return connect.NewResponse(&mantraev1.BootstrapAgentResponse{Token: token}), nil
|
||||
}
|
||||
@@ -193,7 +193,7 @@ CREATE TABLE agents (
|
||||
profile_id INTEGER NOT NULL,
|
||||
hostname TEXT,
|
||||
public_ip TEXT,
|
||||
private_ips TEXT,
|
||||
private_ip TEXT,
|
||||
containers TEXT,
|
||||
active_ip TEXT,
|
||||
token TEXT NOT NULL DEFAULT '',
|
||||
|
||||
@@ -29,7 +29,7 @@ const createAgent = `-- name: CreateAgent :one
|
||||
INSERT INTO
|
||||
agents (id, profile_id, token, created_at)
|
||||
VALUES
|
||||
(?, ?, ?, CURRENT_TIMESTAMP) RETURNING id, profile_id, hostname, public_ip, private_ips, containers, active_ip, token, created_at, updated_at
|
||||
(?, ?, ?, CURRENT_TIMESTAMP) RETURNING id, profile_id, hostname, public_ip, containers, active_ip, token, created_at, updated_at, private_ip
|
||||
`
|
||||
|
||||
type CreateAgentParams struct {
|
||||
@@ -46,12 +46,12 @@ func (q *Queries) CreateAgent(ctx context.Context, arg CreateAgentParams) (Agent
|
||||
&i.ProfileID,
|
||||
&i.Hostname,
|
||||
&i.PublicIp,
|
||||
&i.PrivateIps,
|
||||
&i.Containers,
|
||||
&i.ActiveIp,
|
||||
&i.Token,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateIp,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func (q *Queries) DeleteAgent(ctx context.Context, id string) error {
|
||||
|
||||
const getAgent = `-- name: GetAgent :one
|
||||
SELECT
|
||||
id, profile_id, hostname, public_ip, private_ips, containers, active_ip, token, created_at, updated_at
|
||||
id, profile_id, hostname, public_ip, containers, active_ip, token, created_at, updated_at, private_ip
|
||||
FROM
|
||||
agents
|
||||
WHERE
|
||||
@@ -84,19 +84,19 @@ func (q *Queries) GetAgent(ctx context.Context, id string) (Agent, error) {
|
||||
&i.ProfileID,
|
||||
&i.Hostname,
|
||||
&i.PublicIp,
|
||||
&i.PrivateIps,
|
||||
&i.Containers,
|
||||
&i.ActiveIp,
|
||||
&i.Token,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateIp,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const listAgents = `-- name: ListAgents :many
|
||||
SELECT
|
||||
id, profile_id, hostname, public_ip, private_ips, containers, active_ip, token, created_at, updated_at
|
||||
id, profile_id, hostname, public_ip, containers, active_ip, token, created_at, updated_at, private_ip
|
||||
FROM
|
||||
agents
|
||||
WHERE
|
||||
@@ -129,12 +129,12 @@ func (q *Queries) ListAgents(ctx context.Context, arg ListAgentsParams) ([]Agent
|
||||
&i.ProfileID,
|
||||
&i.Hostname,
|
||||
&i.PublicIp,
|
||||
&i.PrivateIps,
|
||||
&i.Containers,
|
||||
&i.ActiveIp,
|
||||
&i.Token,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateIp,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -154,20 +154,20 @@ UPDATE agents
|
||||
SET
|
||||
hostname = COALESCE(?, hostname),
|
||||
public_ip = COALESCE(?, public_ip),
|
||||
private_ips = COALESCE(?, private_ips),
|
||||
containers = COALESCE(?, containers),
|
||||
private_ip = COALESCE(?, private_ip),
|
||||
active_ip = COALESCE(?, active_ip),
|
||||
containers = COALESCE(?, containers),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE
|
||||
id = ? RETURNING id, profile_id, hostname, public_ip, private_ips, containers, active_ip, token, created_at, updated_at
|
||||
id = ? RETURNING id, profile_id, hostname, public_ip, containers, active_ip, token, created_at, updated_at, private_ip
|
||||
`
|
||||
|
||||
type UpdateAgentParams struct {
|
||||
Hostname *string `json:"hostname"`
|
||||
PublicIp *string `json:"publicIp"`
|
||||
PrivateIps *schema.AgentPrivateIPs `json:"privateIps"`
|
||||
Containers *schema.AgentContainers `json:"containers"`
|
||||
PrivateIp *string `json:"privateIp"`
|
||||
ActiveIp *string `json:"activeIp"`
|
||||
Containers *schema.AgentContainers `json:"containers"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ func (q *Queries) UpdateAgent(ctx context.Context, arg UpdateAgentParams) (Agent
|
||||
row := q.queryRow(ctx, q.updateAgentStmt, updateAgent,
|
||||
arg.Hostname,
|
||||
arg.PublicIp,
|
||||
arg.PrivateIps,
|
||||
arg.Containers,
|
||||
arg.PrivateIp,
|
||||
arg.ActiveIp,
|
||||
arg.Containers,
|
||||
arg.ID,
|
||||
)
|
||||
var i Agent
|
||||
@@ -186,12 +186,12 @@ func (q *Queries) UpdateAgent(ctx context.Context, arg UpdateAgentParams) (Agent
|
||||
&i.ProfileID,
|
||||
&i.Hostname,
|
||||
&i.PublicIp,
|
||||
&i.PrivateIps,
|
||||
&i.Containers,
|
||||
&i.ActiveIp,
|
||||
&i.Token,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateIp,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@ type Agent struct {
|
||||
ProfileID int64 `json:"profileId"`
|
||||
Hostname *string `json:"hostname"`
|
||||
PublicIp *string `json:"publicIp"`
|
||||
PrivateIps *schema.AgentPrivateIPs `json:"privateIps"`
|
||||
Containers *schema.AgentContainers `json:"containers"`
|
||||
ActiveIp *string `json:"activeIp"`
|
||||
Token string `json:"token"`
|
||||
CreatedAt *time.Time `json:"createdAt"`
|
||||
UpdatedAt *time.Time `json:"updatedAt"`
|
||||
PrivateIp *string `json:"privateIp"`
|
||||
}
|
||||
|
||||
type DnsProvider struct {
|
||||
|
||||
@@ -188,15 +188,17 @@ ADD COLUMN description TEXT;
|
||||
-- Update agents table - change JSON columns to TEXT
|
||||
UPDATE agents
|
||||
SET
|
||||
private_ips = CASE
|
||||
WHEN private_ips IS NOT NULL THEN private_ips
|
||||
ELSE NULL
|
||||
END,
|
||||
containers = CASE
|
||||
WHEN containers IS NOT NULL THEN containers
|
||||
ELSE NULL
|
||||
END;
|
||||
|
||||
ALTER TABLE agents
|
||||
DROP COLUMN private_ips;
|
||||
|
||||
ALTER TABLE agents
|
||||
ADD COLUMN private_ip TEXT;
|
||||
|
||||
-- Update users table - change id to TEXT and remove AUTOINCREMENT
|
||||
CREATE TABLE users_new (
|
||||
id TEXT PRIMARY KEY,
|
||||
|
||||
@@ -37,9 +37,9 @@ UPDATE agents
|
||||
SET
|
||||
hostname = COALESCE(?, hostname),
|
||||
public_ip = COALESCE(?, public_ip),
|
||||
private_ips = COALESCE(?, private_ips),
|
||||
containers = COALESCE(?, containers),
|
||||
private_ip = COALESCE(?, private_ip),
|
||||
active_ip = COALESCE(?, active_ip),
|
||||
containers = COALESCE(?, containers),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE
|
||||
id = ? RETURNING *;
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type EventMessage struct {
|
||||
Type string `json:"type"`
|
||||
Category string `json:"category"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
const (
|
||||
// Types
|
||||
EventTypeError = "error"
|
||||
EventTypeInfo = "info"
|
||||
EventTypeCreate = "create"
|
||||
EventTypeUpdate = "update"
|
||||
EventTypeDelete = "delete"
|
||||
|
||||
// Categories
|
||||
EventCategoryProfile = "profile"
|
||||
EventCategoryTraefik = "traefik"
|
||||
EventCategoryDNS = "dns"
|
||||
EventCategoryUser = "user"
|
||||
EventCategoryAgent = "agent"
|
||||
EventCategorySetting = "setting"
|
||||
)
|
||||
|
||||
var (
|
||||
Broadcast = make(chan EventMessage, 100)
|
||||
SSEDone = make(chan struct{})
|
||||
Clients = make(map[http.ResponseWriter]bool)
|
||||
ClientsMutex = &sync.Mutex{}
|
||||
)
|
||||
|
||||
func StartEventProcessor(ctx context.Context) {
|
||||
go func() {
|
||||
defer close(SSEDone)
|
||||
|
||||
for {
|
||||
select {
|
||||
case msg := <-Broadcast:
|
||||
ClientsMutex.Lock()
|
||||
for client := range Clients {
|
||||
// Non-blocking send to each client
|
||||
go func(w http.ResponseWriter, message EventMessage) {
|
||||
if err := SendEventToClient(w, message); err != nil {
|
||||
slog.Error("Failed to send event", "error", err)
|
||||
// Remove failed clients
|
||||
ClientsMutex.Lock()
|
||||
delete(Clients, w)
|
||||
ClientsMutex.Unlock()
|
||||
}
|
||||
}(client, msg)
|
||||
}
|
||||
ClientsMutex.Unlock()
|
||||
|
||||
// If no clients, log the dropped event
|
||||
if len(Clients) == 0 {
|
||||
slog.Debug("Event dropped - no clients connected",
|
||||
"type", msg.Type,
|
||||
"message", msg.Message)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func SendEventToClient(w http.ResponseWriter, msg EventMessage) error {
|
||||
// Implementation of sending event to a single client
|
||||
data, err := json.Marshal(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, "data: %s\n\n", data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if f, ok := w.(http.Flusher); ok {
|
||||
f.Flush()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,18 +33,40 @@ const (
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// AgentServiceGetContainerProcedure is the fully-qualified name of the AgentService's GetContainer
|
||||
// AgentServiceGetAgentProcedure is the fully-qualified name of the AgentService's GetAgent RPC.
|
||||
AgentServiceGetAgentProcedure = "/mantrae.v1.AgentService/GetAgent"
|
||||
// AgentServiceCreateAgentProcedure is the fully-qualified name of the AgentService's CreateAgent
|
||||
// RPC.
|
||||
AgentServiceGetContainerProcedure = "/mantrae.v1.AgentService/GetContainer"
|
||||
AgentServiceCreateAgentProcedure = "/mantrae.v1.AgentService/CreateAgent"
|
||||
// AgentServiceUpdateAgentIPProcedure is the fully-qualified name of the AgentService's
|
||||
// UpdateAgentIP RPC.
|
||||
AgentServiceUpdateAgentIPProcedure = "/mantrae.v1.AgentService/UpdateAgentIP"
|
||||
// AgentServiceDeleteAgentProcedure is the fully-qualified name of the AgentService's DeleteAgent
|
||||
// RPC.
|
||||
AgentServiceDeleteAgentProcedure = "/mantrae.v1.AgentService/DeleteAgent"
|
||||
// AgentServiceListAgentsProcedure is the fully-qualified name of the AgentService's ListAgents RPC.
|
||||
AgentServiceListAgentsProcedure = "/mantrae.v1.AgentService/ListAgents"
|
||||
// AgentServiceHealthCheckProcedure is the fully-qualified name of the AgentService's HealthCheck
|
||||
// RPC.
|
||||
AgentServiceHealthCheckProcedure = "/mantrae.v1.AgentService/HealthCheck"
|
||||
// AgentServiceBootstrapAgentProcedure is the fully-qualified name of the AgentService's
|
||||
// BootstrapAgent RPC.
|
||||
AgentServiceBootstrapAgentProcedure = "/mantrae.v1.AgentService/BootstrapAgent"
|
||||
// AgentServiceRotateAgentTokenProcedure is the fully-qualified name of the AgentService's
|
||||
// RotateAgentToken RPC.
|
||||
AgentServiceRotateAgentTokenProcedure = "/mantrae.v1.AgentService/RotateAgentToken"
|
||||
)
|
||||
|
||||
// AgentServiceClient is a client for the mantrae.v1.AgentService service.
|
||||
type AgentServiceClient interface {
|
||||
GetContainer(context.Context, *connect.Request[v1.GetContainerRequest]) (*connect.Response[v1.GetContainerResponse], error)
|
||||
GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error)
|
||||
CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error)
|
||||
UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error)
|
||||
DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error)
|
||||
ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error)
|
||||
HealthCheck(context.Context, *connect.Request[v1.HealthCheckRequest]) (*connect.Response[v1.HealthCheckResponse], error)
|
||||
BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error)
|
||||
RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error)
|
||||
}
|
||||
|
||||
// NewAgentServiceClient constructs a client for the mantrae.v1.AgentService service. By default, it
|
||||
@@ -58,10 +80,36 @@ func NewAgentServiceClient(httpClient connect.HTTPClient, baseURL string, opts .
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
agentServiceMethods := v1.File_mantrae_v1_agent_proto.Services().ByName("AgentService").Methods()
|
||||
return &agentServiceClient{
|
||||
getContainer: connect.NewClient[v1.GetContainerRequest, v1.GetContainerResponse](
|
||||
getAgent: connect.NewClient[v1.GetAgentRequest, v1.GetAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceGetContainerProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("GetContainer")),
|
||||
baseURL+AgentServiceGetAgentProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("GetAgent")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createAgent: connect.NewClient[v1.CreateAgentRequest, v1.CreateAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceCreateAgentProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("CreateAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateAgentIP: connect.NewClient[v1.UpdateAgentIPRequest, v1.UpdateAgentIPResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceUpdateAgentIPProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("UpdateAgentIP")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteAgent: connect.NewClient[v1.DeleteAgentRequest, v1.DeleteAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceDeleteAgentProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("DeleteAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listAgents: connect.NewClient[v1.ListAgentsRequest, v1.ListAgentsResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceListAgentsProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("ListAgents")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
healthCheck: connect.NewClient[v1.HealthCheckRequest, v1.HealthCheckResponse](
|
||||
@@ -70,18 +118,56 @@ func NewAgentServiceClient(httpClient connect.HTTPClient, baseURL string, opts .
|
||||
connect.WithSchema(agentServiceMethods.ByName("HealthCheck")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
bootstrapAgent: connect.NewClient[v1.BootstrapAgentRequest, v1.BootstrapAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceBootstrapAgentProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("BootstrapAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
rotateAgentToken: connect.NewClient[v1.RotateAgentTokenRequest, v1.RotateAgentTokenResponse](
|
||||
httpClient,
|
||||
baseURL+AgentServiceRotateAgentTokenProcedure,
|
||||
connect.WithSchema(agentServiceMethods.ByName("RotateAgentToken")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// agentServiceClient implements AgentServiceClient.
|
||||
type agentServiceClient struct {
|
||||
getContainer *connect.Client[v1.GetContainerRequest, v1.GetContainerResponse]
|
||||
healthCheck *connect.Client[v1.HealthCheckRequest, v1.HealthCheckResponse]
|
||||
getAgent *connect.Client[v1.GetAgentRequest, v1.GetAgentResponse]
|
||||
createAgent *connect.Client[v1.CreateAgentRequest, v1.CreateAgentResponse]
|
||||
updateAgentIP *connect.Client[v1.UpdateAgentIPRequest, v1.UpdateAgentIPResponse]
|
||||
deleteAgent *connect.Client[v1.DeleteAgentRequest, v1.DeleteAgentResponse]
|
||||
listAgents *connect.Client[v1.ListAgentsRequest, v1.ListAgentsResponse]
|
||||
healthCheck *connect.Client[v1.HealthCheckRequest, v1.HealthCheckResponse]
|
||||
bootstrapAgent *connect.Client[v1.BootstrapAgentRequest, v1.BootstrapAgentResponse]
|
||||
rotateAgentToken *connect.Client[v1.RotateAgentTokenRequest, v1.RotateAgentTokenResponse]
|
||||
}
|
||||
|
||||
// GetContainer calls mantrae.v1.AgentService.GetContainer.
|
||||
func (c *agentServiceClient) GetContainer(ctx context.Context, req *connect.Request[v1.GetContainerRequest]) (*connect.Response[v1.GetContainerResponse], error) {
|
||||
return c.getContainer.CallUnary(ctx, req)
|
||||
// GetAgent calls mantrae.v1.AgentService.GetAgent.
|
||||
func (c *agentServiceClient) GetAgent(ctx context.Context, req *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) {
|
||||
return c.getAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateAgent calls mantrae.v1.AgentService.CreateAgent.
|
||||
func (c *agentServiceClient) CreateAgent(ctx context.Context, req *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error) {
|
||||
return c.createAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateAgentIP calls mantrae.v1.AgentService.UpdateAgentIP.
|
||||
func (c *agentServiceClient) UpdateAgentIP(ctx context.Context, req *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error) {
|
||||
return c.updateAgentIP.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteAgent calls mantrae.v1.AgentService.DeleteAgent.
|
||||
func (c *agentServiceClient) DeleteAgent(ctx context.Context, req *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error) {
|
||||
return c.deleteAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListAgents calls mantrae.v1.AgentService.ListAgents.
|
||||
func (c *agentServiceClient) ListAgents(ctx context.Context, req *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) {
|
||||
return c.listAgents.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// HealthCheck calls mantrae.v1.AgentService.HealthCheck.
|
||||
@@ -89,10 +175,26 @@ func (c *agentServiceClient) HealthCheck(ctx context.Context, req *connect.Reque
|
||||
return c.healthCheck.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// BootstrapAgent calls mantrae.v1.AgentService.BootstrapAgent.
|
||||
func (c *agentServiceClient) BootstrapAgent(ctx context.Context, req *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error) {
|
||||
return c.bootstrapAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// RotateAgentToken calls mantrae.v1.AgentService.RotateAgentToken.
|
||||
func (c *agentServiceClient) RotateAgentToken(ctx context.Context, req *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error) {
|
||||
return c.rotateAgentToken.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AgentServiceHandler is an implementation of the mantrae.v1.AgentService service.
|
||||
type AgentServiceHandler interface {
|
||||
GetContainer(context.Context, *connect.Request[v1.GetContainerRequest]) (*connect.Response[v1.GetContainerResponse], error)
|
||||
GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error)
|
||||
CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error)
|
||||
UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error)
|
||||
DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error)
|
||||
ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error)
|
||||
HealthCheck(context.Context, *connect.Request[v1.HealthCheckRequest]) (*connect.Response[v1.HealthCheckResponse], error)
|
||||
BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error)
|
||||
RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error)
|
||||
}
|
||||
|
||||
// NewAgentServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
@@ -102,10 +204,36 @@ type AgentServiceHandler interface {
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
agentServiceMethods := v1.File_mantrae_v1_agent_proto.Services().ByName("AgentService").Methods()
|
||||
agentServiceGetContainerHandler := connect.NewUnaryHandler(
|
||||
AgentServiceGetContainerProcedure,
|
||||
svc.GetContainer,
|
||||
connect.WithSchema(agentServiceMethods.ByName("GetContainer")),
|
||||
agentServiceGetAgentHandler := connect.NewUnaryHandler(
|
||||
AgentServiceGetAgentProcedure,
|
||||
svc.GetAgent,
|
||||
connect.WithSchema(agentServiceMethods.ByName("GetAgent")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceCreateAgentHandler := connect.NewUnaryHandler(
|
||||
AgentServiceCreateAgentProcedure,
|
||||
svc.CreateAgent,
|
||||
connect.WithSchema(agentServiceMethods.ByName("CreateAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceUpdateAgentIPHandler := connect.NewUnaryHandler(
|
||||
AgentServiceUpdateAgentIPProcedure,
|
||||
svc.UpdateAgentIP,
|
||||
connect.WithSchema(agentServiceMethods.ByName("UpdateAgentIP")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceDeleteAgentHandler := connect.NewUnaryHandler(
|
||||
AgentServiceDeleteAgentProcedure,
|
||||
svc.DeleteAgent,
|
||||
connect.WithSchema(agentServiceMethods.ByName("DeleteAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceListAgentsHandler := connect.NewUnaryHandler(
|
||||
AgentServiceListAgentsProcedure,
|
||||
svc.ListAgents,
|
||||
connect.WithSchema(agentServiceMethods.ByName("ListAgents")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceHealthCheckHandler := connect.NewUnaryHandler(
|
||||
@@ -114,12 +242,36 @@ func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOpti
|
||||
connect.WithSchema(agentServiceMethods.ByName("HealthCheck")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceBootstrapAgentHandler := connect.NewUnaryHandler(
|
||||
AgentServiceBootstrapAgentProcedure,
|
||||
svc.BootstrapAgent,
|
||||
connect.WithSchema(agentServiceMethods.ByName("BootstrapAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentServiceRotateAgentTokenHandler := connect.NewUnaryHandler(
|
||||
AgentServiceRotateAgentTokenProcedure,
|
||||
svc.RotateAgentToken,
|
||||
connect.WithSchema(agentServiceMethods.ByName("RotateAgentToken")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/mantrae.v1.AgentService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case AgentServiceGetContainerProcedure:
|
||||
agentServiceGetContainerHandler.ServeHTTP(w, r)
|
||||
case AgentServiceGetAgentProcedure:
|
||||
agentServiceGetAgentHandler.ServeHTTP(w, r)
|
||||
case AgentServiceCreateAgentProcedure:
|
||||
agentServiceCreateAgentHandler.ServeHTTP(w, r)
|
||||
case AgentServiceUpdateAgentIPProcedure:
|
||||
agentServiceUpdateAgentIPHandler.ServeHTTP(w, r)
|
||||
case AgentServiceDeleteAgentProcedure:
|
||||
agentServiceDeleteAgentHandler.ServeHTTP(w, r)
|
||||
case AgentServiceListAgentsProcedure:
|
||||
agentServiceListAgentsHandler.ServeHTTP(w, r)
|
||||
case AgentServiceHealthCheckProcedure:
|
||||
agentServiceHealthCheckHandler.ServeHTTP(w, r)
|
||||
case AgentServiceBootstrapAgentProcedure:
|
||||
agentServiceBootstrapAgentHandler.ServeHTTP(w, r)
|
||||
case AgentServiceRotateAgentTokenProcedure:
|
||||
agentServiceRotateAgentTokenHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
@@ -129,10 +281,34 @@ func NewAgentServiceHandler(svc AgentServiceHandler, opts ...connect.HandlerOpti
|
||||
// UnimplementedAgentServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedAgentServiceHandler struct{}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) GetContainer(context.Context, *connect.Request[v1.GetContainerRequest]) (*connect.Response[v1.GetContainerResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.GetContainer is not implemented"))
|
||||
func (UnimplementedAgentServiceHandler) GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.GetAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.CreateAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.UpdateAgentIP is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.DeleteAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.ListAgents is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) HealthCheck(context.Context, *connect.Request[v1.HealthCheckRequest]) (*connect.Response[v1.HealthCheckResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.HealthCheck is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.BootstrapAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentServiceHandler) RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentService.RotateAgentToken is not implemented"))
|
||||
}
|
||||
|
||||
@@ -1,288 +0,0 @@
|
||||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: mantrae/v1/agent_management.proto
|
||||
|
||||
package mantraev1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// AgentManagementServiceName is the fully-qualified name of the AgentManagementService service.
|
||||
AgentManagementServiceName = "mantrae.v1.AgentManagementService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// AgentManagementServiceGetAgentProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's GetAgent RPC.
|
||||
AgentManagementServiceGetAgentProcedure = "/mantrae.v1.AgentManagementService/GetAgent"
|
||||
// AgentManagementServiceCreateAgentProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's CreateAgent RPC.
|
||||
AgentManagementServiceCreateAgentProcedure = "/mantrae.v1.AgentManagementService/CreateAgent"
|
||||
// AgentManagementServiceUpdateAgentIPProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's UpdateAgentIP RPC.
|
||||
AgentManagementServiceUpdateAgentIPProcedure = "/mantrae.v1.AgentManagementService/UpdateAgentIP"
|
||||
// AgentManagementServiceDeleteAgentProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's DeleteAgent RPC.
|
||||
AgentManagementServiceDeleteAgentProcedure = "/mantrae.v1.AgentManagementService/DeleteAgent"
|
||||
// AgentManagementServiceListAgentsProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's ListAgents RPC.
|
||||
AgentManagementServiceListAgentsProcedure = "/mantrae.v1.AgentManagementService/ListAgents"
|
||||
// AgentManagementServiceRotateAgentTokenProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's RotateAgentToken RPC.
|
||||
AgentManagementServiceRotateAgentTokenProcedure = "/mantrae.v1.AgentManagementService/RotateAgentToken"
|
||||
// AgentManagementServiceBootstrapAgentProcedure is the fully-qualified name of the
|
||||
// AgentManagementService's BootstrapAgent RPC.
|
||||
AgentManagementServiceBootstrapAgentProcedure = "/mantrae.v1.AgentManagementService/BootstrapAgent"
|
||||
)
|
||||
|
||||
// AgentManagementServiceClient is a client for the mantrae.v1.AgentManagementService service.
|
||||
type AgentManagementServiceClient interface {
|
||||
GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error)
|
||||
CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error)
|
||||
UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error)
|
||||
DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error)
|
||||
ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error)
|
||||
RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error)
|
||||
BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error)
|
||||
}
|
||||
|
||||
// NewAgentManagementServiceClient constructs a client for the mantrae.v1.AgentManagementService
|
||||
// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for
|
||||
// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply
|
||||
// the connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewAgentManagementServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AgentManagementServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
agentManagementServiceMethods := v1.File_mantrae_v1_agent_management_proto.Services().ByName("AgentManagementService").Methods()
|
||||
return &agentManagementServiceClient{
|
||||
getAgent: connect.NewClient[v1.GetAgentRequest, v1.GetAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceGetAgentProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("GetAgent")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createAgent: connect.NewClient[v1.CreateAgentRequest, v1.CreateAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceCreateAgentProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("CreateAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateAgentIP: connect.NewClient[v1.UpdateAgentIPRequest, v1.UpdateAgentIPResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceUpdateAgentIPProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("UpdateAgentIP")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteAgent: connect.NewClient[v1.DeleteAgentRequest, v1.DeleteAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceDeleteAgentProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("DeleteAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listAgents: connect.NewClient[v1.ListAgentsRequest, v1.ListAgentsResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceListAgentsProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("ListAgents")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
rotateAgentToken: connect.NewClient[v1.RotateAgentTokenRequest, v1.RotateAgentTokenResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceRotateAgentTokenProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("RotateAgentToken")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
bootstrapAgent: connect.NewClient[v1.BootstrapAgentRequest, v1.BootstrapAgentResponse](
|
||||
httpClient,
|
||||
baseURL+AgentManagementServiceBootstrapAgentProcedure,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("BootstrapAgent")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// agentManagementServiceClient implements AgentManagementServiceClient.
|
||||
type agentManagementServiceClient struct {
|
||||
getAgent *connect.Client[v1.GetAgentRequest, v1.GetAgentResponse]
|
||||
createAgent *connect.Client[v1.CreateAgentRequest, v1.CreateAgentResponse]
|
||||
updateAgentIP *connect.Client[v1.UpdateAgentIPRequest, v1.UpdateAgentIPResponse]
|
||||
deleteAgent *connect.Client[v1.DeleteAgentRequest, v1.DeleteAgentResponse]
|
||||
listAgents *connect.Client[v1.ListAgentsRequest, v1.ListAgentsResponse]
|
||||
rotateAgentToken *connect.Client[v1.RotateAgentTokenRequest, v1.RotateAgentTokenResponse]
|
||||
bootstrapAgent *connect.Client[v1.BootstrapAgentRequest, v1.BootstrapAgentResponse]
|
||||
}
|
||||
|
||||
// GetAgent calls mantrae.v1.AgentManagementService.GetAgent.
|
||||
func (c *agentManagementServiceClient) GetAgent(ctx context.Context, req *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) {
|
||||
return c.getAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateAgent calls mantrae.v1.AgentManagementService.CreateAgent.
|
||||
func (c *agentManagementServiceClient) CreateAgent(ctx context.Context, req *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error) {
|
||||
return c.createAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateAgentIP calls mantrae.v1.AgentManagementService.UpdateAgentIP.
|
||||
func (c *agentManagementServiceClient) UpdateAgentIP(ctx context.Context, req *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error) {
|
||||
return c.updateAgentIP.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteAgent calls mantrae.v1.AgentManagementService.DeleteAgent.
|
||||
func (c *agentManagementServiceClient) DeleteAgent(ctx context.Context, req *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error) {
|
||||
return c.deleteAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListAgents calls mantrae.v1.AgentManagementService.ListAgents.
|
||||
func (c *agentManagementServiceClient) ListAgents(ctx context.Context, req *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) {
|
||||
return c.listAgents.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// RotateAgentToken calls mantrae.v1.AgentManagementService.RotateAgentToken.
|
||||
func (c *agentManagementServiceClient) RotateAgentToken(ctx context.Context, req *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error) {
|
||||
return c.rotateAgentToken.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// BootstrapAgent calls mantrae.v1.AgentManagementService.BootstrapAgent.
|
||||
func (c *agentManagementServiceClient) BootstrapAgent(ctx context.Context, req *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error) {
|
||||
return c.bootstrapAgent.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AgentManagementServiceHandler is an implementation of the mantrae.v1.AgentManagementService
|
||||
// service.
|
||||
type AgentManagementServiceHandler interface {
|
||||
GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error)
|
||||
CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error)
|
||||
UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error)
|
||||
DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error)
|
||||
ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error)
|
||||
RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error)
|
||||
BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error)
|
||||
}
|
||||
|
||||
// NewAgentManagementServiceHandler builds an HTTP handler from the service implementation. It
|
||||
// returns the path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewAgentManagementServiceHandler(svc AgentManagementServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
agentManagementServiceMethods := v1.File_mantrae_v1_agent_management_proto.Services().ByName("AgentManagementService").Methods()
|
||||
agentManagementServiceGetAgentHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceGetAgentProcedure,
|
||||
svc.GetAgent,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("GetAgent")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceCreateAgentHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceCreateAgentProcedure,
|
||||
svc.CreateAgent,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("CreateAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceUpdateAgentIPHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceUpdateAgentIPProcedure,
|
||||
svc.UpdateAgentIP,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("UpdateAgentIP")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceDeleteAgentHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceDeleteAgentProcedure,
|
||||
svc.DeleteAgent,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("DeleteAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceListAgentsHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceListAgentsProcedure,
|
||||
svc.ListAgents,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("ListAgents")),
|
||||
connect.WithIdempotency(connect.IdempotencyNoSideEffects),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceRotateAgentTokenHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceRotateAgentTokenProcedure,
|
||||
svc.RotateAgentToken,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("RotateAgentToken")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
agentManagementServiceBootstrapAgentHandler := connect.NewUnaryHandler(
|
||||
AgentManagementServiceBootstrapAgentProcedure,
|
||||
svc.BootstrapAgent,
|
||||
connect.WithSchema(agentManagementServiceMethods.ByName("BootstrapAgent")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/mantrae.v1.AgentManagementService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case AgentManagementServiceGetAgentProcedure:
|
||||
agentManagementServiceGetAgentHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceCreateAgentProcedure:
|
||||
agentManagementServiceCreateAgentHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceUpdateAgentIPProcedure:
|
||||
agentManagementServiceUpdateAgentIPHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceDeleteAgentProcedure:
|
||||
agentManagementServiceDeleteAgentHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceListAgentsProcedure:
|
||||
agentManagementServiceListAgentsHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceRotateAgentTokenProcedure:
|
||||
agentManagementServiceRotateAgentTokenHandler.ServeHTTP(w, r)
|
||||
case AgentManagementServiceBootstrapAgentProcedure:
|
||||
agentManagementServiceBootstrapAgentHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedAgentManagementServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedAgentManagementServiceHandler struct{}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) GetAgent(context.Context, *connect.Request[v1.GetAgentRequest]) (*connect.Response[v1.GetAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.GetAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) CreateAgent(context.Context, *connect.Request[v1.CreateAgentRequest]) (*connect.Response[v1.CreateAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.CreateAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) UpdateAgentIP(context.Context, *connect.Request[v1.UpdateAgentIPRequest]) (*connect.Response[v1.UpdateAgentIPResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.UpdateAgentIP is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) DeleteAgent(context.Context, *connect.Request[v1.DeleteAgentRequest]) (*connect.Response[v1.DeleteAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.DeleteAgent is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) ListAgents(context.Context, *connect.Request[v1.ListAgentsRequest]) (*connect.Response[v1.ListAgentsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.ListAgents is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) RotateAgentToken(context.Context, *connect.Request[v1.RotateAgentTokenRequest]) (*connect.Response[v1.RotateAgentTokenResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.RotateAgentToken is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAgentManagementServiceHandler) BootstrapAgent(context.Context, *connect.Request[v1.BootstrapAgentRequest]) (*connect.Response[v1.BootstrapAgentResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.AgentManagementService.BootstrapAgent is not implemented"))
|
||||
}
|
||||
@@ -129,6 +129,68 @@ components:
|
||||
the Joda Time's [`ISODateTimeFormat.dateTime()`](
|
||||
http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()
|
||||
) to obtain a formatter capable of generating timestamps in this format.
|
||||
mantrae.v1.Agent:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
title: id
|
||||
profileId:
|
||||
type:
|
||||
- integer
|
||||
- string
|
||||
title: profile_id
|
||||
format: int64
|
||||
hostname:
|
||||
type: string
|
||||
title: hostname
|
||||
publicIp:
|
||||
type: string
|
||||
title: public_ip
|
||||
privateIp:
|
||||
type: string
|
||||
title: private_ip
|
||||
activeIp:
|
||||
type: string
|
||||
title: active_ip
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
containers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/mantrae.v1.Container'
|
||||
title: containers
|
||||
createdAt:
|
||||
title: created_at
|
||||
$ref: '#/components/schemas/google.protobuf.Timestamp'
|
||||
updatedAt:
|
||||
title: updated_at
|
||||
$ref: '#/components/schemas/google.protobuf.Timestamp'
|
||||
title: Agent
|
||||
additionalProperties: false
|
||||
mantrae.v1.BootstrapAgentRequest:
|
||||
type: object
|
||||
properties:
|
||||
profileId:
|
||||
type:
|
||||
- integer
|
||||
- string
|
||||
title: profile_id
|
||||
format: int64
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: BootstrapAgentRequest
|
||||
additionalProperties: false
|
||||
mantrae.v1.BootstrapAgentResponse:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: BootstrapAgentResponse
|
||||
additionalProperties: false
|
||||
mantrae.v1.Container:
|
||||
type: object
|
||||
properties:
|
||||
@@ -186,170 +248,6 @@ components:
|
||||
format: int32
|
||||
title: PortmapEntry
|
||||
additionalProperties: false
|
||||
mantrae.v1.GetContainerRequest:
|
||||
type: object
|
||||
properties:
|
||||
hostname:
|
||||
type: string
|
||||
title: hostname
|
||||
publicIp:
|
||||
type: string
|
||||
title: public_ip
|
||||
privateIps:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
title: private_ips
|
||||
containers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/mantrae.v1.Container'
|
||||
title: containers
|
||||
updated:
|
||||
title: updated
|
||||
$ref: '#/components/schemas/google.protobuf.Timestamp'
|
||||
title: GetContainerRequest
|
||||
additionalProperties: false
|
||||
mantrae.v1.GetContainerResponse:
|
||||
type: object
|
||||
title: GetContainerResponse
|
||||
additionalProperties: false
|
||||
mantrae.v1.HealthCheckRequest:
|
||||
type: object
|
||||
title: HealthCheckRequest
|
||||
additionalProperties: false
|
||||
mantrae.v1.HealthCheckResponse:
|
||||
type: object
|
||||
properties:
|
||||
ok:
|
||||
type: boolean
|
||||
title: ok
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: HealthCheckResponse
|
||||
additionalProperties: false
|
||||
connect-protocol-version:
|
||||
type: number
|
||||
title: Connect-Protocol-Version
|
||||
enum:
|
||||
- 1
|
||||
description: Define the version of the Connect protocol
|
||||
const: 1
|
||||
connect-timeout-header:
|
||||
type: number
|
||||
title: Connect-Timeout-Ms
|
||||
description: Define the timeout, in ms
|
||||
connect.error:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
examples:
|
||||
- not_found
|
||||
enum:
|
||||
- canceled
|
||||
- unknown
|
||||
- invalid_argument
|
||||
- deadline_exceeded
|
||||
- not_found
|
||||
- already_exists
|
||||
- permission_denied
|
||||
- resource_exhausted
|
||||
- failed_precondition
|
||||
- aborted
|
||||
- out_of_range
|
||||
- unimplemented
|
||||
- internal
|
||||
- unavailable
|
||||
- data_loss
|
||||
- unauthenticated
|
||||
description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
|
||||
message:
|
||||
type: string
|
||||
description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
|
||||
detail:
|
||||
$ref: '#/components/schemas/google.protobuf.Any'
|
||||
title: Connect Error
|
||||
additionalProperties: true
|
||||
description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation'
|
||||
google.protobuf.Any:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
format: binary
|
||||
debug:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
additionalProperties: true
|
||||
description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
|
||||
mantrae.v1.Agent:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
title: id
|
||||
profileId:
|
||||
type:
|
||||
- integer
|
||||
- string
|
||||
title: profile_id
|
||||
format: int64
|
||||
hostname:
|
||||
type: string
|
||||
title: hostname
|
||||
publicIp:
|
||||
type: string
|
||||
title: public_ip
|
||||
activeIp:
|
||||
type: string
|
||||
title: active_ip
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
privateIps:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
title: private_ips
|
||||
containers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/mantrae.v1.Container'
|
||||
title: containers
|
||||
createdAt:
|
||||
title: created_at
|
||||
$ref: '#/components/schemas/google.protobuf.Timestamp'
|
||||
updatedAt:
|
||||
title: updated_at
|
||||
$ref: '#/components/schemas/google.protobuf.Timestamp'
|
||||
title: Agent
|
||||
additionalProperties: false
|
||||
mantrae.v1.BootstrapAgentRequest:
|
||||
type: object
|
||||
properties:
|
||||
profileId:
|
||||
type:
|
||||
- integer
|
||||
- string
|
||||
title: profile_id
|
||||
format: int64
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: BootstrapAgentRequest
|
||||
additionalProperties: false
|
||||
mantrae.v1.BootstrapAgentResponse:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
title: token
|
||||
title: BootstrapAgentResponse
|
||||
additionalProperties: false
|
||||
mantrae.v1.CreateAgentRequest:
|
||||
type: object
|
||||
properties:
|
||||
@@ -397,6 +295,25 @@ components:
|
||||
$ref: '#/components/schemas/mantrae.v1.Agent'
|
||||
title: GetAgentResponse
|
||||
additionalProperties: false
|
||||
mantrae.v1.HealthCheckRequest:
|
||||
type: object
|
||||
properties:
|
||||
publicIp:
|
||||
type: string
|
||||
title: public_ip
|
||||
privateIp:
|
||||
type: string
|
||||
title: private_ip
|
||||
title: HealthCheckRequest
|
||||
additionalProperties: false
|
||||
mantrae.v1.HealthCheckResponse:
|
||||
type: object
|
||||
properties:
|
||||
agent:
|
||||
title: agent
|
||||
$ref: '#/components/schemas/mantrae.v1.Agent'
|
||||
title: HealthCheckResponse
|
||||
additionalProperties: false
|
||||
mantrae.v1.ListAgentsRequest:
|
||||
type: object
|
||||
properties:
|
||||
@@ -495,6 +412,63 @@ components:
|
||||
enum:
|
||||
- v1
|
||||
description: Define the version of the Connect protocol
|
||||
connect-protocol-version:
|
||||
type: number
|
||||
title: Connect-Protocol-Version
|
||||
enum:
|
||||
- 1
|
||||
description: Define the version of the Connect protocol
|
||||
const: 1
|
||||
connect-timeout-header:
|
||||
type: number
|
||||
title: Connect-Timeout-Ms
|
||||
description: Define the timeout, in ms
|
||||
connect.error:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
examples:
|
||||
- not_found
|
||||
enum:
|
||||
- canceled
|
||||
- unknown
|
||||
- invalid_argument
|
||||
- deadline_exceeded
|
||||
- not_found
|
||||
- already_exists
|
||||
- permission_denied
|
||||
- resource_exhausted
|
||||
- failed_precondition
|
||||
- aborted
|
||||
- out_of_range
|
||||
- unimplemented
|
||||
- internal
|
||||
- unavailable
|
||||
- data_loss
|
||||
- unauthenticated
|
||||
description: The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
|
||||
message:
|
||||
type: string
|
||||
description: A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
|
||||
detail:
|
||||
$ref: '#/components/schemas/google.protobuf.Any'
|
||||
title: Connect Error
|
||||
additionalProperties: true
|
||||
description: 'Error type returned by Connect: https://connectrpc.com/docs/go/errors/#http-representation'
|
||||
google.protobuf.Any:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
format: binary
|
||||
debug:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
additionalProperties: true
|
||||
description: Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
|
||||
mantrae.v1.Backup:
|
||||
type: object
|
||||
properties:
|
||||
@@ -2179,82 +2153,12 @@ components:
|
||||
security:
|
||||
- BearerAuth: []
|
||||
paths:
|
||||
/mantrae.v1.AgentService/GetContainer:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentService
|
||||
summary: GetContainer
|
||||
operationId: mantrae.v1.AgentService.GetContainer
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-protocol-version'
|
||||
- name: Connect-Timeout-Ms
|
||||
in: header
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-timeout-header'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.GetContainerRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
description: Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect.error'
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.GetContainerResponse'
|
||||
/mantrae.v1.AgentService/HealthCheck:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentService
|
||||
summary: HealthCheck
|
||||
operationId: mantrae.v1.AgentService.HealthCheck
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-protocol-version'
|
||||
- name: Connect-Timeout-Ms
|
||||
in: header
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-timeout-header'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.HealthCheckRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
description: Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect.error'
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.HealthCheckResponse'
|
||||
/mantrae.v1.AgentManagementService/GetAgent:
|
||||
/mantrae.v1.AgentService/GetAgent:
|
||||
get:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: GetAgent
|
||||
operationId: mantrae.v1.AgentManagementService.GetAgent.get
|
||||
operationId: mantrae.v1.AgentService.GetAgent.get
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2303,9 +2207,9 @@ paths:
|
||||
$ref: '#/components/schemas/mantrae.v1.GetAgentResponse'
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: GetAgent
|
||||
operationId: mantrae.v1.AgentManagementService.GetAgent
|
||||
operationId: mantrae.v1.AgentService.GetAgent
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2335,12 +2239,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.GetAgentResponse'
|
||||
/mantrae.v1.AgentManagementService/CreateAgent:
|
||||
/mantrae.v1.AgentService/CreateAgent:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: CreateAgent
|
||||
operationId: mantrae.v1.AgentManagementService.CreateAgent
|
||||
operationId: mantrae.v1.AgentService.CreateAgent
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2370,12 +2274,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.CreateAgentResponse'
|
||||
/mantrae.v1.AgentManagementService/UpdateAgentIP:
|
||||
/mantrae.v1.AgentService/UpdateAgentIP:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: UpdateAgentIP
|
||||
operationId: mantrae.v1.AgentManagementService.UpdateAgentIP
|
||||
operationId: mantrae.v1.AgentService.UpdateAgentIP
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2405,12 +2309,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.UpdateAgentIPResponse'
|
||||
/mantrae.v1.AgentManagementService/DeleteAgent:
|
||||
/mantrae.v1.AgentService/DeleteAgent:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: DeleteAgent
|
||||
operationId: mantrae.v1.AgentManagementService.DeleteAgent
|
||||
operationId: mantrae.v1.AgentService.DeleteAgent
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2440,12 +2344,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.DeleteAgentResponse'
|
||||
/mantrae.v1.AgentManagementService/ListAgents:
|
||||
/mantrae.v1.AgentService/ListAgents:
|
||||
get:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: ListAgents
|
||||
operationId: mantrae.v1.AgentManagementService.ListAgents.get
|
||||
operationId: mantrae.v1.AgentService.ListAgents.get
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2494,9 +2398,9 @@ paths:
|
||||
$ref: '#/components/schemas/mantrae.v1.ListAgentsResponse'
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: ListAgents
|
||||
operationId: mantrae.v1.AgentManagementService.ListAgents
|
||||
operationId: mantrae.v1.AgentService.ListAgents
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2526,12 +2430,12 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.ListAgentsResponse'
|
||||
/mantrae.v1.AgentManagementService/RotateAgentToken:
|
||||
/mantrae.v1.AgentService/HealthCheck:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
summary: RotateAgentToken
|
||||
operationId: mantrae.v1.AgentManagementService.RotateAgentToken
|
||||
- mantrae.v1.AgentService
|
||||
summary: HealthCheck
|
||||
operationId: mantrae.v1.AgentService.HealthCheck
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2546,7 +2450,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.RotateAgentTokenRequest'
|
||||
$ref: '#/components/schemas/mantrae.v1.HealthCheckRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
@@ -2560,13 +2464,13 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.RotateAgentTokenResponse'
|
||||
/mantrae.v1.AgentManagementService/BootstrapAgent:
|
||||
$ref: '#/components/schemas/mantrae.v1.HealthCheckResponse'
|
||||
/mantrae.v1.AgentService/BootstrapAgent:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentManagementService
|
||||
- mantrae.v1.AgentService
|
||||
summary: BootstrapAgent
|
||||
operationId: mantrae.v1.AgentManagementService.BootstrapAgent
|
||||
operationId: mantrae.v1.AgentService.BootstrapAgent
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
@@ -2596,6 +2500,41 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.BootstrapAgentResponse'
|
||||
/mantrae.v1.AgentService/RotateAgentToken:
|
||||
post:
|
||||
tags:
|
||||
- mantrae.v1.AgentService
|
||||
summary: RotateAgentToken
|
||||
operationId: mantrae.v1.AgentService.RotateAgentToken
|
||||
parameters:
|
||||
- name: Connect-Protocol-Version
|
||||
in: header
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-protocol-version'
|
||||
- name: Connect-Timeout-Ms
|
||||
in: header
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect-timeout-header'
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.RotateAgentTokenRequest'
|
||||
required: true
|
||||
responses:
|
||||
default:
|
||||
description: Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/connect.error'
|
||||
"200":
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/mantrae.v1.RotateAgentTokenResponse'
|
||||
/mantrae.v1.BackupService/CreateBackup:
|
||||
post:
|
||||
tags:
|
||||
@@ -5427,7 +5366,6 @@ paths:
|
||||
$ref: '#/components/schemas/mantrae.v1.GetPublicIPResponse'
|
||||
tags:
|
||||
- name: mantrae.v1.AgentService
|
||||
- name: mantrae.v1.AgentManagementService
|
||||
- name: mantrae.v1.BackupService
|
||||
- name: mantrae.v1.DnsProviderService
|
||||
- name: mantrae.v1.EntryPointService
|
||||
|
||||
@@ -5,8 +5,31 @@ package mantrae.v1;
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
service AgentService {
|
||||
rpc GetContainer(GetContainerRequest) returns (GetContainerResponse);
|
||||
rpc GetAgent(GetAgentRequest) returns (GetAgentResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
rpc CreateAgent(CreateAgentRequest) returns (CreateAgentResponse);
|
||||
rpc UpdateAgentIP(UpdateAgentIPRequest) returns (UpdateAgentIPResponse);
|
||||
rpc DeleteAgent(DeleteAgentRequest) returns (DeleteAgentResponse);
|
||||
rpc ListAgents(ListAgentsRequest) returns (ListAgentsResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);
|
||||
rpc BootstrapAgent(BootstrapAgentRequest) returns (BootstrapAgentResponse);
|
||||
rpc RotateAgentToken(RotateAgentTokenRequest) returns (RotateAgentTokenResponse);
|
||||
}
|
||||
|
||||
message Agent {
|
||||
string id = 1;
|
||||
int64 profile_id = 2;
|
||||
string hostname = 3;
|
||||
string public_ip = 4;
|
||||
string private_ip = 5;
|
||||
string active_ip = 6;
|
||||
string token = 7;
|
||||
repeated Container containers = 8;
|
||||
google.protobuf.Timestamp created_at = 9;
|
||||
google.protobuf.Timestamp updated_at = 10;
|
||||
}
|
||||
|
||||
message Container {
|
||||
@@ -19,17 +42,62 @@ message Container {
|
||||
google.protobuf.Timestamp created = 7;
|
||||
}
|
||||
|
||||
message GetContainerRequest {
|
||||
string hostname = 1;
|
||||
string public_ip = 2;
|
||||
repeated string private_ips = 3;
|
||||
repeated Container containers = 4;
|
||||
google.protobuf.Timestamp updated = 5;
|
||||
message GetAgentRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message GetAgentResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
message GetContainerResponse {}
|
||||
|
||||
message HealthCheckRequest {}
|
||||
message CreateAgentRequest {
|
||||
int64 profile_id = 1;
|
||||
}
|
||||
message CreateAgentResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message UpdateAgentIPRequest {
|
||||
string id = 1;
|
||||
string ip = 2;
|
||||
}
|
||||
message UpdateAgentIPResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message DeleteAgentRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message DeleteAgentResponse {}
|
||||
|
||||
message ListAgentsRequest {
|
||||
int64 profile_id = 1;
|
||||
optional int64 limit = 2;
|
||||
optional int64 offset = 3;
|
||||
}
|
||||
message ListAgentsResponse {
|
||||
repeated Agent agents = 1;
|
||||
int64 total_count = 2;
|
||||
}
|
||||
|
||||
message HealthCheckRequest {
|
||||
string public_ip = 1;
|
||||
string private_ip = 2;
|
||||
}
|
||||
message HealthCheckResponse {
|
||||
bool ok = 1;
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message RotateAgentTokenRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message RotateAgentTokenResponse {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message BootstrapAgentRequest {
|
||||
int64 profile_id = 1;
|
||||
string token = 2;
|
||||
}
|
||||
message BootstrapAgentResponse {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package mantrae.v1;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "mantrae/v1/agent.proto";
|
||||
|
||||
service AgentManagementService {
|
||||
rpc GetAgent(GetAgentRequest) returns (GetAgentResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
rpc CreateAgent(CreateAgentRequest) returns (CreateAgentResponse);
|
||||
rpc UpdateAgentIP(UpdateAgentIPRequest) returns (UpdateAgentIPResponse);
|
||||
rpc DeleteAgent(DeleteAgentRequest) returns (DeleteAgentResponse);
|
||||
rpc ListAgents(ListAgentsRequest) returns (ListAgentsResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
rpc RotateAgentToken(RotateAgentTokenRequest) returns (RotateAgentTokenResponse);
|
||||
rpc BootstrapAgent(BootstrapAgentRequest) returns (BootstrapAgentResponse);
|
||||
}
|
||||
|
||||
message Agent {
|
||||
string id = 1;
|
||||
int64 profile_id = 2;
|
||||
string hostname = 3;
|
||||
string public_ip = 4;
|
||||
string active_ip = 5;
|
||||
string token = 6;
|
||||
repeated string private_ips = 7;
|
||||
repeated Container containers = 8;
|
||||
google.protobuf.Timestamp created_at = 9;
|
||||
google.protobuf.Timestamp updated_at = 10;
|
||||
}
|
||||
|
||||
message GetAgentRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message GetAgentResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message CreateAgentRequest {
|
||||
int64 profile_id = 1;
|
||||
}
|
||||
message CreateAgentResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message UpdateAgentIPRequest {
|
||||
string id = 1;
|
||||
string ip = 2;
|
||||
}
|
||||
message UpdateAgentIPResponse {
|
||||
Agent agent = 1;
|
||||
}
|
||||
|
||||
message DeleteAgentRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message DeleteAgentResponse {}
|
||||
|
||||
message ListAgentsRequest {
|
||||
int64 profile_id = 1;
|
||||
optional int64 limit = 2;
|
||||
optional int64 offset = 3;
|
||||
}
|
||||
message ListAgentsResponse {
|
||||
repeated Agent agents = 1;
|
||||
int64 total_count = 2;
|
||||
}
|
||||
|
||||
message RotateAgentTokenRequest {
|
||||
string id = 1;
|
||||
}
|
||||
message RotateAgentTokenResponse {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message BootstrapAgentRequest {
|
||||
int64 profile_id = 1;
|
||||
string token = 2;
|
||||
}
|
||||
message BootstrapAgentResponse {
|
||||
string token = 1;
|
||||
}
|
||||
@@ -10,11 +10,11 @@ import { ServiceService } from './gen/mantrae/v1/service_pb';
|
||||
import { MiddlewareService } from './gen/mantrae/v1/middleware_pb';
|
||||
import { SettingService } from './gen/mantrae/v1/setting_pb';
|
||||
import { BackupService } from './gen/mantrae/v1/backup_pb';
|
||||
import { AgentManagementService } from './gen/mantrae/v1/agent_management_pb';
|
||||
import { EntryPointService } from './gen/mantrae/v1/entry_point_pb';
|
||||
import { DnsProviderService } from './gen/mantrae/v1/dns_provider_pb';
|
||||
import { UtilService } from './gen/mantrae/v1/util_pb';
|
||||
import { user } from './stores/user';
|
||||
import { AgentService } from './gen/mantrae/v1/agent_pb';
|
||||
|
||||
// Global state variables
|
||||
export const BACKEND_PORT = import.meta.env.PORT || 3000;
|
||||
@@ -52,7 +52,7 @@ export const profileClient = useClient(ProfileService);
|
||||
export const userClient = useClient(UserService);
|
||||
export const entryPointClient = useClient(EntryPointService);
|
||||
export const dnsClient = useClient(DnsProviderService);
|
||||
export const agentClient = useClient(AgentManagementService);
|
||||
export const agentClient = useClient(AgentService);
|
||||
export const routerClient = useClient(RouterService);
|
||||
export const serviceClient = useClient(ServiceService);
|
||||
export const middlewareClient = useClient(MiddlewareService);
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
import CopyButton from '../ui/copy-button/copy-button.svelte';
|
||||
import { DateFormat, pageIndex, pageSize } from '$lib/stores/common';
|
||||
import { RotateCcw } from '@lucide/svelte';
|
||||
import type { Agent } from '$lib/gen/mantrae/v1/agent_management_pb';
|
||||
import { agentClient } from '$lib/api';
|
||||
import { profile } from '$lib/stores/profile';
|
||||
import { ConnectError } from '@connectrpc/connect';
|
||||
import { timestampDate } from '@bufbuild/protobuf/wkt';
|
||||
import type { Agent } from '$lib/gen/mantrae/v1/agent_pb';
|
||||
|
||||
interface Props {
|
||||
data: Agent[];
|
||||
@@ -121,19 +121,17 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if item.privateIps?.length > 0}
|
||||
{#if item.privateIp !== ''}
|
||||
<div class="grid grid-cols-4 items-center gap-2">
|
||||
<Label for="privateip">Private IPs</Label>
|
||||
<div class="col-span-3 flex flex-wrap gap-2">
|
||||
{#each item.privateIps ?? [] as ip (ip)}
|
||||
{#if item.activeIp === ip}
|
||||
<Badge variant="default">{ip ?? 'None'}</Badge>
|
||||
{:else}
|
||||
<button onclick={() => handleSubmit(ip)}>
|
||||
<Badge variant="secondary">{ip}</Badge>
|
||||
</button>
|
||||
{/if}
|
||||
{/each}
|
||||
{#if item.activeIp === item.privateIp}
|
||||
<Badge variant="default">{item.privateIp ?? 'None'}</Badge>
|
||||
{:else}
|
||||
<button onclick={() => handleSubmit(item.privateIp)}>
|
||||
<Badge variant="secondary">{item.privateIp}</Badge>
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,402 +0,0 @@
|
||||
// @generated by protoc-gen-es v2.5.2 with parameter "target=ts"
|
||||
// @generated from file mantrae/v1/agent_management.proto (package mantrae.v1, syntax proto3)
|
||||
/* eslint-disable */
|
||||
|
||||
import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
|
||||
import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2";
|
||||
import type { Timestamp } from "@bufbuild/protobuf/wkt";
|
||||
import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt";
|
||||
import type { Container } from "./agent_pb";
|
||||
import { file_mantrae_v1_agent } from "./agent_pb";
|
||||
import type { Message } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* Describes the file mantrae/v1/agent_management.proto.
|
||||
*/
|
||||
export const file_mantrae_v1_agent_management: GenFile = /*@__PURE__*/
|
||||
fileDesc("CiFtYW50cmFlL3YxL2FnZW50X21hbmFnZW1lbnQucHJvdG8SCm1hbnRyYWUudjEijgIKBUFnZW50EgoKAmlkGAEgASgJEhIKCnByb2ZpbGVfaWQYAiABKAMSEAoIaG9zdG5hbWUYAyABKAkSEQoJcHVibGljX2lwGAQgASgJEhEKCWFjdGl2ZV9pcBgFIAEoCRINCgV0b2tlbhgGIAEoCRITCgtwcml2YXRlX2lwcxgHIAMoCRIpCgpjb250YWluZXJzGAggAygLMhUubWFudHJhZS52MS5Db250YWluZXISLgoKY3JlYXRlZF9hdBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiHQoPR2V0QWdlbnRSZXF1ZXN0EgoKAmlkGAEgASgJIjQKEEdldEFnZW50UmVzcG9uc2USIAoFYWdlbnQYASABKAsyES5tYW50cmFlLnYxLkFnZW50IigKEkNyZWF0ZUFnZW50UmVxdWVzdBISCgpwcm9maWxlX2lkGAEgASgDIjcKE0NyZWF0ZUFnZW50UmVzcG9uc2USIAoFYWdlbnQYASABKAsyES5tYW50cmFlLnYxLkFnZW50Ii4KFFVwZGF0ZUFnZW50SVBSZXF1ZXN0EgoKAmlkGAEgASgJEgoKAmlwGAIgASgJIjkKFVVwZGF0ZUFnZW50SVBSZXNwb25zZRIgCgVhZ2VudBgBIAEoCzIRLm1hbnRyYWUudjEuQWdlbnQiIAoSRGVsZXRlQWdlbnRSZXF1ZXN0EgoKAmlkGAEgASgJIhUKE0RlbGV0ZUFnZW50UmVzcG9uc2UiZQoRTGlzdEFnZW50c1JlcXVlc3QSEgoKcHJvZmlsZV9pZBgBIAEoAxISCgVsaW1pdBgCIAEoA0gAiAEBEhMKBm9mZnNldBgDIAEoA0gBiAEBQggKBl9saW1pdEIJCgdfb2Zmc2V0IkwKEkxpc3RBZ2VudHNSZXNwb25zZRIhCgZhZ2VudHMYASADKAsyES5tYW50cmFlLnYxLkFnZW50EhMKC3RvdGFsX2NvdW50GAIgASgDIiUKF1JvdGF0ZUFnZW50VG9rZW5SZXF1ZXN0EgoKAmlkGAEgASgJIikKGFJvdGF0ZUFnZW50VG9rZW5SZXNwb25zZRINCgV0b2tlbhgBIAEoCSI6ChVCb290c3RyYXBBZ2VudFJlcXVlc3QSEgoKcHJvZmlsZV9pZBgBIAEoAxINCgV0b2tlbhgCIAEoCSInChZCb290c3RyYXBBZ2VudFJlc3BvbnNlEg0KBXRva2VuGAEgASgJMuQEChZBZ2VudE1hbmFnZW1lbnRTZXJ2aWNlEkoKCEdldEFnZW50EhsubWFudHJhZS52MS5HZXRBZ2VudFJlcXVlc3QaHC5tYW50cmFlLnYxLkdldEFnZW50UmVzcG9uc2UiA5ACARJOCgtDcmVhdGVBZ2VudBIeLm1hbnRyYWUudjEuQ3JlYXRlQWdlbnRSZXF1ZXN0Gh8ubWFudHJhZS52MS5DcmVhdGVBZ2VudFJlc3BvbnNlElQKDVVwZGF0ZUFnZW50SVASIC5tYW50cmFlLnYxLlVwZGF0ZUFnZW50SVBSZXF1ZXN0GiEubWFudHJhZS52MS5VcGRhdGVBZ2VudElQUmVzcG9uc2USTgoLRGVsZXRlQWdlbnQSHi5tYW50cmFlLnYxLkRlbGV0ZUFnZW50UmVxdWVzdBofLm1hbnRyYWUudjEuRGVsZXRlQWdlbnRSZXNwb25zZRJQCgpMaXN0QWdlbnRzEh0ubWFudHJhZS52MS5MaXN0QWdlbnRzUmVxdWVzdBoeLm1hbnRyYWUudjEuTGlzdEFnZW50c1Jlc3BvbnNlIgOQAgESXQoQUm90YXRlQWdlbnRUb2tlbhIjLm1hbnRyYWUudjEuUm90YXRlQWdlbnRUb2tlblJlcXVlc3QaJC5tYW50cmFlLnYxLlJvdGF0ZUFnZW50VG9rZW5SZXNwb25zZRJXCg5Cb290c3RyYXBBZ2VudBIhLm1hbnRyYWUudjEuQm9vdHN0cmFwQWdlbnRSZXF1ZXN0GiIubWFudHJhZS52MS5Cb290c3RyYXBBZ2VudFJlc3BvbnNlQq4BCg5jb20ubWFudHJhZS52MUIUQWdlbnRNYW5hZ2VtZW50UHJvdG9QAVo9Z2l0aHViLmNvbS9taXp1Y2hpbGFicy9tYW50cmFlL3Byb3RvL2dlbi9tYW50cmFlL3YxO21hbnRyYWV2MaICA01YWKoCCk1hbnRyYWUuVjHKAgpNYW50cmFlXFYx4gIWTWFudHJhZVxWMVxHUEJNZXRhZGF0YeoCC01hbnRyYWU6OlYxYgZwcm90bzM", [file_google_protobuf_timestamp, file_mantrae_v1_agent]);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.Agent
|
||||
*/
|
||||
export type Agent = Message<"mantrae.v1.Agent"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 2;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: string hostname = 3;
|
||||
*/
|
||||
hostname: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string public_ip = 4;
|
||||
*/
|
||||
publicIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string active_ip = 5;
|
||||
*/
|
||||
activeIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string token = 6;
|
||||
*/
|
||||
token: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string private_ips = 7;
|
||||
*/
|
||||
privateIps: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: repeated mantrae.v1.Container containers = 8;
|
||||
*/
|
||||
containers: Container[];
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp created_at = 9;
|
||||
*/
|
||||
createdAt?: Timestamp;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp updated_at = 10;
|
||||
*/
|
||||
updatedAt?: Timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.Agent.
|
||||
* Use `create(AgentSchema)` to create a new message.
|
||||
*/
|
||||
export const AgentSchema: GenMessage<Agent> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 0);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.GetAgentRequest
|
||||
*/
|
||||
export type GetAgentRequest = Message<"mantrae.v1.GetAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.GetAgentRequest.
|
||||
* Use `create(GetAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const GetAgentRequestSchema: GenMessage<GetAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 1);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.GetAgentResponse
|
||||
*/
|
||||
export type GetAgentResponse = Message<"mantrae.v1.GetAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.GetAgentResponse.
|
||||
* Use `create(GetAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const GetAgentResponseSchema: GenMessage<GetAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 2);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.CreateAgentRequest
|
||||
*/
|
||||
export type CreateAgentRequest = Message<"mantrae.v1.CreateAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.CreateAgentRequest.
|
||||
* Use `create(CreateAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const CreateAgentRequestSchema: GenMessage<CreateAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 3);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.CreateAgentResponse
|
||||
*/
|
||||
export type CreateAgentResponse = Message<"mantrae.v1.CreateAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.CreateAgentResponse.
|
||||
* Use `create(CreateAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const CreateAgentResponseSchema: GenMessage<CreateAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 4);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.UpdateAgentIPRequest
|
||||
*/
|
||||
export type UpdateAgentIPRequest = Message<"mantrae.v1.UpdateAgentIPRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string ip = 2;
|
||||
*/
|
||||
ip: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.UpdateAgentIPRequest.
|
||||
* Use `create(UpdateAgentIPRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const UpdateAgentIPRequestSchema: GenMessage<UpdateAgentIPRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 5);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.UpdateAgentIPResponse
|
||||
*/
|
||||
export type UpdateAgentIPResponse = Message<"mantrae.v1.UpdateAgentIPResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.UpdateAgentIPResponse.
|
||||
* Use `create(UpdateAgentIPResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const UpdateAgentIPResponseSchema: GenMessage<UpdateAgentIPResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 6);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.DeleteAgentRequest
|
||||
*/
|
||||
export type DeleteAgentRequest = Message<"mantrae.v1.DeleteAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.DeleteAgentRequest.
|
||||
* Use `create(DeleteAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const DeleteAgentRequestSchema: GenMessage<DeleteAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 7);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.DeleteAgentResponse
|
||||
*/
|
||||
export type DeleteAgentResponse = Message<"mantrae.v1.DeleteAgentResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.DeleteAgentResponse.
|
||||
* Use `create(DeleteAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const DeleteAgentResponseSchema: GenMessage<DeleteAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 8);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.ListAgentsRequest
|
||||
*/
|
||||
export type ListAgentsRequest = Message<"mantrae.v1.ListAgentsRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: optional int64 limit = 2;
|
||||
*/
|
||||
limit?: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: optional int64 offset = 3;
|
||||
*/
|
||||
offset?: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.ListAgentsRequest.
|
||||
* Use `create(ListAgentsRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const ListAgentsRequestSchema: GenMessage<ListAgentsRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 9);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.ListAgentsResponse
|
||||
*/
|
||||
export type ListAgentsResponse = Message<"mantrae.v1.ListAgentsResponse"> & {
|
||||
/**
|
||||
* @generated from field: repeated mantrae.v1.Agent agents = 1;
|
||||
*/
|
||||
agents: Agent[];
|
||||
|
||||
/**
|
||||
* @generated from field: int64 total_count = 2;
|
||||
*/
|
||||
totalCount: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.ListAgentsResponse.
|
||||
* Use `create(ListAgentsResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const ListAgentsResponseSchema: GenMessage<ListAgentsResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 10);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.RotateAgentTokenRequest
|
||||
*/
|
||||
export type RotateAgentTokenRequest = Message<"mantrae.v1.RotateAgentTokenRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.RotateAgentTokenRequest.
|
||||
* Use `create(RotateAgentTokenRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const RotateAgentTokenRequestSchema: GenMessage<RotateAgentTokenRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 11);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.RotateAgentTokenResponse
|
||||
*/
|
||||
export type RotateAgentTokenResponse = Message<"mantrae.v1.RotateAgentTokenResponse"> & {
|
||||
/**
|
||||
* @generated from field: string token = 1;
|
||||
*/
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.RotateAgentTokenResponse.
|
||||
* Use `create(RotateAgentTokenResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const RotateAgentTokenResponseSchema: GenMessage<RotateAgentTokenResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 12);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.BootstrapAgentRequest
|
||||
*/
|
||||
export type BootstrapAgentRequest = Message<"mantrae.v1.BootstrapAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: string token = 2;
|
||||
*/
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.BootstrapAgentRequest.
|
||||
* Use `create(BootstrapAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const BootstrapAgentRequestSchema: GenMessage<BootstrapAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 13);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.BootstrapAgentResponse
|
||||
*/
|
||||
export type BootstrapAgentResponse = Message<"mantrae.v1.BootstrapAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: string token = 1;
|
||||
*/
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.BootstrapAgentResponse.
|
||||
* Use `create(BootstrapAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const BootstrapAgentResponseSchema: GenMessage<BootstrapAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent_management, 14);
|
||||
|
||||
/**
|
||||
* @generated from service mantrae.v1.AgentManagementService
|
||||
*/
|
||||
export const AgentManagementService: GenService<{
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.GetAgent
|
||||
*/
|
||||
getAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof GetAgentRequestSchema;
|
||||
output: typeof GetAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.CreateAgent
|
||||
*/
|
||||
createAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof CreateAgentRequestSchema;
|
||||
output: typeof CreateAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.UpdateAgentIP
|
||||
*/
|
||||
updateAgentIP: {
|
||||
methodKind: "unary";
|
||||
input: typeof UpdateAgentIPRequestSchema;
|
||||
output: typeof UpdateAgentIPResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.DeleteAgent
|
||||
*/
|
||||
deleteAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof DeleteAgentRequestSchema;
|
||||
output: typeof DeleteAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.ListAgents
|
||||
*/
|
||||
listAgents: {
|
||||
methodKind: "unary";
|
||||
input: typeof ListAgentsRequestSchema;
|
||||
output: typeof ListAgentsResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.RotateAgentToken
|
||||
*/
|
||||
rotateAgentToken: {
|
||||
methodKind: "unary";
|
||||
input: typeof RotateAgentTokenRequestSchema;
|
||||
output: typeof RotateAgentTokenResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentManagementService.BootstrapAgent
|
||||
*/
|
||||
bootstrapAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof BootstrapAgentRequestSchema;
|
||||
output: typeof BootstrapAgentResponseSchema;
|
||||
},
|
||||
}> = /*@__PURE__*/
|
||||
serviceDesc(file_mantrae_v1_agent_management, 0);
|
||||
|
||||
@@ -12,7 +12,69 @@ import type { Message } from "@bufbuild/protobuf";
|
||||
* Describes the file mantrae/v1/agent.proto.
|
||||
*/
|
||||
export const file_mantrae_v1_agent: GenFile = /*@__PURE__*/
|
||||
fileDesc("ChZtYW50cmFlL3YxL2FnZW50LnByb3RvEgptYW50cmFlLnYxIrgCCglDb250YWluZXISCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIxCgZsYWJlbHMYAyADKAsyIS5tYW50cmFlLnYxLkNvbnRhaW5lci5MYWJlbHNFbnRyeRINCgVpbWFnZRgEIAEoCRIzCgdwb3J0bWFwGAUgAygLMiIubWFudHJhZS52MS5Db250YWluZXIuUG9ydG1hcEVudHJ5Eg4KBnN0YXR1cxgGIAEoCRIrCgdjcmVhdGVkGAcgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBotCgtMYWJlbHNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBGi4KDFBvcnRtYXBFbnRyeRILCgNrZXkYASABKAUSDQoFdmFsdWUYAiABKAU6AjgBIqcBChNHZXRDb250YWluZXJSZXF1ZXN0EhAKCGhvc3RuYW1lGAEgASgJEhEKCXB1YmxpY19pcBgCIAEoCRITCgtwcml2YXRlX2lwcxgDIAMoCRIpCgpjb250YWluZXJzGAQgAygLMhUubWFudHJhZS52MS5Db250YWluZXISKwoHdXBkYXRlZBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiFgoUR2V0Q29udGFpbmVyUmVzcG9uc2UiFAoSSGVhbHRoQ2hlY2tSZXF1ZXN0IjAKE0hlYWx0aENoZWNrUmVzcG9uc2USCgoCb2sYASABKAgSDQoFdG9rZW4YAiABKAkysQEKDEFnZW50U2VydmljZRJRCgxHZXRDb250YWluZXISHy5tYW50cmFlLnYxLkdldENvbnRhaW5lclJlcXVlc3QaIC5tYW50cmFlLnYxLkdldENvbnRhaW5lclJlc3BvbnNlEk4KC0hlYWx0aENoZWNrEh4ubWFudHJhZS52MS5IZWFsdGhDaGVja1JlcXVlc3QaHy5tYW50cmFlLnYxLkhlYWx0aENoZWNrUmVzcG9uc2VCpAEKDmNvbS5tYW50cmFlLnYxQgpBZ2VudFByb3RvUAFaPWdpdGh1Yi5jb20vbWl6dWNoaWxhYnMvbWFudHJhZS9wcm90by9nZW4vbWFudHJhZS92MTttYW50cmFldjGiAgNNWFiqAgpNYW50cmFlLlYxygIKTWFudHJhZVxWMeICFk1hbnRyYWVcVjFcR1BCTWV0YWRhdGHqAgtNYW50cmFlOjpWMWIGcHJvdG8z", [file_google_protobuf_timestamp]);
|
||||
fileDesc("ChZtYW50cmFlL3YxL2FnZW50LnByb3RvEgptYW50cmFlLnYxIo0CCgVBZ2VudBIKCgJpZBgBIAEoCRISCgpwcm9maWxlX2lkGAIgASgDEhAKCGhvc3RuYW1lGAMgASgJEhEKCXB1YmxpY19pcBgEIAEoCRISCgpwcml2YXRlX2lwGAUgASgJEhEKCWFjdGl2ZV9pcBgGIAEoCRINCgV0b2tlbhgHIAEoCRIpCgpjb250YWluZXJzGAggAygLMhUubWFudHJhZS52MS5Db250YWluZXISLgoKY3JlYXRlZF9hdBgJIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASLgoKdXBkYXRlZF9hdBgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAiuAIKCUNvbnRhaW5lchIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEjEKBmxhYmVscxgDIAMoCzIhLm1hbnRyYWUudjEuQ29udGFpbmVyLkxhYmVsc0VudHJ5Eg0KBWltYWdlGAQgASgJEjMKB3BvcnRtYXAYBSADKAsyIi5tYW50cmFlLnYxLkNvbnRhaW5lci5Qb3J0bWFwRW50cnkSDgoGc3RhdHVzGAYgASgJEisKB2NyZWF0ZWQYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wGi0KC0xhYmVsc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoCToCOAEaLgoMUG9ydG1hcEVudHJ5EgsKA2tleRgBIAEoBRINCgV2YWx1ZRgCIAEoBToCOAEiHQoPR2V0QWdlbnRSZXF1ZXN0EgoKAmlkGAEgASgJIjQKEEdldEFnZW50UmVzcG9uc2USIAoFYWdlbnQYASABKAsyES5tYW50cmFlLnYxLkFnZW50IigKEkNyZWF0ZUFnZW50UmVxdWVzdBISCgpwcm9maWxlX2lkGAEgASgDIjcKE0NyZWF0ZUFnZW50UmVzcG9uc2USIAoFYWdlbnQYASABKAsyES5tYW50cmFlLnYxLkFnZW50Ii4KFFVwZGF0ZUFnZW50SVBSZXF1ZXN0EgoKAmlkGAEgASgJEgoKAmlwGAIgASgJIjkKFVVwZGF0ZUFnZW50SVBSZXNwb25zZRIgCgVhZ2VudBgBIAEoCzIRLm1hbnRyYWUudjEuQWdlbnQiIAoSRGVsZXRlQWdlbnRSZXF1ZXN0EgoKAmlkGAEgASgJIhUKE0RlbGV0ZUFnZW50UmVzcG9uc2UiZQoRTGlzdEFnZW50c1JlcXVlc3QSEgoKcHJvZmlsZV9pZBgBIAEoAxISCgVsaW1pdBgCIAEoA0gAiAEBEhMKBm9mZnNldBgDIAEoA0gBiAEBQggKBl9saW1pdEIJCgdfb2Zmc2V0IkwKEkxpc3RBZ2VudHNSZXNwb25zZRIhCgZhZ2VudHMYASADKAsyES5tYW50cmFlLnYxLkFnZW50EhMKC3RvdGFsX2NvdW50GAIgASgDIjsKEkhlYWx0aENoZWNrUmVxdWVzdBIRCglwdWJsaWNfaXAYASABKAkSEgoKcHJpdmF0ZV9pcBgCIAEoCSI3ChNIZWFsdGhDaGVja1Jlc3BvbnNlEiAKBWFnZW50GAEgASgLMhEubWFudHJhZS52MS5BZ2VudCIlChdSb3RhdGVBZ2VudFRva2VuUmVxdWVzdBIKCgJpZBgBIAEoCSIpChhSb3RhdGVBZ2VudFRva2VuUmVzcG9uc2USDQoFdG9rZW4YASABKAkiOgoVQm9vdHN0cmFwQWdlbnRSZXF1ZXN0EhIKCnByb2ZpbGVfaWQYASABKAMSDQoFdG9rZW4YAiABKAkiJwoWQm9vdHN0cmFwQWdlbnRSZXNwb25zZRINCgV0b2tlbhgBIAEoCTKqBQoMQWdlbnRTZXJ2aWNlEkoKCEdldEFnZW50EhsubWFudHJhZS52MS5HZXRBZ2VudFJlcXVlc3QaHC5tYW50cmFlLnYxLkdldEFnZW50UmVzcG9uc2UiA5ACARJOCgtDcmVhdGVBZ2VudBIeLm1hbnRyYWUudjEuQ3JlYXRlQWdlbnRSZXF1ZXN0Gh8ubWFudHJhZS52MS5DcmVhdGVBZ2VudFJlc3BvbnNlElQKDVVwZGF0ZUFnZW50SVASIC5tYW50cmFlLnYxLlVwZGF0ZUFnZW50SVBSZXF1ZXN0GiEubWFudHJhZS52MS5VcGRhdGVBZ2VudElQUmVzcG9uc2USTgoLRGVsZXRlQWdlbnQSHi5tYW50cmFlLnYxLkRlbGV0ZUFnZW50UmVxdWVzdBofLm1hbnRyYWUudjEuRGVsZXRlQWdlbnRSZXNwb25zZRJQCgpMaXN0QWdlbnRzEh0ubWFudHJhZS52MS5MaXN0QWdlbnRzUmVxdWVzdBoeLm1hbnRyYWUudjEuTGlzdEFnZW50c1Jlc3BvbnNlIgOQAgESTgoLSGVhbHRoQ2hlY2sSHi5tYW50cmFlLnYxLkhlYWx0aENoZWNrUmVxdWVzdBofLm1hbnRyYWUudjEuSGVhbHRoQ2hlY2tSZXNwb25zZRJXCg5Cb290c3RyYXBBZ2VudBIhLm1hbnRyYWUudjEuQm9vdHN0cmFwQWdlbnRSZXF1ZXN0GiIubWFudHJhZS52MS5Cb290c3RyYXBBZ2VudFJlc3BvbnNlEl0KEFJvdGF0ZUFnZW50VG9rZW4SIy5tYW50cmFlLnYxLlJvdGF0ZUFnZW50VG9rZW5SZXF1ZXN0GiQubWFudHJhZS52MS5Sb3RhdGVBZ2VudFRva2VuUmVzcG9uc2VCpAEKDmNvbS5tYW50cmFlLnYxQgpBZ2VudFByb3RvUAFaPWdpdGh1Yi5jb20vbWl6dWNoaWxhYnMvbWFudHJhZS9wcm90by9nZW4vbWFudHJhZS92MTttYW50cmFldjGiAgNNWFiqAgpNYW50cmFlLlYxygIKTWFudHJhZVxWMeICFk1hbnRyYWVcVjFcR1BCTWV0YWRhdGHqAgtNYW50cmFlOjpWMWIGcHJvdG8z", [file_google_protobuf_timestamp]);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.Agent
|
||||
*/
|
||||
export type Agent = Message<"mantrae.v1.Agent"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 2;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: string hostname = 3;
|
||||
*/
|
||||
hostname: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string public_ip = 4;
|
||||
*/
|
||||
publicIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string private_ip = 5;
|
||||
*/
|
||||
privateIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string active_ip = 6;
|
||||
*/
|
||||
activeIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string token = 7;
|
||||
*/
|
||||
token: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated mantrae.v1.Container containers = 8;
|
||||
*/
|
||||
containers: Container[];
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp created_at = 9;
|
||||
*/
|
||||
createdAt?: Timestamp;
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp updated_at = 10;
|
||||
*/
|
||||
updatedAt?: Timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.Agent.
|
||||
* Use `create(AgentSchema)` to create a new message.
|
||||
*/
|
||||
export const AgentSchema: GenMessage<Agent> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 0);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.Container
|
||||
@@ -59,62 +121,207 @@ export type Container = Message<"mantrae.v1.Container"> & {
|
||||
* Use `create(ContainerSchema)` to create a new message.
|
||||
*/
|
||||
export const ContainerSchema: GenMessage<Container> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 0);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.GetContainerRequest
|
||||
*/
|
||||
export type GetContainerRequest = Message<"mantrae.v1.GetContainerRequest"> & {
|
||||
/**
|
||||
* @generated from field: string hostname = 1;
|
||||
*/
|
||||
hostname: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string public_ip = 2;
|
||||
*/
|
||||
publicIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: repeated string private_ips = 3;
|
||||
*/
|
||||
privateIps: string[];
|
||||
|
||||
/**
|
||||
* @generated from field: repeated mantrae.v1.Container containers = 4;
|
||||
*/
|
||||
containers: Container[];
|
||||
|
||||
/**
|
||||
* @generated from field: google.protobuf.Timestamp updated = 5;
|
||||
*/
|
||||
updated?: Timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.GetContainerRequest.
|
||||
* Use `create(GetContainerRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const GetContainerRequestSchema: GenMessage<GetContainerRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 1);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.GetContainerResponse
|
||||
* @generated from message mantrae.v1.GetAgentRequest
|
||||
*/
|
||||
export type GetContainerResponse = Message<"mantrae.v1.GetContainerResponse"> & {
|
||||
export type GetAgentRequest = Message<"mantrae.v1.GetAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.GetContainerResponse.
|
||||
* Use `create(GetContainerResponseSchema)` to create a new message.
|
||||
* Describes the message mantrae.v1.GetAgentRequest.
|
||||
* Use `create(GetAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const GetContainerResponseSchema: GenMessage<GetContainerResponse> = /*@__PURE__*/
|
||||
export const GetAgentRequestSchema: GenMessage<GetAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 2);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.GetAgentResponse
|
||||
*/
|
||||
export type GetAgentResponse = Message<"mantrae.v1.GetAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.GetAgentResponse.
|
||||
* Use `create(GetAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const GetAgentResponseSchema: GenMessage<GetAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 3);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.CreateAgentRequest
|
||||
*/
|
||||
export type CreateAgentRequest = Message<"mantrae.v1.CreateAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.CreateAgentRequest.
|
||||
* Use `create(CreateAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const CreateAgentRequestSchema: GenMessage<CreateAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 4);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.CreateAgentResponse
|
||||
*/
|
||||
export type CreateAgentResponse = Message<"mantrae.v1.CreateAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.CreateAgentResponse.
|
||||
* Use `create(CreateAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const CreateAgentResponseSchema: GenMessage<CreateAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 5);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.UpdateAgentIPRequest
|
||||
*/
|
||||
export type UpdateAgentIPRequest = Message<"mantrae.v1.UpdateAgentIPRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string ip = 2;
|
||||
*/
|
||||
ip: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.UpdateAgentIPRequest.
|
||||
* Use `create(UpdateAgentIPRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const UpdateAgentIPRequestSchema: GenMessage<UpdateAgentIPRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 6);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.UpdateAgentIPResponse
|
||||
*/
|
||||
export type UpdateAgentIPResponse = Message<"mantrae.v1.UpdateAgentIPResponse"> & {
|
||||
/**
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.UpdateAgentIPResponse.
|
||||
* Use `create(UpdateAgentIPResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const UpdateAgentIPResponseSchema: GenMessage<UpdateAgentIPResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 7);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.DeleteAgentRequest
|
||||
*/
|
||||
export type DeleteAgentRequest = Message<"mantrae.v1.DeleteAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.DeleteAgentRequest.
|
||||
* Use `create(DeleteAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const DeleteAgentRequestSchema: GenMessage<DeleteAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 8);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.DeleteAgentResponse
|
||||
*/
|
||||
export type DeleteAgentResponse = Message<"mantrae.v1.DeleteAgentResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.DeleteAgentResponse.
|
||||
* Use `create(DeleteAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const DeleteAgentResponseSchema: GenMessage<DeleteAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 9);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.ListAgentsRequest
|
||||
*/
|
||||
export type ListAgentsRequest = Message<"mantrae.v1.ListAgentsRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: optional int64 limit = 2;
|
||||
*/
|
||||
limit?: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: optional int64 offset = 3;
|
||||
*/
|
||||
offset?: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.ListAgentsRequest.
|
||||
* Use `create(ListAgentsRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const ListAgentsRequestSchema: GenMessage<ListAgentsRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 10);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.ListAgentsResponse
|
||||
*/
|
||||
export type ListAgentsResponse = Message<"mantrae.v1.ListAgentsResponse"> & {
|
||||
/**
|
||||
* @generated from field: repeated mantrae.v1.Agent agents = 1;
|
||||
*/
|
||||
agents: Agent[];
|
||||
|
||||
/**
|
||||
* @generated from field: int64 total_count = 2;
|
||||
*/
|
||||
totalCount: bigint;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.ListAgentsResponse.
|
||||
* Use `create(ListAgentsResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const ListAgentsResponseSchema: GenMessage<ListAgentsResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 11);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.HealthCheckRequest
|
||||
*/
|
||||
export type HealthCheckRequest = Message<"mantrae.v1.HealthCheckRequest"> & {
|
||||
/**
|
||||
* @generated from field: string public_ip = 1;
|
||||
*/
|
||||
publicIp: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string private_ip = 2;
|
||||
*/
|
||||
privateIp: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -122,16 +329,67 @@ export type HealthCheckRequest = Message<"mantrae.v1.HealthCheckRequest"> & {
|
||||
* Use `create(HealthCheckRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const HealthCheckRequestSchema: GenMessage<HealthCheckRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 3);
|
||||
messageDesc(file_mantrae_v1_agent, 12);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.HealthCheckResponse
|
||||
*/
|
||||
export type HealthCheckResponse = Message<"mantrae.v1.HealthCheckResponse"> & {
|
||||
/**
|
||||
* @generated from field: bool ok = 1;
|
||||
* @generated from field: mantrae.v1.Agent agent = 1;
|
||||
*/
|
||||
ok: boolean;
|
||||
agent?: Agent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.HealthCheckResponse.
|
||||
* Use `create(HealthCheckResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const HealthCheckResponseSchema: GenMessage<HealthCheckResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 13);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.RotateAgentTokenRequest
|
||||
*/
|
||||
export type RotateAgentTokenRequest = Message<"mantrae.v1.RotateAgentTokenRequest"> & {
|
||||
/**
|
||||
* @generated from field: string id = 1;
|
||||
*/
|
||||
id: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.RotateAgentTokenRequest.
|
||||
* Use `create(RotateAgentTokenRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const RotateAgentTokenRequestSchema: GenMessage<RotateAgentTokenRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 14);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.RotateAgentTokenResponse
|
||||
*/
|
||||
export type RotateAgentTokenResponse = Message<"mantrae.v1.RotateAgentTokenResponse"> & {
|
||||
/**
|
||||
* @generated from field: string token = 1;
|
||||
*/
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.RotateAgentTokenResponse.
|
||||
* Use `create(RotateAgentTokenResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const RotateAgentTokenResponseSchema: GenMessage<RotateAgentTokenResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 15);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.BootstrapAgentRequest
|
||||
*/
|
||||
export type BootstrapAgentRequest = Message<"mantrae.v1.BootstrapAgentRequest"> & {
|
||||
/**
|
||||
* @generated from field: int64 profile_id = 1;
|
||||
*/
|
||||
profileId: bigint;
|
||||
|
||||
/**
|
||||
* @generated from field: string token = 2;
|
||||
@@ -140,23 +398,72 @@ export type HealthCheckResponse = Message<"mantrae.v1.HealthCheckResponse"> & {
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.HealthCheckResponse.
|
||||
* Use `create(HealthCheckResponseSchema)` to create a new message.
|
||||
* Describes the message mantrae.v1.BootstrapAgentRequest.
|
||||
* Use `create(BootstrapAgentRequestSchema)` to create a new message.
|
||||
*/
|
||||
export const HealthCheckResponseSchema: GenMessage<HealthCheckResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 4);
|
||||
export const BootstrapAgentRequestSchema: GenMessage<BootstrapAgentRequest> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 16);
|
||||
|
||||
/**
|
||||
* @generated from message mantrae.v1.BootstrapAgentResponse
|
||||
*/
|
||||
export type BootstrapAgentResponse = Message<"mantrae.v1.BootstrapAgentResponse"> & {
|
||||
/**
|
||||
* @generated from field: string token = 1;
|
||||
*/
|
||||
token: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message mantrae.v1.BootstrapAgentResponse.
|
||||
* Use `create(BootstrapAgentResponseSchema)` to create a new message.
|
||||
*/
|
||||
export const BootstrapAgentResponseSchema: GenMessage<BootstrapAgentResponse> = /*@__PURE__*/
|
||||
messageDesc(file_mantrae_v1_agent, 17);
|
||||
|
||||
/**
|
||||
* @generated from service mantrae.v1.AgentService
|
||||
*/
|
||||
export const AgentService: GenService<{
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.GetContainer
|
||||
* @generated from rpc mantrae.v1.AgentService.GetAgent
|
||||
*/
|
||||
getContainer: {
|
||||
getAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof GetContainerRequestSchema;
|
||||
output: typeof GetContainerResponseSchema;
|
||||
input: typeof GetAgentRequestSchema;
|
||||
output: typeof GetAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.CreateAgent
|
||||
*/
|
||||
createAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof CreateAgentRequestSchema;
|
||||
output: typeof CreateAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.UpdateAgentIP
|
||||
*/
|
||||
updateAgentIP: {
|
||||
methodKind: "unary";
|
||||
input: typeof UpdateAgentIPRequestSchema;
|
||||
output: typeof UpdateAgentIPResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.DeleteAgent
|
||||
*/
|
||||
deleteAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof DeleteAgentRequestSchema;
|
||||
output: typeof DeleteAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.ListAgents
|
||||
*/
|
||||
listAgents: {
|
||||
methodKind: "unary";
|
||||
input: typeof ListAgentsRequestSchema;
|
||||
output: typeof ListAgentsResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.HealthCheck
|
||||
@@ -166,6 +473,22 @@ export const AgentService: GenService<{
|
||||
input: typeof HealthCheckRequestSchema;
|
||||
output: typeof HealthCheckResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.BootstrapAgent
|
||||
*/
|
||||
bootstrapAgent: {
|
||||
methodKind: "unary";
|
||||
input: typeof BootstrapAgentRequestSchema;
|
||||
output: typeof BootstrapAgentResponseSchema;
|
||||
},
|
||||
/**
|
||||
* @generated from rpc mantrae.v1.AgentService.RotateAgentToken
|
||||
*/
|
||||
rotateAgentToken: {
|
||||
methodKind: "unary";
|
||||
input: typeof RotateAgentTokenRequestSchema;
|
||||
output: typeof RotateAgentTokenResponseSchema;
|
||||
},
|
||||
}> = /*@__PURE__*/
|
||||
serviceDesc(file_mantrae_v1_agent, 0);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import TableActions from '$lib/components/tables/TableActions.svelte';
|
||||
import type { BulkAction } from '$lib/components/tables/types';
|
||||
import { renderComponent } from '$lib/components/ui/data-table';
|
||||
import type { Agent } from '$lib/gen/mantrae/v1/agent_management_pb';
|
||||
import type { Agent } from '$lib/gen/mantrae/v1/agent_pb';
|
||||
import { DateFormat, pageIndex, pageSize } from '$lib/stores/common';
|
||||
import { profile } from '$lib/stores/profile';
|
||||
import { timestampDate, type Timestamp } from '@bufbuild/protobuf/wkt';
|
||||
|
||||
Reference in New Issue
Block a user