From cb95196f8ee2bb089f188f7af5ec90c736453cb5 Mon Sep 17 00:00:00 2001 From: Yann Stepienik Date: Thu, 27 Aug 2026 18:05:51 +0100 Subject: [PATCH] [release] v0.23.1 --- api-docs/openapi.json | 2 +- api-docs/swagger.json | 2 +- api-docs/swagger.yaml | 2 +- client/src/pages/constellation/vpn.jsx | 5 +- go-sdk/client.gen.go | 604 ++++++++++++------------- go-sdk/version.go | 2 +- package.json | 2 +- src/constellation/NATS_client_only.go | 153 +++++++ src/constellation/api_nebula.go | 18 +- src/constellation/index.go | 14 +- src/index.go | 2 +- 11 files changed, 494 insertions(+), 312 deletions(-) create mode 100644 src/constellation/NATS_client_only.go diff --git a/api-docs/openapi.json b/api-docs/openapi.json index 41099ad3..ca30e8ef 100644 --- a/api-docs/openapi.json +++ b/api-docs/openapi.json @@ -4,7 +4,7 @@ "description": "REST API for Cosmos Cloud server management", "title": "Cosmos Server API", "contact": {}, - "version": "0.23.0" + "version": "0.23.1" }, "paths": { "/_logs": { diff --git a/api-docs/swagger.json b/api-docs/swagger.json index 543b4cd8..2ecb9529 100644 --- a/api-docs/swagger.json +++ b/api-docs/swagger.json @@ -4,7 +4,7 @@ "description": "REST API for Cosmos Cloud server management", "title": "Cosmos Server API", "contact": {}, - "version": "0.23.0" + "version": "0.23.1" }, "basePath": "/cosmos", "paths": { diff --git a/api-docs/swagger.yaml b/api-docs/swagger.yaml index 5dd82621..b8d9e2a9 100644 --- a/api-docs/swagger.yaml +++ b/api-docs/swagger.yaml @@ -2066,7 +2066,7 @@ info: contact: {} description: REST API for Cosmos Cloud server management title: Cosmos Server API - version: 0.23.0 + version: 0.23.1 paths: /_logs: get: diff --git a/client/src/pages/constellation/vpn.jsx b/client/src/pages/constellation/vpn.jsx index 04a1683d..4923a556 100644 --- a/client/src/pages/constellation/vpn.jsx +++ b/client/src/pages/constellation/vpn.jsx @@ -180,7 +180,8 @@ export const ConstellationVPN = ({ freeVersion }) => { // whole dependency chain healthy — a successful ping with a broken chain is // only a degraded connection (non-admins have no natsInfo: assume healthy) - const chainOk = !natsInfo || (natsInfo.nebulaStarted && natsInfo.serverRunning && natsInfo.clientConnected + const isClientNode = !!natsInfo && natsInfo.role === 'client'; + const chainOk = !natsInfo || isClientNode || (natsInfo.nebulaStarted && natsInfo.serverRunning && natsInfo.clientConnected && (natsInfo.role !== 'agent' || natsInfo.managerLinkUp) && natsInfo.jetstreamReady && natsInfo.kvNodesReady); @@ -299,7 +300,7 @@ export const ConstellationVPN = ({ freeVersion }) => { {t('mgmt.constellation.nats.loading')} )} - {constellationEnabled && isAdmin && natsInfo && (() => { + {constellationEnabled && isAdmin && natsInfo && !isClientNode && (() => { const isAgentNode = natsInfo.role === 'agent'; // dependency chain: each step only works if the previous ones do, // so the first red dot is where the stack actually broke diff --git a/go-sdk/client.gen.go b/go-sdk/client.gen.go index 8fc1397f..19a6fa19 100644 --- a/go-sdk/client.gen.go +++ b/go-sdk/client.gen.go @@ -36461,323 +36461,323 @@ func ParsePostRcloneVfsStatsResponse(rsp *http.Response) (*PostRcloneVfsStatsRes // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "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", - "NmkBpzAoZ30Bcpn0XveOItRp975+/Pr/BwAA//8=", + "7V6KxFNNxQz5pEjHI72PTmOmd7yOzhgksbLKZReZ2z2MOtrzIxuUY6bDskrxIlmIJE/h6E/738vGXvUf", + "sf3HstcusmLaFLWz7VwGF900XiqzqI7d5Xf5C2X5clK2C+J20LLpFbsRvm1b7spO9NG16uDkxyqasyjv", + "tW3ytypEPFqqDDtJTZPrOxjbbKXH7fJldG4z30Z1WUOjEJlNxEw0ckc+ESoVqvCRMd1stvqry19L4/AG", + "dX5nRt8J2Nj9KOOz+qHu9hUJwPDfms7wzXIXmGejO8DEHonXji6jRHA4sp7dRy7l8laPwBH2sCFNJ0WK", + "5n2J3k7PuhGkoixiaQ1uhoX3ielpfc4rMmPnFNhRt8ejbqMTA/mYF75W+9H+7kWoqmFm22uoilTD4kHz", + "aEj1Hr+ssMk8quyuag+qDpeeIC7t8wzie4FunmbbnkE1kDVtuyQ2re4mTzOUcqZ5khT3s560qsE1JUxp", + "e62q6W29q3TpLq31e7GGS4ocIAXF/LHLDLDQTZ9wYZ5fMXDNaKJeNLtKRRctZK8xXUB3fe0yftIFIM7t", + "j26VbJ6575Ly2h19qNoJHlM+dpkxVxy9E4w7wfhbpMnkBL4wpRmftZQxJGBkciOmZRNfd8zquZuxZ4mY", + "0FLY0ZJyNXXhxWoHwJSwoY7oROS6CZ98X/Y5xi575HHBlh2x7IjlBuyb1bz6PqklztMswSpVELfHQRdv", + "S3Jl/p/xqXDl95wC4EALTZM+yRXEfTKVALuk18VUrUj5Lpz8OFUrWt4h419CDWHA7uPZ2NJ5B20Yawvx", + "NmkBpzAoZ30Bcpn03vSOItRp975++vr/BwAA//8=", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/go-sdk/version.go b/go-sdk/version.go index 865d40ff..b6f7579d 100644 --- a/go-sdk/version.go +++ b/go-sdk/version.go @@ -1,4 +1,4 @@ package cosmossdk // Version is the SDK version, synced with Cosmos Server at build time. -const Version = "0.23.0" +const Version = "0.23.1" diff --git a/package.json b/package.json index a6c430af..dce8c096 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.23.0", + "version": "0.23.1", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/constellation/NATS_client_only.go b/src/constellation/NATS_client_only.go new file mode 100644 index 00000000..4078994b --- /dev/null +++ b/src/constellation/NATS_client_only.go @@ -0,0 +1,153 @@ +package constellation + +import ( + "encoding/json" + "errors" + "sort" + "strconv" + "sync/atomic" + "time" + + "github.com/azukaar/cosmos-server/src/utils" +) + +// Client-only nodes (CosmosNode == 0) don't run NATS; they fetch the public +// device list from a manager and persist it locally. + +var clientSyncOK atomic.Bool +var clientSyncGen atomic.Int64 + +func IsClientNode() bool { + d, err := GetCurrentDevice() + return err == nil && d.CosmosNode == 0 +} + +func IsClientSynced() bool { + return clientSyncOK.Load() +} + +// seed managers first, then lighthouse hosts, sorted +func clientSyncTargets() []string { + seen := map[string]bool{} + targets := []string{} + add := func(ip string) { + ip = cleanIp(ip) + if ip != "" && !seen[ip] { + seen[ip] = true + targets = append(targets, ip) + } + } + seeds := getSeedManagerIPs() + sort.Strings(seeds) + for _, ip := range seeds { + add(ip) + } + lhs, _ := GetAllLighthouseIPFromTempConfig() + sort.Strings(lhs) + for _, ip := range lhs { + add(ip) + } + return targets +} + +func fetchPublicDevicesFrom(ip string) ([]PublicDeviceInfo, error) { + user, pwd, err := GetNATSCredentials() + if err != nil { + return nil, err + } + conn, err := connectNATSClient("nats://"+ip+":4222", user, pwd) + if err != nil { + return nil, err + } + defer conn.Close() + + msg, err := conn.Request(publicDevicesSubject, []byte{}, 8*time.Second) + if err != nil { + return nil, err + } + + var reply struct { + Status string `json:"status"` + Data []PublicDeviceInfo `json:"data"` + } + if err := json.Unmarshal(msg.Data, &reply); err != nil { + return nil, err + } + if reply.Status != "OK" || reply.Data == nil { + return nil, errors.New("malformed public-devices reply from " + ip) + } + return reply.Data, nil +} + +// persistPublicDevices replaces the local device table (minus self) so nebula +// restarts pick up the right lighthouses/relays/firewall. +func persistPublicDevices(list []PublicDeviceInfo) error { + self, _ := GetCurrentDeviceName() + + if err := utils.CommitMutationLocal(utils.Mutation{Table: "devices", Op: "deleteMany", Filter: map[string]interface{}{}}); err != nil { + return err + } + for _, p := range list { + if p.DeviceName == "" || p.DeviceName == self { + continue + } + d := utils.ConstellationDevice{ + Nickname: p.User, + DeviceName: p.DeviceName, + IP: p.IP, + IsLighthouse: p.IsLighthouse, + CosmosNode: p.CosmosNode, + IsRelay: p.IsRelay, + IsExitNode: p.IsExitNode, + PublicHostname: p.PublicHostname, + Port: p.Port, + } + if err := utils.CommitMutationLocal(utils.Mutation{Table: "devices", Op: "insert", Doc: d}); err != nil { + utils.Warn("[CLIENT] could not persist device " + p.DeviceName + ": " + err.Error()) + } + } + return nil +} + +func clientSyncOnce() error { + targets := clientSyncTargets() + if len(targets) == 0 { + return errors.New("no manager or lighthouse to fetch devices from") + } + var lastErr error + for _, ip := range targets { + list, err := fetchPublicDevicesFrom(ip) + if err != nil { + lastErr = err + utils.Debug("[CLIENT] public-devices fetch from " + ip + " failed: " + err.Error()) + continue + } + if err := persistPublicDevices(list); err != nil { + return err + } + utils.Log("[CLIENT] synced " + strconv.Itoa(len(list)) + " devices from " + ip) + refreshDeviceCache() + return nil + } + return lastErr +} + +// StartClientDeviceSync does one fetch on connect, retried up to 5 times +// every 15s. A restart bumps the generation so a stale attempt exits. +func StartClientDeviceSync() { + gen := clientSyncGen.Add(1) + alive := func() bool { return NebulaStarted.Load() && clientSyncGen.Load() == gen } + + clientSyncOK.Store(false) + for attempt := 1; attempt <= 5 && alive(); attempt++ { + err := clientSyncOnce() + if err == nil { + clientSyncOK.Store(true) + return + } + utils.Warn("[CLIENT] device fetch failed (attempt " + strconv.Itoa(attempt) + "/5): " + err.Error()) + for end := time.Now().Add(15 * time.Second); alive() && time.Now().Before(end); { + time.Sleep(time.Second) + } + } +} diff --git a/src/constellation/api_nebula.go b/src/constellation/api_nebula.go index 1dd59824..e7ff9e63 100644 --- a/src/constellation/api_nebula.go +++ b/src/constellation/api_nebula.go @@ -187,6 +187,17 @@ func API_NATSStatus(w http.ResponseWriter, req *http.Request) { } if req.Method == "GET" { + if IsClientNode() { + json.NewEncoder(w).Encode(map[string]interface{}{ + "status": "OK", + "data": map[string]interface{}{ + "role": "client", + "nebulaStarted": NebulaStarted.Load(), + "clientSynced": IsClientSynced(), + }, + }) + return + } json.NewEncoder(w).Encode(map[string]interface{}{ "status": "OK", "data": GetNATSStatus(), @@ -212,7 +223,12 @@ func API_Ping(w http.ResponseWriter, req *http.Request) { } if(req.Method == "GET") { - isConnected := PingNATSClient() + isConnected := false + if IsClientNode() { + isConnected = NebulaStarted.Load() && IsClientSynced() + } else { + isConnected = PingNATSClient() + } json.NewEncoder(w).Encode(map[string]interface{}{ "status": "OK", diff --git a/src/constellation/index.go b/src/constellation/index.go index c436cc06..4fbbd025 100644 --- a/src/constellation/index.go +++ b/src/constellation/index.go @@ -172,7 +172,11 @@ func Init() { utils.IsConstellationIP = IsConstellationIP // every user/device write in the product goes through here from now on - utils.SetPublishOpHook(publishOp) + if IsClientNode() { + utils.SetPublishOpHook(nil) + } else { + utils.SetPublishOpHook(publishOp) + } utils.GetConstellationTunnelRoutes = getConstellationTunnelRoutes utils.PublishRolesOp = func(roles map[utils.Role]utils.RoleConfig) error { return PublishDomainOp(DomainRoles, roles) @@ -212,6 +216,14 @@ func Init() { return } + // client node: no NATS/DNS, just sync the device list + if IsClientNode() { + go StartClientDeviceSync() + go InitPingLighthouses() + utils.Log("Constellation module initialized (client mode)") + return + } + go InitDNS() go StartNATS() diff --git a/src/index.go b/src/index.go index a474c14d..7cf2fb1e 100644 --- a/src/index.go +++ b/src/index.go @@ -206,7 +206,7 @@ func main() { } // @title Cosmos Server API -// @version 0.23.0 +// @version 0.23.1 // @description REST API for Cosmos Cloud server management // @BasePath /cosmos // @securityDefinitions.apikey BearerAuth