mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix: disable relay if built-in DERP is disabled (#12654)
Fixes https://github.com/coder/coder/issues/12493
This commit is contained in:
@@ -418,6 +418,8 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("create DERP mesh TLS config: %w", err)
|
||||
}
|
||||
// We always want to run the replica manager even if we don't have DERP
|
||||
// enabled, since it's used to detect other coder servers for licensing.
|
||||
api.replicaManager, err = replicasync.New(ctx, options.Logger, options.Database, options.Pubsub, &replicasync.Options{
|
||||
ID: api.AGPL.ID,
|
||||
RelayAddress: options.DERPServerRelayAddress,
|
||||
@@ -428,7 +430,9 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("initialize replica: %w", err)
|
||||
}
|
||||
api.derpMesh = derpmesh.New(options.Logger.Named("derpmesh"), api.DERPServer, meshTLSConfig)
|
||||
if api.DERPServer != nil {
|
||||
api.derpMesh = derpmesh.New(options.Logger.Named("derpmesh"), api.DERPServer, meshTLSConfig)
|
||||
}
|
||||
|
||||
// Moon feature init. Proxyhealh is a go routine to periodically check
|
||||
// the health of all workspace proxies.
|
||||
@@ -666,11 +670,18 @@ func (api *API) updateEntitlements(ctx context.Context) error {
|
||||
}
|
||||
|
||||
api.replicaManager.SetCallback(func() {
|
||||
addresses := make([]string, 0)
|
||||
for _, replica := range api.replicaManager.Regional() {
|
||||
addresses = append(addresses, replica.RelayAddress)
|
||||
// Only update DERP mesh if the built-in server is enabled.
|
||||
if api.Options.DeploymentValues.DERP.Server.Enable {
|
||||
addresses := make([]string, 0)
|
||||
for _, replica := range api.replicaManager.Regional() {
|
||||
// Don't add replicas with an empty relay address.
|
||||
if replica.RelayAddress == "" {
|
||||
continue
|
||||
}
|
||||
addresses = append(addresses, replica.RelayAddress)
|
||||
}
|
||||
api.derpMesh.SetAddresses(addresses, false)
|
||||
}
|
||||
api.derpMesh.SetAddresses(addresses, false)
|
||||
_ = api.updateEntitlements(ctx)
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -13,6 +13,8 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
|
||||
agplaudit "github.com/coder/coder/v2/coderd/audit"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
@@ -27,7 +29,10 @@ import (
|
||||
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
|
||||
"github.com/coder/coder/v2/enterprise/coderd/license"
|
||||
"github.com/coder/coder/v2/enterprise/dbcrypt"
|
||||
"github.com/coder/coder/v2/enterprise/replicasync"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
"github.com/coder/retry"
|
||||
"github.com/coder/serpent"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@@ -371,6 +376,83 @@ func TestExternalTokenEncryption(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestMultiReplica_EmptyRelayAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
db, ps := dbtestutil.NewDB(t)
|
||||
logger := slogtest.Make(t, nil)
|
||||
|
||||
_, _ = coderdenttest.New(t, &coderdenttest.Options{
|
||||
EntitlementsUpdateInterval: 25 * time.Millisecond,
|
||||
ReplicaSyncUpdateInterval: 25 * time.Millisecond,
|
||||
Options: &coderdtest.Options{
|
||||
Logger: &logger,
|
||||
Database: db,
|
||||
Pubsub: ps,
|
||||
},
|
||||
})
|
||||
|
||||
mgr, err := replicasync.New(ctx, logger, db, ps, &replicasync.Options{
|
||||
ID: uuid.New(),
|
||||
RelayAddress: "",
|
||||
RegionID: 999,
|
||||
UpdateInterval: testutil.IntervalFast,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
defer mgr.Close()
|
||||
|
||||
// Send a bunch of updates to see if the coderd will log errors.
|
||||
{
|
||||
ctx, cancel := context.WithTimeout(ctx, testutil.IntervalMedium)
|
||||
for r := retry.New(testutil.IntervalFast, testutil.IntervalFast); r.Wait(ctx); {
|
||||
require.NoError(t, mgr.PublishUpdate())
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiReplica_EmptyRelayAddress_DisabledDERP(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
db, ps := dbtestutil.NewDB(t)
|
||||
logger := slogtest.Make(t, nil)
|
||||
|
||||
dv := coderdtest.DeploymentValues(t)
|
||||
dv.DERP.Server.Enable = serpent.Bool(false)
|
||||
dv.DERP.Config.URL = serpent.String("https://controlplane.tailscale.com/derpmap/default")
|
||||
|
||||
_, _ = coderdenttest.New(t, &coderdenttest.Options{
|
||||
EntitlementsUpdateInterval: 25 * time.Millisecond,
|
||||
ReplicaSyncUpdateInterval: 25 * time.Millisecond,
|
||||
Options: &coderdtest.Options{
|
||||
Logger: &logger,
|
||||
Database: db,
|
||||
Pubsub: ps,
|
||||
DeploymentValues: dv,
|
||||
},
|
||||
})
|
||||
|
||||
mgr, err := replicasync.New(ctx, logger, db, ps, &replicasync.Options{
|
||||
ID: uuid.New(),
|
||||
RelayAddress: "",
|
||||
RegionID: 999,
|
||||
UpdateInterval: testutil.IntervalFast,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
defer mgr.Close()
|
||||
|
||||
// Send a bunch of updates to see if the coderd will log errors.
|
||||
{
|
||||
ctx, cancel := context.WithTimeout(ctx, testutil.IntervalMedium)
|
||||
for r := retry.New(testutil.IntervalFast, testutil.IntervalFast); r.Wait(ctx); {
|
||||
require.NoError(t, mgr.PublishUpdate())
|
||||
}
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
// testDBAuthzRole returns a context with a subject that has a role
|
||||
// with permissions required for test setup.
|
||||
func testDBAuthzRole(ctx context.Context) context.Context {
|
||||
|
||||
Reference in New Issue
Block a user