new changes
This commit is contained in:
8
control-plane-go/cmd/agent-gateway/main.go
Normal file
8
control-plane-go/cmd/agent-gateway/main.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
func main() {
|
||||
log.Println("yakpanel agent-gateway bootstrap")
|
||||
log.Println("responsibilities: mTLS sessions, heartbeat intake, command channel routing")
|
||||
}
|
||||
5
control-plane-go/go.mod
Normal file
5
control-plane-go/go.mod
Normal file
@@ -0,0 +1,5 @@
|
||||
module yakpanel/control-plane-go
|
||||
|
||||
go 1.23
|
||||
|
||||
require github.com/redis/go-redis/v9 v9.6.1
|
||||
19
control-plane-go/internal/orchestration/dispatcher.go
Normal file
19
control-plane-go/internal/orchestration/dispatcher.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package orchestration
|
||||
|
||||
import "yakpanel/control-plane-go/pkg/contracts"
|
||||
|
||||
type Queue interface {
|
||||
Publish(topic string, payload any) error
|
||||
}
|
||||
|
||||
type Dispatcher struct {
|
||||
queue Queue
|
||||
}
|
||||
|
||||
func NewDispatcher(queue Queue) *Dispatcher {
|
||||
return &Dispatcher{queue: queue}
|
||||
}
|
||||
|
||||
func (d *Dispatcher) DispatchCommand(cmd contracts.CommandEnvelope) error {
|
||||
return d.queue.Publish("yakpanel.commands", cmd)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package orchestration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type RedisStreamQueue struct {
|
||||
client *redis.Client
|
||||
stream string
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewRedisStreamQueue(ctx context.Context, client *redis.Client, stream string) *RedisStreamQueue {
|
||||
return &RedisStreamQueue{
|
||||
client: client,
|
||||
stream: stream,
|
||||
ctx: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
func (q *RedisStreamQueue) Publish(topic string, payload any) error {
|
||||
body, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = q.client.XAdd(q.ctx, &redis.XAddArgs{
|
||||
Stream: q.stream,
|
||||
Values: map[string]any{
|
||||
"topic": topic,
|
||||
"body": string(body),
|
||||
},
|
||||
}).Result()
|
||||
return err
|
||||
}
|
||||
42
control-plane-go/internal/webserver/adapters.go
Normal file
42
control-plane-go/internal/webserver/adapters.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package webserver
|
||||
|
||||
import "errors"
|
||||
|
||||
type Adapter interface {
|
||||
Name() string
|
||||
ValidateVHost(config string) error
|
||||
Reload() error
|
||||
}
|
||||
|
||||
type NginxAdapter struct{}
|
||||
type ApacheAdapter struct{}
|
||||
type OpenLiteSpeedAdapter struct{}
|
||||
|
||||
func (a NginxAdapter) Name() string { return "nginx" }
|
||||
func (a ApacheAdapter) Name() string { return "apache" }
|
||||
func (a OpenLiteSpeedAdapter) Name() string { return "openlitespeed" }
|
||||
|
||||
func (a NginxAdapter) ValidateVHost(config string) error {
|
||||
if config == "" {
|
||||
return errors.New("empty nginx vhost config")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a ApacheAdapter) ValidateVHost(config string) error {
|
||||
if config == "" {
|
||||
return errors.New("empty apache vhost config")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a OpenLiteSpeedAdapter) ValidateVHost(config string) error {
|
||||
if config == "" {
|
||||
return errors.New("empty openlitespeed vhost config")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a NginxAdapter) Reload() error { return nil }
|
||||
func (a ApacheAdapter) Reload() error { return nil }
|
||||
func (a OpenLiteSpeedAdapter) Reload() error { return nil }
|
||||
22
control-plane-go/pkg/contracts/command.go
Normal file
22
control-plane-go/pkg/contracts/command.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package contracts
|
||||
|
||||
type CommandEnvelope struct {
|
||||
CommandID string `json:"cmd_id"`
|
||||
JobID string `json:"job_id"`
|
||||
TenantID string `json:"tenant_id"`
|
||||
ServerID string `json:"server_id"`
|
||||
Type string `json:"type"`
|
||||
Args map[string]any `json:"args"`
|
||||
TimeoutSec int `json:"timeout_sec"`
|
||||
IdempotencyKey string `json:"idempotency_key"`
|
||||
RequiredCaps []string `json:"required_capabilities"`
|
||||
RequestedByUserID string `json:"requested_by_user_id"`
|
||||
}
|
||||
|
||||
type CommandResult struct {
|
||||
CommandID string `json:"cmd_id"`
|
||||
Status string `json:"status"`
|
||||
ExitCode int `json:"exit_code"`
|
||||
Output map[string]any `json:"output"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}
|
||||
Reference in New Issue
Block a user