mirror of
https://github.com/azukaar/Cosmos-Server.git
synced 2026-10-12 02:11:26 +00:00
[release] v0.23.0-unstable012
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"description": "REST API for Cosmos Cloud server management",
|
||||
"title": "Cosmos Server API",
|
||||
"contact": {},
|
||||
"version": "0.23.0-unstable011"
|
||||
"version": "0.23.0-unstable012"
|
||||
},
|
||||
"paths": {
|
||||
"/_logs": {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"description": "REST API for Cosmos Cloud server management",
|
||||
"title": "Cosmos Server API",
|
||||
"contact": {},
|
||||
"version": "0.23.0-unstable011"
|
||||
"version": "0.23.0-unstable012"
|
||||
},
|
||||
"basePath": "/cosmos",
|
||||
"paths": {
|
||||
|
||||
@@ -2066,7 +2066,7 @@ info:
|
||||
contact: {}
|
||||
description: REST API for Cosmos Cloud server management
|
||||
title: Cosmos Server API
|
||||
version: 0.23.0-unstable011
|
||||
version: 0.23.0-unstable012
|
||||
paths:
|
||||
/_logs:
|
||||
get:
|
||||
|
||||
@@ -36609,7 +36609,7 @@ var swaggerSpec = []string{
|
||||
"nGxBNLXkUfj7lkPcQUjdGbelSmt304IyXddrXqw5z0qWUrk8EUnAHcqGl25pEp74g/Jl1d3u3hk2LCRU",
|
||||
"6XVLbP1rYT4/mVM+C86QMH7bvpTDmi/0tu+nX7KtTYIraxsK4Xp88iUXLkpfjw0Q2YN/C1SCPM6t3GzO",
|
||||
"sTe3sm6BWi7FAfvDSkorEMuY2ffXr1gSaCpczVtNUZu5kYVldDq+xtjpqZDElqgjJ4nIY2KLu5B0VXzJ",
|
||||
"CHEanYhdw7Ftcnx13uv3FkVgZu/l4PXPg5eHOVfaUIiXr14VRXFoxnpvej8PXg5euqQ1uNujz6g8evNn",
|
||||
"CHEanYhdw7Ftcnx13uv3FkVgZu/l4PXPg5eHOVfaUIiXr14XRXFoxnpvej8PXg5euqQ1uNujz6g8evNn",
|
||||
"z1HU9VAznUvucqTZKRMxw0BaQpXNzsY40fBFE1trzy3XZSwV/Dzuven9CgYmFXIz6zuNU75++bI4o8KV",
|
||||
"EL7oIxwTiQCidi11zoRxKpceP+qN433/T7P1X16+ajhFs6JPVTuSZ9IPnDrYgNhO//O3nP5MyAmLY0A+",
|
||||
"8LfGp/sgc5+7itAFaGLzGpJhSF0Vvf796eunfk/lqaGtGP5+xxNB4wqooeMRRkH+u2dDt3ufzJhHNGNH",
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package cosmossdk
|
||||
|
||||
// Version is the SDK version, synced with Cosmos Server at build time.
|
||||
const Version = "0.23.0-unstable011"
|
||||
const Version = "0.23.0-unstable012"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cosmos-server",
|
||||
"version": "0.23.0-unstable011",
|
||||
"version": "0.23.0-unstable012",
|
||||
"description": "",
|
||||
"main": "test-server.js",
|
||||
"bugs": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package constellation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -143,3 +144,38 @@ func TestUnitTunnelHostOverridden(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replays the production scenario: a manager (non-LB) receives an agent's
|
||||
// heartbeat over the wire and must answer DNS for the agent's plain routes.
|
||||
func TestUnitHandleDNSRequestFromWireHeartbeat(t *testing.T) {
|
||||
setupTestEnv(t, func(cfg *utils.Config) {
|
||||
cfg.ConstellationConfig.ThisDeviceName = "cosmos-0"
|
||||
cfg.HTTPConfig.Hostname = "cosmos.mocham.com"
|
||||
})
|
||||
seedDeviceCache(t, utils.ConstellationDevice{DeviceName: "cosmos-0", IP: "192.168.201.1"})
|
||||
|
||||
// verbatim shape of an agent heartbeat as stored in constellation-nodes
|
||||
wire := `{"DeviceName":"vpn","IP":"192.168.201.2","IsRelay":true,"IsLighthouse":true,"IsExitNode":true,"CosmosNode":1,"Tunnels":[],"hostnames":["vpn.mocham.com","test-url.com","filebrowser-vpn.mocham.com","159.65.210.47"],"runningDeployments":[],"monitoringOn":false}`
|
||||
var hb NodeHeartbeat
|
||||
if err := json.Unmarshal([]byte(wire), &hb); err != nil {
|
||||
t.Fatal("unmarshal wire heartbeat:", err)
|
||||
}
|
||||
if len(hb.Hostnames) != 4 {
|
||||
t.Fatalf("wire heartbeat decoded %d hostnames, want 4 (json tag drift?)", len(hb.Hostnames))
|
||||
}
|
||||
seedClusterDNS(t, buildClusterDNS([]NodeHeartbeat{hb}, nil))
|
||||
|
||||
tests := []struct {
|
||||
qName string
|
||||
want []string
|
||||
}{
|
||||
{"filebrowser-vpn.mocham.com.", []string{"192.168.201.2"}},
|
||||
{"vpn.mocham.com.", []string{"192.168.201.2"}},
|
||||
{"cosmos.mocham.com.", []string{"192.168.201.1"}}, // own hostname stays local
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if got := answeredIPs(t, tt.qName); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("DNS answer for %s = %v, want %v", tt.qName, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -642,6 +642,15 @@ func mergeTunnelHeartbeats(heartbeats []NodeHeartbeat, currentDeviceName string)
|
||||
return tunnels
|
||||
}
|
||||
|
||||
// tunnelsForNode gates serving on load-balancer status: only LBs serve tunnels,
|
||||
func tunnelsForNode(heartbeats []NodeHeartbeat, currentDeviceName string) []utils.ConstellationTunnel {
|
||||
isLB, err := GetCurrentDeviceIsLoadbalancer()
|
||||
if err != nil || !isLB {
|
||||
return []utils.ConstellationTunnel{}
|
||||
}
|
||||
return mergeTunnelHeartbeats(heartbeats, currentDeviceName)
|
||||
}
|
||||
|
||||
func UpdateLocalTunnelCache() {
|
||||
if IsConstellationStandalone() {
|
||||
return
|
||||
@@ -707,7 +716,7 @@ func UpdateLocalTunnelCache() {
|
||||
// every node keeps the cluster DNS map, even non load balancers
|
||||
setClusterDNS(buildClusterDNS(heartbeats, loadBalancerIPs()))
|
||||
|
||||
tunnels := mergeTunnelHeartbeats(heartbeats, currentDeviceName)
|
||||
tunnels := tunnelsForNode(heartbeats, currentDeviceName)
|
||||
|
||||
// Compare old and new cache using sorted copies for consistent comparison
|
||||
sortTunnelsForComparison := func(t []utils.ConstellationTunnel) []utils.ConstellationTunnel {
|
||||
@@ -746,16 +755,6 @@ func GetLocalTunnelCache() []utils.ConstellationTunnel {
|
||||
return []utils.ConstellationTunnel{}
|
||||
}
|
||||
|
||||
isLB, err := GetCurrentDeviceIsLoadbalancer()
|
||||
if err != nil {
|
||||
utils.Debug("[constellation] Failed to get current device load balancer status for tunnel cache retrieval " + err.Error())
|
||||
return []utils.ConstellationTunnel{}
|
||||
}
|
||||
|
||||
if !isLB {
|
||||
return []utils.ConstellationTunnel{}
|
||||
}
|
||||
|
||||
localTunnelCacheMutex.RLock()
|
||||
defer localTunnelCacheMutex.RUnlock()
|
||||
|
||||
|
||||
@@ -176,3 +176,24 @@ func TestUnitMergeTunnelHeartbeatsIgnoresUnnamedAdvertiser(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Serving tunnels is LB-only — even _ANY_ routes must not land on a
|
||||
// non-load-balancer, while an LB merges them as before.
|
||||
func TestUnitTunnelsForNodeGatesOnLoadBalancer(t *testing.T) {
|
||||
setupTestEnv(t, func(cfg *utils.Config) {
|
||||
cfg.ConstellationConfig.ThisDeviceName = "node-a"
|
||||
})
|
||||
heartbeats := []NodeHeartbeat{
|
||||
tunnelAdvertiser("node_b", "round_robin", false, false, 10*time.Second),
|
||||
}
|
||||
|
||||
seedDeviceCache(t, utils.ConstellationDevice{DeviceName: "node-a", IP: "192.168.201.5"})
|
||||
if got := tunnelsForNode(heartbeats, "node-a"); len(got) != 0 {
|
||||
t.Errorf("non-LB node serves %d tunnels, want 0", len(got))
|
||||
}
|
||||
|
||||
seedDeviceCache(t, utils.ConstellationDevice{DeviceName: "node-a", IP: "192.168.201.5", IsLoadBalancer: true})
|
||||
if got := tunnelsForNode(heartbeats, "node-a"); len(got) != 1 {
|
||||
t.Errorf("LB node serves %d tunnels, want 1", len(got))
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -206,7 +206,7 @@ func main() {
|
||||
}
|
||||
|
||||
// @title Cosmos Server API
|
||||
// @version 0.23.0-unstable011
|
||||
// @version 0.23.0-unstable012
|
||||
// @description REST API for Cosmos Cloud server management
|
||||
// @BasePath /cosmos
|
||||
// @securityDefinitions.apikey BearerAuth
|
||||
|
||||
Reference in New Issue
Block a user