Files
rdp-proxy/backend/internal/modules/nodeagent/module.go
T
m 20d361a886
build / backend (push) Has been cancelled
build / node-agent (push) Has been cancelled
build / worker (push) Has been cancelled
рабочий вариант, но скороть 10 МБит
2026-05-22 21:46:49 +03:00

179 lines
6.4 KiB
Go

package nodeagent
import (
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
clustermodule "github.com/example/remote-access-platform/backend/internal/modules/cluster"
"github.com/example/remote-access-platform/backend/internal/platform/httpx"
"github.com/example/remote-access-platform/backend/internal/platform/module"
"github.com/example/remote-access-platform/backend/internal/platform/secrets"
)
type Module struct {
cluster *clustermodule.Service
}
func NewModule(deps module.Dependencies) *Module {
clusterStore := clustermodule.NewPostgresStore(deps.Infra.DB)
if deps.Config.Secret.EncryptionKeyBase64 != "" {
if encryptor, err := secrets.NewEncryptor(deps.Config.Secret.EncryptionKeyBase64, deps.Config.Secret.EncryptionKeyID); err == nil {
clusterStore.WithClusterKeyEncryptor(encryptor)
}
}
return &Module{
cluster: clustermodule.NewService(clusterStore),
}
}
func (m *Module) Name() string {
return "nodeagent"
}
func (m *Module) RegisterRoutes(router chi.Router) {
router.Route("/node-agents", func(r chi.Router) {
r.Post("/docker-join-bundle", m.dockerJoinBundle)
r.Post("/windows-join-bundle", m.windowsJoinBundle)
r.Post("/linux-join-bundle", m.linuxJoinBundle)
r.Post("/register", m.registerFabricNode)
r.Post("/enroll", m.enrollAgent)
r.Post("/enrollments/{requestID}/join", m.fetchEnrollmentJoinContract)
})
}
func (m *Module) linuxJoinBundle(w http.ResponseWriter, r *http.Request) {
var payload clustermodule.DockerInstallProfileRequest
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid linux join bundle payload")
return
}
bundle, err := m.cluster.GetLinuxJoinBundle(r.Context(), payload)
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusOK, map[string]any{"join_bundle": bundle})
}
func (m *Module) windowsJoinBundle(w http.ResponseWriter, r *http.Request) {
var payload clustermodule.DockerInstallProfileRequest
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid windows join bundle payload")
return
}
bundle, err := m.cluster.GetWindowsJoinBundle(r.Context(), payload)
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusOK, map[string]any{"join_bundle": bundle})
}
func (m *Module) dockerJoinBundle(w http.ResponseWriter, r *http.Request) {
var payload clustermodule.DockerInstallProfileRequest
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid docker join bundle payload")
return
}
bundle, err := m.cluster.GetDockerJoinBundle(r.Context(), payload)
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusOK, map[string]any{"join_bundle": bundle})
}
func (m *Module) registerFabricNode(w http.ResponseWriter, r *http.Request) {
var payload struct {
ClusterID string `json:"cluster_id"`
NodeKey string `json:"node_key"`
Name string `json:"name"`
OwnershipType string `json:"ownership_type"`
OwnerOrganizationID *string `json:"owner_organization_id"`
ReportedVersion *string `json:"reported_version"`
Metadata json.RawMessage `json:"metadata"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid fabric node registration payload")
return
}
item, err := m.cluster.RegisterFabricNode(r.Context(), clustermodule.RegisterFabricNodeInput{
ClusterID: payload.ClusterID,
NodeKey: payload.NodeKey,
Name: payload.Name,
OwnershipType: payload.OwnershipType,
OwnerOrganizationID: payload.OwnerOrganizationID,
ReportedVersion: payload.ReportedVersion,
Metadata: payload.Metadata,
})
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusOK, map[string]any{
"status": "registered",
"node_id": item.ID,
"node": item,
})
}
func (m *Module) enrollAgent(w http.ResponseWriter, r *http.Request) {
var payload struct {
ClusterID string `json:"cluster_id"`
JoinToken string `json:"join_token"`
NodeName string `json:"node_name"`
NodeFingerprint string `json:"node_fingerprint"`
PublicKey string `json:"public_key"`
ReportedCapabilities json.RawMessage `json:"reported_capabilities"`
ReportedFacts json.RawMessage `json:"reported_facts"`
RequestedRoles json.RawMessage `json:"requested_roles"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid agent enrollment payload")
return
}
joinRequest, err := m.cluster.CreateJoinRequest(r.Context(), clustermodule.CreateJoinRequestInput{
ClusterID: payload.ClusterID,
JoinToken: payload.JoinToken,
NodeName: payload.NodeName,
NodeFingerprint: payload.NodeFingerprint,
PublicKey: payload.PublicKey,
ReportedCapabilities: payload.ReportedCapabilities,
ReportedFacts: payload.ReportedFacts,
RequestedRoles: payload.RequestedRoles,
})
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusAccepted, map[string]any{
"status": "pending_approval",
"join_request": joinRequest,
})
}
func (m *Module) fetchEnrollmentJoinContract(w http.ResponseWriter, r *http.Request) {
var payload struct {
ClusterID string `json:"cluster_id"`
NodeFingerprint string `json:"node_fingerprint"`
PublicKey string `json:"public_key"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
httpx.WriteError(w, http.StatusBadRequest, "invalid enrollment join payload")
return
}
result, err := m.cluster.GetJoinRequestJoin(r.Context(), clustermodule.GetJoinRequestJoinInput{
ClusterID: payload.ClusterID,
JoinRequestID: chi.URLParam(r, "requestID"),
NodeFingerprint: payload.NodeFingerprint,
PublicKey: payload.PublicKey,
})
if err != nil {
httpx.WriteError(w, http.StatusBadRequest, err.Error())
return
}
httpx.WriteJSON(w, http.StatusOK, result)
}