2020-08-24 13:22:10 -04:00
|
|
|
package servers_test
|
|
|
|
|
|
|
|
|
|
import (
|
2021-07-14 09:14:24 -07:00
|
|
|
"context"
|
2020-08-24 13:22:10 -04:00
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
2021-09-07 22:13:19 -04:00
|
|
|
"github.com/hashicorp/boundary/api/recovery"
|
2020-08-24 13:22:10 -04:00
|
|
|
"github.com/hashicorp/boundary/api/roles"
|
|
|
|
|
"github.com/hashicorp/boundary/globals"
|
2022-05-09 12:45:10 -07:00
|
|
|
"github.com/hashicorp/boundary/internal/daemon/controller"
|
2020-08-24 13:22:10 -04:00
|
|
|
"github.com/hashicorp/boundary/internal/db"
|
2021-07-14 09:14:24 -07:00
|
|
|
"github.com/hashicorp/boundary/internal/kms"
|
2021-01-21 16:27:20 -05:00
|
|
|
"github.com/hashicorp/boundary/internal/servers"
|
2020-09-08 13:27:51 -07:00
|
|
|
"github.com/hashicorp/boundary/internal/types/scope"
|
2020-08-24 13:22:10 -04:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestRecoveryNonces(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
|
|
|
|
|
// Set these low so that we can not have the test run forever
|
|
|
|
|
globals.RecoveryTokenValidityPeriod = 10 * time.Second
|
2021-10-27 20:32:07 -04:00
|
|
|
globals.WorkerAuthNonceValidityPeriod = 10 * time.Second
|
|
|
|
|
controller.NonceCleanupInterval = 20 * time.Second
|
2020-08-24 13:22:10 -04:00
|
|
|
|
|
|
|
|
wrapper := db.TestWrapper(t)
|
|
|
|
|
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
|
|
|
|
RecoveryKms: wrapper,
|
|
|
|
|
})
|
|
|
|
|
defer tc.Shutdown()
|
|
|
|
|
|
2022-05-13 13:53:22 -04:00
|
|
|
externalWrappers := tc.Kms().GetExternalWrappers(context.Background())
|
|
|
|
|
externalRecovery := externalWrappers.Recovery()
|
|
|
|
|
require.Equal(externalRecovery, wrapper)
|
|
|
|
|
|
2020-08-24 13:22:10 -04:00
|
|
|
client := tc.Client()
|
|
|
|
|
repo := tc.ServersRepo()
|
|
|
|
|
|
|
|
|
|
// First, validate that we can't use the same token twice. Get two tokens,
|
|
|
|
|
// try to use the first twice (should succeed first time, fail second), then
|
|
|
|
|
// ensure second token works
|
|
|
|
|
token1, err := recovery.GenerateRecoveryToken(tc.Context(), wrapper)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
token2, err := recovery.GenerateRecoveryToken(tc.Context(), wrapper)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
// Token 1, try 1
|
|
|
|
|
client.SetToken(token1)
|
2020-08-27 20:43:33 -04:00
|
|
|
roleClient := roles.NewClient(client)
|
2020-09-24 14:34:58 -07:00
|
|
|
_, err = roleClient.Create(tc.Context(), scope.Global.String())
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
2021-10-27 20:32:07 -04:00
|
|
|
nonces, err := repo.ListNonces(tc.Context(), servers.NoncePurposeRecovery)
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Len(nonces, 1)
|
|
|
|
|
|
|
|
|
|
// Token 1, try 2
|
2020-09-24 14:34:58 -07:00
|
|
|
_, err = roleClient.Create(tc.Context(), scope.Global.String())
|
|
|
|
|
require.Error(err)
|
2021-10-27 20:32:07 -04:00
|
|
|
nonces, err = repo.ListNonces(tc.Context(), servers.NoncePurposeRecovery)
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Len(nonces, 1)
|
|
|
|
|
|
|
|
|
|
// Token 2
|
2020-09-08 13:27:51 -07:00
|
|
|
roleClient.ApiClient().SetToken(token2)
|
2020-09-24 14:34:58 -07:00
|
|
|
_, err = roleClient.Create(tc.Context(), scope.Global.String())
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
2021-10-27 20:32:07 -04:00
|
|
|
nonces, err = repo.ListNonces(tc.Context(), servers.NoncePurposeRecovery)
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Len(nonces, 2)
|
|
|
|
|
|
|
|
|
|
// Make sure they get cleaned up
|
2021-10-27 20:32:07 -04:00
|
|
|
time.Sleep(2 * controller.NonceCleanupInterval)
|
|
|
|
|
nonces, err = repo.ListNonces(tc.Context(), servers.NoncePurposeRecovery)
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Len(nonces, 0)
|
|
|
|
|
|
|
|
|
|
// And finally, make sure they still can't be used
|
|
|
|
|
for _, token := range []string{token1, token2} {
|
2020-09-08 13:27:51 -07:00
|
|
|
roleClient.ApiClient().SetToken(token)
|
2020-09-24 14:34:58 -07:00
|
|
|
_, err = roleClient.Create(tc.Context(), scope.Global.String())
|
|
|
|
|
require.Error(err)
|
2021-10-27 20:32:07 -04:00
|
|
|
nonces, err = repo.ListNonces(tc.Context(), servers.NoncePurposeRecovery)
|
2020-08-24 13:22:10 -04:00
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Len(nonces, 0)
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-21 16:27:20 -05:00
|
|
|
|
|
|
|
|
func TestTagUpdatingListing(t *testing.T) {
|
|
|
|
|
require := require.New(t)
|
|
|
|
|
|
|
|
|
|
wrapper := db.TestWrapper(t)
|
|
|
|
|
tc := controller.NewTestController(t, &controller.TestControllerOpts{
|
|
|
|
|
RecoveryKms: wrapper,
|
|
|
|
|
})
|
|
|
|
|
defer tc.Shutdown()
|
|
|
|
|
|
|
|
|
|
repo := tc.ServersRepo()
|
|
|
|
|
srv := &servers.Server{
|
|
|
|
|
PrivateId: "test1",
|
|
|
|
|
Type: "worker",
|
|
|
|
|
Address: "127.0.0.1",
|
|
|
|
|
Tags: map[string]*servers.TagValues{
|
|
|
|
|
"tag1": {
|
|
|
|
|
Values: []string{"value1", "value2"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
2021-09-30 08:47:34 -04:00
|
|
|
|
2021-01-21 16:27:20 -05:00
|
|
|
_, _, err := repo.UpsertServer(tc.Context(), srv, servers.WithUpdateTags(true))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
srv = &servers.Server{
|
|
|
|
|
PrivateId: "test2",
|
|
|
|
|
Type: "worker",
|
|
|
|
|
Address: "127.0.0.1",
|
|
|
|
|
Tags: map[string]*servers.TagValues{
|
|
|
|
|
"tag2": {
|
|
|
|
|
Values: []string{"value1", "value2"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
_, _, err = repo.UpsertServer(tc.Context(), srv, servers.WithUpdateTags(true))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
tags, err := repo.ListTagsForServers(tc.Context(), []string{"test1", "test2"})
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
|
|
|
|
|
// Base case
|
|
|
|
|
exp := []*servers.ServerTag{
|
|
|
|
|
{
|
|
|
|
|
ServerId: "test1",
|
|
|
|
|
Key: "tag1",
|
|
|
|
|
Value: "value1",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
ServerId: "test1",
|
|
|
|
|
Key: "tag1",
|
|
|
|
|
Value: "value2",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
ServerId: "test2",
|
|
|
|
|
Key: "tag2",
|
|
|
|
|
Value: "value1",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
ServerId: "test2",
|
|
|
|
|
Key: "tag2",
|
|
|
|
|
Value: "value2",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
require.Equal(exp, tags)
|
|
|
|
|
|
|
|
|
|
// Update without saying to update tags
|
|
|
|
|
srv = &servers.Server{
|
|
|
|
|
PrivateId: "test2",
|
|
|
|
|
Type: "worker",
|
|
|
|
|
Address: "192.168.1.1",
|
|
|
|
|
Tags: map[string]*servers.TagValues{
|
|
|
|
|
"tag22": {
|
|
|
|
|
Values: []string{"value21", "value22"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
_, _, err = repo.UpsertServer(tc.Context(), srv)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
tags, err = repo.ListTagsForServers(tc.Context(), []string{"test1", "test2"})
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Equal(exp, tags)
|
|
|
|
|
|
|
|
|
|
// Update tags and test again
|
|
|
|
|
_, _, err = repo.UpsertServer(tc.Context(), srv, servers.WithUpdateTags(true))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
tags, err = repo.ListTagsForServers(tc.Context(), []string{"test1", "test2"})
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.NotEqual(exp, tags)
|
|
|
|
|
// Update and try again
|
|
|
|
|
exp[2] = &servers.ServerTag{
|
|
|
|
|
ServerId: "test2",
|
|
|
|
|
Key: "tag22",
|
|
|
|
|
Value: "value21",
|
|
|
|
|
}
|
|
|
|
|
exp[3] = &servers.ServerTag{
|
|
|
|
|
ServerId: "test2",
|
|
|
|
|
Key: "tag22",
|
|
|
|
|
Value: "value22",
|
|
|
|
|
}
|
|
|
|
|
require.Equal(exp, tags)
|
|
|
|
|
}
|
2021-07-14 09:14:24 -07:00
|
|
|
|
|
|
|
|
func TestListServersWithLiveness(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
require := require.New(t)
|
|
|
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
|
|
|
rw := db.New(conn)
|
|
|
|
|
wrapper := db.TestWrapper(t)
|
|
|
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
|
|
|
serversRepo, err := servers.NewRepository(rw, rw, kms)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
|
|
newServer := func(privateId string) *servers.Server {
|
|
|
|
|
result := &servers.Server{
|
|
|
|
|
PrivateId: privateId,
|
|
|
|
|
Type: "worker",
|
|
|
|
|
Address: "127.0.0.1",
|
|
|
|
|
}
|
|
|
|
|
_, rowsUpdated, err := serversRepo.UpsertServer(ctx, result)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Equal(1, rowsUpdated)
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server1 := newServer("test1")
|
|
|
|
|
server2 := newServer("test2")
|
|
|
|
|
server3 := newServer("test3")
|
|
|
|
|
|
|
|
|
|
// Sleep the default liveness time (15sec currently) +1s
|
|
|
|
|
time.Sleep(time.Second * 16)
|
|
|
|
|
|
|
|
|
|
// Push an upsert to the first worker so that its status has been
|
|
|
|
|
// updated.
|
|
|
|
|
_, rowsUpdated, err := serversRepo.UpsertServer(ctx, server1)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Equal(1, rowsUpdated)
|
|
|
|
|
|
|
|
|
|
requireIds := func(expected []string, actual []*servers.Server) {
|
|
|
|
|
require.Len(expected, len(actual))
|
|
|
|
|
want := make(map[string]struct{})
|
|
|
|
|
for _, v := range expected {
|
|
|
|
|
want[v] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
got := make(map[string]struct{})
|
|
|
|
|
for _, v := range actual {
|
|
|
|
|
got[v.PrivateId] = struct{}{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
require.Equal(want, got)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Default liveness, should only list 1
|
|
|
|
|
result, err := serversRepo.ListServers(ctx, servers.ServerTypeWorker)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Len(result, 1)
|
|
|
|
|
requireIds([]string{server1.PrivateId}, result)
|
|
|
|
|
|
|
|
|
|
// Upsert second server.
|
|
|
|
|
_, rowsUpdated, err = serversRepo.UpsertServer(ctx, server2)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Equal(1, rowsUpdated)
|
|
|
|
|
|
|
|
|
|
// Static liveness. Should get two, so long as this did not take
|
|
|
|
|
// more than 5s to execute.
|
|
|
|
|
result, err = serversRepo.ListServers(ctx, servers.ServerTypeWorker, servers.WithLiveness(time.Second*5))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Len(result, 2)
|
|
|
|
|
requireIds([]string{server1.PrivateId, server2.PrivateId}, result)
|
|
|
|
|
|
|
|
|
|
// Liveness disabled, should get all three servers.
|
|
|
|
|
result, err = serversRepo.ListServers(ctx, servers.ServerTypeWorker, servers.WithLiveness(-1))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
require.Len(result, 3)
|
|
|
|
|
requireIds([]string{server1.PrivateId, server2.PrivateId, server3.PrivateId}, result)
|
|
|
|
|
}
|