Merge remote-tracking branch 'origin/byow-attrib-consolidation' into llb-byow

This commit is contained in:
Jeff Mitchell committed 2022-06-15 16:04:16 -05:00
commit bfd9565010
47 files changed
+1649 -1652

No files matched your search

-12
View File
@@ -87,18 +87,6 @@ func WithRecursive(recurse bool) Option {
}
}
func WithAddress(inAddress string) Option {
return func(o *options) {
o.postMap["address"] = inAddress
}
}
func DefaultAddress() Option {
return func(o *options) {
o.postMap["address"] = nil
}
}
func WithDescription(inDescription string) Option {
return func(o *options) {
o.postMap["description"] = inDescription
+16 -17
View File
@@ -13,23 +13,22 @@ import (
)
type Worker struct {
Id string `json:"id,omitempty"`
ScopeId string `json:"scope_id,omitempty"`
Scope *scopes.ScopeInfo `json:"scope,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
CreatedTime time.Time `json:"created_time,omitempty"`
UpdatedTime time.Time `json:"updated_time,omitempty"`
Version uint32 `json:"version,omitempty"`
Address string `json:"address,omitempty"`
CanonicalAddress string `json:"canonical_address,omitempty"`
Tags map[string][]string `json:"tags,omitempty"`
CanonicalTags map[string][]string `json:"canonical_tags,omitempty"`
LastStatusTime time.Time `json:"last_status_time,omitempty"`
WorkerProvidedConfiguration *WorkerProvidedConfiguration `json:"worker_provided_configuration,omitempty"`
WorkerGeneratedAuthToken string `json:"worker_generated_auth_token,omitempty"`
ActiveConnectionCount uint32 `json:"active_connection_count,omitempty"`
AuthorizedActions []string `json:"authorized_actions,omitempty"`
Id string `json:"id,omitempty"`
ScopeId string `json:"scope_id,omitempty"`
Scope *scopes.ScopeInfo `json:"scope,omitempty"`
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
CreatedTime time.Time `json:"created_time,omitempty"`
UpdatedTime time.Time `json:"updated_time,omitempty"`
Version uint32 `json:"version,omitempty"`
Address string `json:"address,omitempty"`
CanonicalTags map[string][]string `json:"canonical_tags,omitempty"`
ConfigTags map[string][]string `json:"config_tags,omitempty"`
LastStatusTime time.Time `json:"last_status_time,omitempty"`
WorkerGeneratedAuthToken string `json:"worker_generated_auth_token,omitempty"`
ActiveConnectionCount uint32 `json:"active_connection_count,omitempty"`
Type string `json:"type,omitempty"`
AuthorizedActions []string `json:"authorized_actions,omitempty"`
response *api.Response
}
@@ -1,8 +0,0 @@
// Code generated by "make api"; DO NOT EDIT.
package workers
type WorkerProvidedConfiguration struct {
Address string `json:"address,omitempty"`
Name string `json:"name,omitempty"`
Tags map[string][]string `json:"tags,omitempty"`
}
+1
View File
@@ -78,6 +78,7 @@ const (
CanonicalAddressField = "canonical_address"
TagsField = "tags"
CanonicalTagsField = "canonical_tags"
ConfigTagsField = "config_tags"
ConfigurationField = "configuration"
WorkerGeneratedAuthTokenField = "worker_generated_auth_token"
WorkerProvidedConfigurationField = "worker_provided_configuration"
-4
View File
@@ -746,10 +746,6 @@ var inputStructs = []*structInfo{
fieldFilter: []string{"private_key"},
recursiveListing: true,
},
{
inProto: &workers.WorkerProvidedConfiguration{},
outFile: "workers/worker_provided_configuration.gen.go",
},
{
inProto: &workers.Worker{},
outFile: "workers/worker.gen.go",
+1 -1
View File
@@ -70,7 +70,7 @@ func parsePBs() {
name = fmt.Sprintf("%s.%s", pkg, name)
}
switch name {
case "v1.AuthorizedCollectionActionsEntry", "v1.CanonicalTagsEntry", "v1.TagsEntry":
case "v1.AuthorizedCollectionActionsEntry", "v1.CanonicalTagsEntry", "v1.TagsEntry", "v1.ConfigTagsEntry":
fi.FieldType = "map[string][]string"
default:
fi.FieldType = sliceText + ptr + name
+2
View File
@@ -587,6 +587,8 @@ func (c *Command) Run(args []string) int {
c.UI.Error("Worker Auth KMS not found after parsing KMS blocks")
return base.CommandUserError
}
c.Config.Worker.Name = ""
c.Config.Worker.Description = ""
c.InfoKeys = append(c.InfoKeys, "[Worker-Auth] AEAD Key Bytes")
c.Info["[Worker-Auth] AEAD Key Bytes"] = c.Config.DevWorkerAuthKey
}
+4
View File
@@ -197,6 +197,10 @@ func (c *Command) Run(args []string) int {
c.UI.Error("No worker auth KMS specified and no worker auth storage path specified.")
return base.CommandUserError
}
if c.Config.Worker.Name != "" || c.Config.Worker.Description != "" {
c.UI.Error("Worker config cannot contain name or description when using PKI-based worker authentication; it must be set via the API.")
return base.CommandUserError
}
default:
if c.Config.Worker.Name == "" {
c.UI.Error("Worker is using KMS auth but has no name set. It must be the unique name of this instance.")
@@ -106,7 +106,7 @@ func TestServer_ReloadWorkerTags(t *testing.T) {
t.Helper()
serversRepo, err := testController.Controller().ServersRepoFn()
require.NoError(err)
w, err := serversRepo.LookupWorkerByWorkerReportedName(testController.Context(), name)
w, err := serversRepo.LookupWorkerByName(testController.Context(), name)
require.NoError(err)
require.NotNil(w)
v, ok := w.CanonicalTags()[key]
+17 -61
View File
@@ -59,6 +59,11 @@ func (c *Command) printListTable(items []*workers.Worker) string {
fmt.Sprintf(" Scope ID: %s", item.ScopeId),
)
}
if item.Type != "" {
output = append(output,
fmt.Sprintf(" Type: %s", item.Type),
)
}
if item.Version > 0 {
output = append(output,
fmt.Sprintf(" Version: %d", item.Version),
@@ -74,9 +79,9 @@ func (c *Command) printListTable(items []*workers.Worker) string {
fmt.Sprintf(" Description: %s", item.Description),
)
}
if item.CanonicalAddress != "" {
if item.Address != "" {
output = append(output,
fmt.Sprintf(" Canonical Address: %s", item.CanonicalAddress),
fmt.Sprintf(" Address: %s", item.Address),
)
}
if !item.LastStatusTime.IsZero() {
@@ -117,6 +122,12 @@ func printItemTable(result api.GenericResult) string {
if item.Description != "" {
nonAttributeMap["Description"] = item.Description
}
if item.Type != "" {
nonAttributeMap["Type"] = item.Type
}
if item.Address != "" {
nonAttributeMap["Address"] = item.Address
}
if !item.LastStatusTime.IsZero() {
nonAttributeMap["Last Status Time"] = item.LastStatusTime
}
@@ -142,69 +153,14 @@ func printItemTable(result api.GenericResult) string {
)
}
var workerProvidedTags map[string][]string
var workerProvidedAddress string
if item.WorkerProvidedConfiguration != nil {
config := item.WorkerProvidedConfiguration
configMap := make(map[string]any)
if config.Address != "" {
configMap["Address"] = config.Address
workerProvidedAddress = config.Address
}
if config.Name != "" {
configMap["Name"] = config.Name
}
ret = append(ret,
"",
" Worker-Provided Configuration:",
base.WrapMap(4, maxLength, configMap),
)
workerProvidedTags = config.Tags
}
if len(item.Address) > 0 || len(item.CanonicalAddress) > 0 || len(workerProvidedAddress) > 0 {
ret = append(ret,
"",
" Address:",
)
if len(item.Address) > 0 {
ret = append(ret,
" Item (via API):",
" "+item.Address,
)
}
if len(workerProvidedAddress) > 0 {
ret = append(ret,
" Worker Configuration:",
" "+workerProvidedAddress,
)
}
if len(item.CanonicalAddress) > 0 {
ret = append(ret,
" Canonical:",
" "+item.CanonicalAddress,
)
}
}
if len(item.Tags) > 0 || len(item.CanonicalTags) > 0 || len(workerProvidedTags) > 0 {
if len(item.CanonicalTags) > 0 || len(item.ConfigTags) > 0 {
ret = append(ret,
"",
" Tags:",
)
if len(item.Tags) > 0 {
tagMap := make(map[string]any, len(item.Tags))
for k, v := range item.Tags {
tagMap[k] = v
}
ret = append(ret,
" Item (via API):",
base.WrapMap(6, 2, tagMap),
)
}
if len(workerProvidedTags) > 0 {
tagMap := make(map[string]any, len(workerProvidedTags))
for k, v := range workerProvidedTags {
if len(item.ConfigTags) > 0 {
tagMap := make(map[string]any, len(item.ConfigTags))
for k, v := range item.ConfigTags {
tagMap[k] = v
}
ret = append(ret,
@@ -65,7 +65,9 @@ func (ws *workerServiceServer) Status(ctx context.Context, req *pbs.StatusReques
}
switch {
case wStat.GetName() == "" && wStat.GetKeyId() == "":
return &pbs.StatusResponse{}, status.Error(codes.InvalidArgument, "Name and keyId are not set in the request; at least one is required.")
return &pbs.StatusResponse{}, status.Error(codes.InvalidArgument, "Name and keyId are not set in the request; one is required.")
case wStat.GetName() != "" && wStat.GetKeyId() != "":
return &pbs.StatusResponse{}, status.Error(codes.InvalidArgument, "Name and keyId are both set in the request; only one is allowed.")
case wStat.GetAddress() == "":
return &pbs.StatusResponse{}, status.Error(codes.InvalidArgument, "Address is not set but is required.")
}
@@ -88,17 +90,18 @@ func (ws *workerServiceServer) Status(ctx context.Context, req *pbs.StatusReques
})
}
wKeyId := wStat.GetKeyId()
wConf := servers.NewWorkerForStatus(scope.Global.String(),
wConf := servers.NewWorker(scope.Global.String(),
servers.WithName(wStat.GetName()),
servers.WithDescription(wStat.GetDescription()),
servers.WithAddress(wStat.GetAddress()),
servers.WithWorkerTags(workerTags...),
servers.WithKeyId(wKeyId))
servers.WithWorkerTags(workerTags...))
opts := []servers.Option{servers.WithUpdateTags(req.GetUpdateTags())}
if wStat.GetPublicId() != "" {
opts = append(opts, servers.WithPublicId(wStat.GetPublicId()))
}
if wStat.GetKeyId() != "" {
opts = append(opts, servers.WithKeyId(wStat.GetKeyId()))
}
wrk, err := serverRepo.UpsertWorkerStatus(ctx, wConf, opts...)
if err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error storing worker status"))
@@ -229,7 +232,7 @@ func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.Looku
}
var w *servers.Worker
if req.WorkerKeyId != "" {
workerId, err := serversRepo.LookupWorkerIdByWorkerReportedKeyId(ctx, req.WorkerKeyId)
workerId, err := serversRepo.LookupWorkerIdByKeyId(ctx, req.WorkerKeyId)
if err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error looking up worker by keyId", "keyId", req.WorkerKeyId))
return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, "Error looking up tags for server: %v", err)
@@ -240,7 +243,7 @@ func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.Looku
return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, "Error looking up tags for server: %v", err)
}
} else {
w, err = serversRepo.LookupWorkerByWorkerReportedName(ctx, req.GetServerId())
w, err = serversRepo.LookupWorkerByName(ctx, req.GetServerId())
if err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error looking up worker by name", "name", req.ServerId))
return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, "Error looking up tags for server: %v", err)
@@ -255,12 +258,8 @@ func (ws *workerServiceServer) LookupSession(ctx context.Context, req *pbs.Looku
event.WriteError(ctx, op, err, event.WithInfoMsg("error creating worker filter evaluator", "server_id", req.ServerId))
return &pbs.LookupSessionResponse{}, status.Errorf(codes.Internal, "Error creating worker filter evaluator: %v", err)
}
name := w.GetName()
if name == "" {
name = w.GetWorkerReportedName()
}
filterInput := map[string]interface{}{
"name": name,
"name": w.GetName(),
"tags": tagMap,
}
ok, err := eval.Evaluate(filterInput)
@@ -391,7 +390,7 @@ func (ws *workerServiceServer) AuthorizeConnection(ctx context.Context, req *pbs
if err != nil {
return nil, status.Errorf(codes.Internal, "error getting servers repo: %v", err)
}
w, err := serversRepo.LookupWorkerByWorkerReportedName(ctx, req.GetWorkerId())
w, err := serversRepo.LookupWorkerByName(ctx, req.GetWorkerId())
if err != nil {
return nil, status.Errorf(codes.Internal, "error looking up worker: %v", err)
}
@@ -71,7 +71,7 @@ func TestStatus(t *testing.T) {
target.WithSessionConnectionLimit(-1),
)
worker1 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
@@ -107,8 +107,8 @@ func TestStatus(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Name: worker1.GetName(),
Address: worker1.GetAddress(),
},
},
want: &pbs.StatusResponse{
@@ -127,8 +127,8 @@ func TestStatus(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Name: worker1.GetName(),
Address: worker1.GetAddress(),
},
Jobs: []*pbs.JobStatus{
{
@@ -166,10 +166,10 @@ func TestStatus(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Address: worker1.CanonicalAddress(),
Address: worker1.GetAddress(),
},
},
wantErrMsg: status.Error(codes.InvalidArgument, "Name and keyId are not set in the request; at least one is required.").Error(),
wantErrMsg: status.Error(codes.InvalidArgument, "Name and keyId are not set in the request; one is required.").Error(),
},
{
name: "No Address",
@@ -177,7 +177,7 @@ func TestStatus(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Name: worker1.GetWorkerReportedName(),
Name: worker1.GetName(),
},
},
wantErrMsg: status.Error(codes.InvalidArgument, "Address is not set but is required.").Error(),
@@ -257,7 +257,7 @@ func TestStatusSessionClosed(t *testing.T) {
target.WithSessionConnectionLimit(-1),
)
worker1 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
@@ -310,8 +310,8 @@ func TestStatusSessionClosed(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Name: worker1.GetName(),
Address: worker1.GetAddress(),
},
Jobs: []*pbs.JobStatus{
{
@@ -408,7 +408,7 @@ func TestStatusDeadConnection(t *testing.T) {
Address: "127.0.0.1",
})
worker1 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
serversRepoFn := func() (*servers.Repository, error) {
return serverRepo, nil
@@ -477,8 +477,8 @@ func TestStatusDeadConnection(t *testing.T) {
req := &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
PublicId: worker1.GetPublicId(),
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Name: worker1.GetName(),
Address: worker1.GetAddress(),
},
Jobs: []*pbs.JobStatus{
{
@@ -578,7 +578,7 @@ func TestStatusWorkerWithKeyId(t *testing.T) {
target.WithSessionConnectionLimit(-1),
)
worker1 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestPkiWorker(t, conn, wrapper)
rootStorage, err := servers.NewRepositoryStorage(ctx, rw, rw, kms)
require.NoError(t, err)
@@ -636,8 +636,7 @@ func TestStatusWorkerWithKeyId(t *testing.T) {
wantErr: false,
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Address: "someaddress",
KeyId: nodeInfo.Id,
},
},
@@ -657,8 +656,7 @@ func TestStatusWorkerWithKeyId(t *testing.T) {
req: &pbs.StatusRequest{
WorkerStatus: &servers.ServerWorkerStatus{
KeyId: nodeInfo.Id,
Name: worker1.GetWorkerReportedName(),
Address: worker1.CanonicalAddress(),
Address: "someaddress",
},
Jobs: []*pbs.JobStatus{
{
@@ -703,6 +701,7 @@ func TestStatusWorkerWithKeyId(t *testing.T) {
assert.Equal(tc.wantErrMsg, err.Error())
return
}
require.NoError(err)
assert.Empty(
cmp.Diff(
tc.want,
@@ -2140,7 +2140,7 @@ type workerList []*servers.Worker
func (w workerList) addresses() []string {
ret := make([]string, 0, len(w))
for _, worker := range w {
ret = append(ret, worker.CanonicalAddress())
ret = append(ret, worker.GetAddress())
}
return ret
}
@@ -2149,7 +2149,7 @@ func (w workerList) addresses() []string {
func (w workerList) workerInfos() []*pb.WorkerInfo {
ret := make([]*pb.WorkerInfo, 0, len(w))
for _, worker := range w {
ret = append(ret, &pb.WorkerInfo{Address: worker.CanonicalAddress()})
ret = append(ret, &pb.WorkerInfo{Address: worker.GetAddress()})
}
return ret
}
@@ -2159,15 +2159,8 @@ func (w workerList) workerInfos() []*pb.WorkerInfo {
func (w workerList) filtered(eval *bexpr.Evaluator) (workerList, error) {
var ret []*servers.Worker
for _, worker := range w {
// TODO: Decide how we are actually going to filter by name now that
// we are separating reported status name and the resource name.
name := worker.GetName()
if name == "" {
name = worker.GetWorkerReportedName()
}
filterInput := map[string]interface{}{
"name": name,
"name": worker.GetName(),
"tags": worker.CanonicalTags(),
}
ok, err := eval.Evaluate(filterInput)
@@ -4,6 +4,7 @@ import (
"fmt"
"testing"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/types/scope"
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/targets"
@@ -32,18 +33,20 @@ func TestWorkerList_Addresses(t *testing.T) {
}
func TestWorkerList_Filter(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
var workers []*servers.Worker
for i := 0; i < 5; i++ {
switch {
case i%2 == 0:
workers = append(workers, servers.NewWorker(scope.Global.String(),
workers = append(workers, servers.TestKmsWorker(t, conn, wrapper,
servers.WithName(fmt.Sprintf("test_worker_%d", i)),
servers.WithWorkerTags(&servers.Tag{
Key: fmt.Sprintf("key%d", i),
Value: fmt.Sprintf("value%d", i),
})))
default:
workers = append(workers, servers.NewWorkerForStatus(scope.Global.String(),
workers = append(workers, servers.TestPkiWorker(t, conn, wrapper,
servers.WithName(fmt.Sprintf("test_worker_%d", i)),
servers.WithWorkerTags(&servers.Tag{
Key: "key",
@@ -2784,7 +2784,7 @@ func TestAuthorizeSession(t *testing.T) {
require.NoError(t, err)
// Tell our DB that there is a worker ready to serve the data
servers.TestWorker(t, conn, wrapper)
servers.TestKmsWorker(t, conn, wrapper)
asRes1, err := s.AuthorizeSession(ctx, &pbs.AuthorizeSessionRequest{
Id: tar.GetPublicId(),
@@ -3062,7 +3062,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
require.NoError(t, err)
// Tell our DB that there is a worker ready to serve the data
servers.TestWorker(t, conn, wrapper)
servers.TestKmsWorker(t, conn, wrapper)
asRes, err := s.AuthorizeSession(ctx, &pbs.AuthorizeSessionRequest{
Id: tar.GetPublicId(),
@@ -3,6 +3,7 @@ package workers
import (
"context"
"fmt"
"strings"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/daemon/controller/auth"
@@ -19,6 +20,7 @@ import (
"github.com/hashicorp/boundary/internal/types/resource"
"github.com/hashicorp/boundary/internal/types/scope"
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/workers"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/nodeenrollment/types"
"github.com/mr-tron/base58"
"google.golang.org/grpc/codes"
@@ -27,6 +29,11 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
)
const (
PkiWorkerType = "pki"
KmsWorkerType = "kms"
)
var (
maskManager handlers.MaskManager
@@ -330,7 +337,6 @@ func (s Service) createInRepo(ctx context.Context, worker *pb.Worker, creds *typ
worker.GetScopeId(),
servers.WithName(worker.GetName().GetValue()),
servers.WithDescription(worker.GetDescription().GetValue()),
servers.WithAddress(worker.GetAddress().GetValue()),
)
retWorker, err := repo.CreateWorker(ctx, newWorker, servers.WithFetchNodeCredentialsRequest(creds))
if err != nil {
@@ -364,9 +370,6 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, id string, mask []st
if name := item.GetName(); name != nil {
opts = append(opts, servers.WithName(name.GetValue()))
}
if addr := item.GetAddress(); addr != nil {
opts = append(opts, servers.WithAddress(addr.GetValue()))
}
w := servers.NewWorker(scopeId, opts...)
w.PublicId = id
dbMask := maskManager.Translate(mask)
@@ -452,12 +455,22 @@ func toProto(ctx context.Context, in *servers.Worker, opt ...handlers.Option) (*
}
if outputFields.Has(globals.AuthorizedActionsField) {
out.AuthorizedActions = opts.WithAuthorizedActions
if in.Type == KmsWorkerType && out.AuthorizedActions != nil {
// KMS workers cannot be updated through the API
allActions := out.AuthorizedActions
out.AuthorizedActions = make([]string, 0, len(allActions))
for _, act := range allActions {
if act != action.Update.String() {
out.AuthorizedActions = append(out.AuthorizedActions, act)
}
}
}
}
if outputFields.Has(globals.AddressField) && in.GetAddress() != "" {
out.Address = wrapperspb.String(in.GetAddress())
out.Address = in.GetAddress()
}
if outputFields.Has(globals.CanonicalAddressField) {
out.CanonicalAddress = in.CanonicalAddress()
if outputFields.Has(globals.TypeField) && in.GetType() != "" {
out.Type = in.GetType()
}
if outputFields.Has(globals.LastStatusTimeField) {
out.LastStatusTime = in.GetLastStatusTime().GetTimestamp()
@@ -465,6 +478,13 @@ func toProto(ctx context.Context, in *servers.Worker, opt ...handlers.Option) (*
if outputFields.Has(globals.ActiveConnectionCountField) {
out.ActiveConnectionCount = &wrapperspb.UInt32Value{Value: in.ActiveConnectionCount()}
}
if outputFields.Has(globals.ConfigTagsField) && len(in.GetConfigTags()) > 0 {
var err error
out.ConfigTags, err = tagsToMapProto(in.GetConfigTags())
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error preparing config tags proto"))
}
}
if outputFields.Has(globals.CanonicalTagsField) && len(in.CanonicalTags()) > 0 {
var err error
out.CanonicalTags, err = tagsToMapProto(in.CanonicalTags())
@@ -472,31 +492,6 @@ func toProto(ctx context.Context, in *servers.Worker, opt ...handlers.Option) (*
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error preparing canonical tags proto"))
}
}
if outputFields.Has(globals.TagsField) && len(in.GetApiTags()) > 0 {
var err error
out.Tags, err = tagsToMapProto(in.GetApiTags())
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error preparing api tags proto"))
}
}
if outputFields.Has(globals.ConfigurationField) {
if in.GetWorkerReportedAddress() != "" ||
in.GetWorkerReportedName() != "" ||
len(in.GetConfigTags()) > 0 {
out.WorkerProvidedConfiguration = &pb.WorkerProvidedConfiguration{}
}
if len(in.GetConfigTags()) > 0 {
var err error
out.GetWorkerProvidedConfiguration().Tags, err = tagsToMapProto(in.GetConfigTags())
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error preparing config tags proto"))
}
}
if out.WorkerProvidedConfiguration != nil {
out.GetWorkerProvidedConfiguration().Address = in.GetWorkerReportedAddress()
out.GetWorkerProvidedConfiguration().Name = in.GetWorkerReportedName()
}
}
return &out, nil
}
@@ -551,17 +546,25 @@ func validateDeleteRequest(req *pbs.DeleteWorkerRequest) error {
func validateUpdateRequest(req *pbs.UpdateWorkerRequest) error {
return handlers.ValidateUpdateRequest(req, req.GetItem(), func() map[string]string {
badFields := map[string]string{}
if req.GetItem().GetWorkerProvidedConfiguration() != nil {
badFields[globals.ConfigurationField] = "This is a read only field."
}
if req.GetItem().GetCanonicalAddress() != "" {
badFields[globals.CanonicalAddressField] = "This is a read only field."
if req.GetItem().GetAddress() != "" {
badFields[globals.AddressField] = "This is a read only field."
}
if req.GetItem().GetCanonicalTags() != nil {
badFields[globals.CanonicalAddressField] = "This is a read only field."
}
if req.GetItem().GetTags() != nil {
badFields[globals.TagsField] = "These values cannot be updated in this type of request."
if req.GetItem().GetConfigTags() != nil {
badFields[globals.TagsField] = "This is a read only field."
}
nameString := req.GetItem().GetName().String()
if !strutil.Printable(nameString) {
badFields[globals.NameField] = "Contains non-printable characters"
}
if strings.ToLower(nameString) != nameString {
badFields[globals.NameField] = "Must be all lowercase."
}
descriptionString := req.GetItem().GetDescription().String()
if !strutil.Printable(descriptionString) {
badFields[globals.DescriptionField] = "Contains non-printable characters."
}
return badFields
}, servers.WorkerPrefix)
@@ -583,24 +586,32 @@ func validateCreateRequest(req *pbs.CreateWorkerLedRequest) error {
if req.GetItem().WorkerGeneratedAuthToken == nil {
badFields[globals.WorkerGeneratedAuthTokenField] = cannotBeEmptyMsg
}
if req.GetItem().CanonicalAddress != "" {
if req.GetItem().Address != "" {
badFields[globals.CanonicalAddressField] = readOnlyFieldMsg
}
if req.GetItem().Tags != nil {
badFields[globals.TagsField] = readOnlyFieldMsg
}
if req.GetItem().CanonicalTags != nil {
badFields[globals.CanonicalTagsField] = readOnlyFieldMsg
}
if req.GetItem().ConfigTags != nil {
badFields[globals.ConfigTagsField] = readOnlyFieldMsg
}
if req.GetItem().LastStatusTime != nil {
badFields[globals.LastStatusTimeField] = readOnlyFieldMsg
}
if req.GetItem().WorkerProvidedConfiguration != nil {
badFields[globals.WorkerProvidedConfigurationField] = readOnlyFieldMsg
}
if req.GetItem().AuthorizedActions != nil {
badFields[globals.AuthorizedActionsField] = readOnlyFieldMsg
}
nameString := req.GetItem().GetName().String()
if !strutil.Printable(nameString) {
badFields[globals.NameField] = "Name contains non-printable characters."
}
if strings.ToLower(nameString) != nameString {
badFields[globals.NameField] = "Name must be all lowercase."
}
descriptionString := req.GetItem().GetDescription().String()
if !strutil.Printable(descriptionString) {
badFields[globals.DescriptionField] = "Description contains non-printable characters."
}
return badFields
})
}
@@ -16,10 +16,12 @@ import (
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/scope"
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes"
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/workers"
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/workers"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/nodeenrollment/rotation"
"github.com/hashicorp/nodeenrollment/storage/file"
"github.com/hashicorp/nodeenrollment/types"
@@ -63,51 +65,73 @@ func TestGet(t *testing.T) {
return repo, nil
}
worker := servers.TestWorker(t, conn, wrap,
servers.WithName("test worker names"),
servers.WithDescription("test worker description"),
servers.WithAddress("test worker address"),
kmsWorker := servers.TestKmsWorker(t, conn, wrap,
servers.WithName("test kms worker names"),
servers.WithDescription("test kms worker description"),
servers.WithAddress("test kms worker address"),
servers.WithWorkerTags(&servers.Tag{Key: "key", Value: "val"}))
kmsAuthzActions := make([]string, len(testAuthorizedActions))
copy(kmsAuthzActions, testAuthorizedActions)
wantKmsWorker := &pb.Worker{
Id: kmsWorker.GetPublicId(),
ScopeId: kmsWorker.GetScopeId(),
Scope: &scopes.ScopeInfo{Id: kmsWorker.GetScopeId(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
CreatedTime: kmsWorker.CreateTime.GetTimestamp(),
UpdatedTime: kmsWorker.UpdateTime.GetTimestamp(),
Version: kmsWorker.GetVersion(),
Name: wrapperspb.String(kmsWorker.GetName()),
Description: wrapperspb.String(kmsWorker.GetDescription()),
Address: kmsWorker.GetAddress(),
AuthorizedActions: strutil.StrListDelete(kmsAuthzActions, action.Update.String()),
LastStatusTime: kmsWorker.GetLastStatusTime().GetTimestamp(),
CanonicalTags: map[string]*structpb.ListValue{
"key": structListValue(t, "val"),
},
ConfigTags: map[string]*structpb.ListValue{
"key": structListValue(t, "val"),
},
Type: KmsWorkerType,
}
var pkiWorkerKeyId string
pkiWorker := servers.TestPkiWorker(t, conn, wrap,
servers.WithName("test pki worker names"),
servers.WithDescription("test pki worker description"),
servers.WithTestPkiWorkerAuthorizedKeyId(&pkiWorkerKeyId))
// Add config tags to the created worker
worker, err = repo.UpsertWorkerStatus(context.Background(),
servers.NewWorkerForStatus(worker.GetScopeId(),
servers.WithName(worker.GetWorkerReportedName()),
servers.WithAddress(worker.GetWorkerReportedAddress()),
pkiWorker, err = repo.UpsertWorkerStatus(context.Background(),
servers.NewWorker(pkiWorker.GetScopeId(),
servers.WithAddress("test kms worker address"),
servers.WithWorkerTags(&servers.Tag{
Key: "config",
Value: "test",
})),
servers.WithUpdateTags(true),
servers.WithPublicId(worker.GetPublicId()))
servers.WithPublicId(pkiWorker.GetPublicId()),
servers.WithKeyId(pkiWorkerKeyId))
require.NoError(t, err)
wantWorker := &pb.Worker{
Id: worker.GetPublicId(),
ScopeId: worker.GetScopeId(),
Scope: &scopes.ScopeInfo{Id: worker.GetScopeId(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
CreatedTime: worker.CreateTime.GetTimestamp(),
UpdatedTime: worker.UpdateTime.GetTimestamp(),
Version: worker.GetVersion(),
Name: wrapperspb.String(worker.GetName()),
Description: wrapperspb.String(worker.GetDescription()),
Address: wrapperspb.String(worker.GetAddress()),
wantPkiWorker := &pb.Worker{
Id: pkiWorker.GetPublicId(),
ScopeId: pkiWorker.GetScopeId(),
Scope: &scopes.ScopeInfo{Id: pkiWorker.GetScopeId(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
CreatedTime: pkiWorker.CreateTime.GetTimestamp(),
UpdatedTime: pkiWorker.UpdateTime.GetTimestamp(),
Version: pkiWorker.GetVersion(),
Name: wrapperspb.String(pkiWorker.GetName()),
Description: wrapperspb.String(pkiWorker.GetDescription()),
Address: pkiWorker.GetAddress(),
AuthorizedActions: testAuthorizedActions,
CanonicalAddress: worker.CanonicalAddress(),
LastStatusTime: worker.GetLastStatusTime().GetTimestamp(),
LastStatusTime: pkiWorker.GetLastStatusTime().GetTimestamp(),
CanonicalTags: map[string]*structpb.ListValue{
"key": structListValue(t, "val"),
"config": structListValue(t, "test"),
},
Tags: map[string]*structpb.ListValue{
"key": structListValue(t, "val"),
},
WorkerProvidedConfiguration: &pb.WorkerProvidedConfiguration{
Address: worker.GetWorkerReportedAddress(),
Name: worker.GetWorkerReportedName(),
Tags: map[string]*structpb.ListValue{
"config": structListValue(t, "test"),
},
ConfigTags: map[string]*structpb.ListValue{
"config": structListValue(t, "test"),
},
Type: PkiWorkerType,
}
cases := []struct {
@@ -118,10 +142,16 @@ func TestGet(t *testing.T) {
err error
}{
{
name: "Get an Existing Worker",
scopeId: worker.GetScopeId(),
req: &pbs.GetWorkerRequest{Id: worker.GetPublicId()},
res: &pbs.GetWorkerResponse{Item: wantWorker},
name: "Get an Existing KMS Worker",
scopeId: kmsWorker.GetScopeId(),
req: &pbs.GetWorkerRequest{Id: kmsWorker.GetPublicId()},
res: &pbs.GetWorkerResponse{Item: wantKmsWorker},
},
{
name: "Get an Existing PKI Worker",
scopeId: pkiWorker.GetScopeId(),
req: &pbs.GetWorkerRequest{Id: pkiWorker.GetPublicId()},
res: &pbs.GetWorkerResponse{Item: wantPkiWorker},
},
{
name: "Get a non-existent Worker",
@@ -172,10 +202,30 @@ func TestList(t *testing.T) {
return servers.NewRepository(rw, rw, kms)
}
var wantWorkers []*pb.Worker
var wantKmsWorkers []*pb.Worker
for i := 0; i < 10; i++ {
w := servers.TestWorker(t, conn, wrap, servers.WithName(fmt.Sprintf("worker%d", i)))
wantWorkers = append(wantWorkers, &pb.Worker{
w := servers.TestKmsWorker(t, conn, wrap, servers.WithName(fmt.Sprintf("kms-worker%d", i)))
kmsAuthzActions := make([]string, len(testAuthorizedActions))
copy(kmsAuthzActions, testAuthorizedActions)
wantKmsWorkers = append(wantKmsWorkers, &pb.Worker{
Id: w.GetPublicId(),
ScopeId: w.GetScopeId(),
Scope: &scopes.ScopeInfo{Id: w.GetScopeId(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
CreatedTime: w.CreateTime.GetTimestamp(),
UpdatedTime: w.UpdateTime.GetTimestamp(),
Version: w.GetVersion(),
Name: wrapperspb.String(w.GetName()),
AuthorizedActions: strutil.StrListDelete(kmsAuthzActions, action.Update.String()),
Address: w.GetAddress(),
Type: KmsWorkerType,
LastStatusTime: w.GetLastStatusTime().GetTimestamp(),
})
}
var wantPkiWorkers []*pb.Worker
for i := 0; i < 10; i++ {
w := servers.TestPkiWorker(t, conn, wrap, servers.WithName(fmt.Sprintf("pki-worker%d", i)))
wantPkiWorkers = append(wantPkiWorkers, &pb.Worker{
Id: w.GetPublicId(),
ScopeId: w.GetScopeId(),
Scope: &scopes.ScopeInfo{Id: w.GetScopeId(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"},
@@ -184,12 +234,9 @@ func TestList(t *testing.T) {
Version: w.GetVersion(),
Name: wrapperspb.String(w.GetName()),
AuthorizedActions: testAuthorizedActions,
CanonicalAddress: w.CanonicalAddress(),
Address: w.GetAddress(),
Type: PkiWorkerType,
LastStatusTime: w.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: &pb.WorkerProvidedConfiguration{
Address: w.GetWorkerReportedAddress(),
Name: w.GetWorkerReportedName(),
},
})
}
@@ -202,27 +249,27 @@ func TestList(t *testing.T) {
{
name: "List All Workers",
req: &pbs.ListWorkersRequest{ScopeId: scope.Global.String()},
res: &pbs.ListWorkersResponse{Items: wantWorkers},
res: &pbs.ListWorkersResponse{Items: append(wantKmsWorkers, wantPkiWorkers...)},
},
{
name: "List global workers recursively",
req: &pbs.ListWorkersRequest{ScopeId: "global", Recursive: true},
res: &pbs.ListWorkersResponse{
Items: wantWorkers,
Items: append(wantKmsWorkers, wantPkiWorkers...),
},
},
{
name: "Filter to a single workers",
req: &pbs.ListWorkersRequest{ScopeId: "global", Recursive: true, Filter: `"/item/name"=="worker2"`},
name: "Filter to a single worker of each type",
req: &pbs.ListWorkersRequest{ScopeId: "global", Recursive: true, Filter: `"/item/name"=="kms-worker2" or "/item/name"=="pki-worker2"`},
res: &pbs.ListWorkersResponse{
Items: wantWorkers[2:3],
Items: []*pb.Worker{wantKmsWorkers[2], wantPkiWorkers[2]},
},
},
{
name: "Filter to 2 workers",
req: &pbs.ListWorkersRequest{ScopeId: "global", Recursive: true, Filter: `"/item/name" matches "worker[23]"`},
name: "Filter to 2 workers of each type",
req: &pbs.ListWorkersRequest{ScopeId: "global", Recursive: true, Filter: `"/item/name" matches "kms-worker[23]" or "/item/name" matches "pki-worker[23]"`},
res: &pbs.ListWorkersResponse{
Items: wantWorkers[2:4],
Items: []*pb.Worker{wantKmsWorkers[2], wantKmsWorkers[3], wantPkiWorkers[2], wantPkiWorkers[3]},
},
},
{
@@ -253,6 +300,10 @@ func TestList(t *testing.T) {
sort.Slice(got.Items, func(i, j int) bool {
return got.Items[i].GetName().GetValue() < got.Items[j].GetName().GetValue()
})
require.NoError(gErr)
sort.Slice(tc.res.Items, func(i, j int) bool {
return tc.res.Items[i].GetName().GetValue() < tc.res.Items[j].GetName().GetValue()
})
assert.Empty(cmp.Diff(got, tc.res, protocmp.Transform()), "ListWorkers(%q) got response %q, wanted %q", tc.req.GetScopeId(), got, tc.res)
// Test the anon case
@@ -285,7 +336,7 @@ func TestDelete(t *testing.T) {
s, err := NewService(ctx, repoFn, iamRepoFn)
require.NoError(t, err, "Error when getting new worker service.")
w := servers.TestWorker(t, conn, wrap)
w := servers.TestKmsWorker(t, conn, wrap)
cases := []struct {
name string
@@ -349,16 +400,15 @@ func TestUpdate(t *testing.T) {
return repo, nil
}
wkr := servers.TestWorker(t, conn, wrapper,
wkr := servers.TestPkiWorker(t, conn, wrapper,
servers.WithName("default"),
servers.WithDescription("default"),
servers.WithAddress("default"))
servers.WithDescription("default"))
version := wkr.GetVersion()
resetWorker := func() {
version++
_, _, err = repo.UpdateWorker(context.Background(), wkr, version, []string{"Name", "Description", "Address"})
_, _, err = repo.UpdateWorker(context.Background(), wkr, version, []string{"Name", "Description"})
require.NoError(t, err, "Failed to reset worker.")
version++
}
@@ -370,10 +420,6 @@ func TestUpdate(t *testing.T) {
workerService, err := NewService(ctx, repoFn, iamRepoFn)
require.NoError(t, err)
expectedScope := &scopes.ScopeInfo{Id: scope.Global.String(), Type: scope.Global.String(), Name: scope.Global.String(), Description: "Global Scope"}
expectedConfig := &pb.WorkerProvidedConfiguration{
Address: wkr.GetWorkerReportedAddress(),
Name: wkr.GetWorkerReportedName(),
}
cases := []struct {
name string
@@ -385,27 +431,24 @@ func TestUpdate(t *testing.T) {
name: "Update an Existing Worker",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description", "address"},
Paths: []string{"name", "description"},
},
Item: &pb.Worker{
Name: wrapperspb.String("name"),
Description: wrapperspb.String("desc"),
Address: wrapperspb.String("address"),
},
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("name"),
Description: wrapperspb.String("desc"),
Address: wrapperspb.String("address"),
CanonicalAddress: "address",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("name"),
Description: wrapperspb.String("desc"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
@@ -422,20 +465,30 @@ func TestUpdate(t *testing.T) {
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("name"),
Description: wrapperspb.String("desc"),
Address: wrapperspb.String("default"),
CanonicalAddress: "default",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("name"),
Description: wrapperspb.String("desc"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
{
name: "cant update address",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"address"},
},
Item: &pb.Worker{
Address: "updated",
},
},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "No Update Mask",
req: &pbs.UpdateWorkerRequest{
@@ -457,14 +510,6 @@ func TestUpdate(t *testing.T) {
},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Update port to 0",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{Paths: []string{"default_port"}},
Item: &pb.Worker{},
},
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Only non-existant paths in Mask",
req: &pbs.UpdateWorkerRequest{
@@ -488,16 +533,14 @@ func TestUpdate(t *testing.T) {
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Description: wrapperspb.String("default"),
Address: wrapperspb.String("default"),
CanonicalAddress: "default",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Description: wrapperspb.String("default"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
@@ -513,16 +556,14 @@ func TestUpdate(t *testing.T) {
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("default"),
Address: wrapperspb.String("default"),
CanonicalAddress: "default",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("default"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
@@ -539,17 +580,15 @@ func TestUpdate(t *testing.T) {
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("updated"),
Description: wrapperspb.String("default"),
Address: wrapperspb.String("default"),
CanonicalAddress: "default",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("updated"),
Description: wrapperspb.String("default"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
@@ -566,17 +605,15 @@ func TestUpdate(t *testing.T) {
},
res: &pbs.UpdateWorkerResponse{
Item: &pb.Worker{
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("default"),
Description: wrapperspb.String("notignored"),
Address: wrapperspb.String("default"),
CanonicalAddress: "default",
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
WorkerProvidedConfiguration: expectedConfig,
AuthorizedActions: testAuthorizedActions,
Id: wkr.GetPublicId(),
ScopeId: wkr.GetScopeId(),
Scope: expectedScope,
Name: wrapperspb.String("default"),
Description: wrapperspb.String("notignored"),
CreatedTime: wkr.GetCreateTime().GetTimestamp(),
LastStatusTime: wkr.GetLastStatusTime().GetTimestamp(),
AuthorizedActions: testAuthorizedActions,
Type: PkiWorkerType,
},
},
},
@@ -593,38 +630,6 @@ func TestUpdate(t *testing.T) {
},
err: handlers.ApiErrorWithCode(codes.NotFound),
},
{
name: "Cant change Worker Defined Name",
req: &pbs.UpdateWorkerRequest{
Id: wkr.GetPublicId(),
UpdateMask: &field_mask.FieldMask{
Paths: []string{"worker_provided_configuration.name"},
},
Item: &pb.Worker{
WorkerProvidedConfiguration: &pb.WorkerProvidedConfiguration{
Name: "name",
},
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Cant change Worker Defined Address",
req: &pbs.UpdateWorkerRequest{
Id: wkr.GetPublicId(),
UpdateMask: &field_mask.FieldMask{
Paths: []string{"worker_provided_configuration.address"},
},
Item: &pb.Worker{
WorkerProvidedConfiguration: &pb.WorkerProvidedConfiguration{
Address: "address",
},
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Cant change Id",
req: &pbs.UpdateWorkerRequest{
@@ -672,7 +677,7 @@ func TestUpdate(t *testing.T) {
Paths: []string{"tags"},
},
Item: &pb.Worker{
Tags: map[string]*structpb.ListValue{
ConfigTags: map[string]*structpb.ListValue{
"foo": structListValue(t, "bar"),
},
},
@@ -696,13 +701,52 @@ func TestUpdate(t *testing.T) {
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Cant specify canonical address",
name: "Cant specify address",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"canonical_address"},
Paths: []string{globals.AddressField},
},
Item: &pb.Worker{
CanonicalAddress: "should_fail",
Address: "should_fail",
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Invalid name- uppercase",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description", "address"},
},
Item: &pb.Worker{
Name: wrapperspb.String("BADNAME"),
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Invalid name- non-printable",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description", "address"},
},
Item: &pb.Worker{
Name: wrapperspb.String("\x00"),
},
},
res: nil,
err: handlers.ApiErrorWithCode(codes.InvalidArgument),
},
{
name: "Invalid description- nonprintable",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name", "description", "address"},
},
Item: &pb.Worker{
Description: wrapperspb.String("\x00"),
},
},
res: nil,
@@ -743,6 +787,85 @@ func TestUpdate(t *testing.T) {
}
}
func TestUpdate_KMS(t *testing.T) {
t.Parallel()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kms := kms.TestKms(t, conn, wrapper)
ctx := context.Background()
rw := db.New(conn)
iamRepo := iam.TestRepo(t, conn, wrapper)
iamRepoFn := func() (*iam.Repository, error) {
return iamRepo, nil
}
repo, err := servers.NewRepository(rw, rw, kms)
require.NoError(t, err)
repoFn := func() (*servers.Repository, error) {
return repo, nil
}
wkr := servers.TestKmsWorker(t, conn, wrapper,
servers.WithName("default"),
servers.WithDescription("default"))
toMerge := &pbs.UpdateWorkerRequest{
Id: wkr.GetPublicId(),
}
workerService, err := NewService(ctx, repoFn, iamRepoFn)
require.NoError(t, err)
cases := []struct {
name string
req *pbs.UpdateWorkerRequest
res *pbs.UpdateWorkerResponse
err error
}{
{
name: "Cant set name",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"name"},
},
Item: &pb.Worker{
Name: wrapperspb.String("name"),
},
},
},
{
name: "Cant set description",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"description"},
},
Item: &pb.Worker{
Description: wrapperspb.String("description"),
},
},
},
{
name: "Cant set address",
req: &pbs.UpdateWorkerRequest{
UpdateMask: &field_mask.FieldMask{
Paths: []string{"address"},
},
Item: &pb.Worker{
Address: "address",
},
},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
req := proto.Clone(toMerge).(*pbs.UpdateWorkerRequest)
proto.Merge(req, tc.req)
got, gErr := workerService.UpdateWorker(auth.DisabledAuthTestContext(iamRepoFn, scope.Global.String()), req)
assert.Error(t, gErr)
assert.Nil(t, got)
})
}
}
func TestUpdate_BadVersion(t *testing.T) {
t.Parallel()
conn, _ := db.TestSetup(t, "postgres")
@@ -767,7 +890,7 @@ func TestUpdate_BadVersion(t *testing.T) {
workerService, err := NewService(ctx, repoFn, iamRepoFn)
require.NoError(t, err, "Failed to create a new host set service.")
wkr := servers.TestWorker(t, conn, wrapper)
wkr := servers.TestKmsWorker(t, conn, wrapper)
upTar, err := workerService.UpdateWorker(auth.DisabledAuthTestContext(iamRepoFn, proj.GetPublicId()), &pbs.UpdateWorkerRequest{
Id: wkr.GetPublicId(),
@@ -877,29 +1000,29 @@ func TestCreateWorkerLed(t *testing.T) {
wantErrContains: globals.IdField,
},
{
name: "invalid-canonical-address",
name: "invalid-address",
service: testSrv,
scopeId: scope.Global.String(),
req: &pbs.CreateWorkerLedRequest{
Item: &workers.Worker{
ScopeId: scope.Global.String(),
WorkerGeneratedAuthToken: &wrapperspb.StringValue{Value: fetchReqFn()},
CanonicalAddress: "invalid-canonical-address",
Address: "invalid-address",
},
},
wantErr: true,
wantErrIs: handlers.ApiErrorWithCode(codes.InvalidArgument),
wantErrContains: globals.CanonicalAddressField,
wantErrContains: globals.AddressField,
},
{
name: "invalid-tags",
name: "invalid-config-tags",
service: testSrv,
scopeId: scope.Global.String(),
req: &pbs.CreateWorkerLedRequest{
Item: &workers.Worker{
ScopeId: scope.Global.String(),
WorkerGeneratedAuthToken: &wrapperspb.StringValue{Value: fetchReqFn()},
Tags: map[string]*structpb.ListValue{
ConfigTags: map[string]*structpb.ListValue{
"invalid": {Values: []*structpb.Value{
structpb.NewStringValue("invalid-tags"),
}},
@@ -908,7 +1031,7 @@ func TestCreateWorkerLed(t *testing.T) {
},
wantErr: true,
wantErrIs: handlers.ApiErrorWithCode(codes.InvalidArgument),
wantErrContains: globals.TagsField,
wantErrContains: globals.ConfigTagsField,
},
{
name: "invalid-canonical-tags",
@@ -944,21 +1067,6 @@ func TestCreateWorkerLed(t *testing.T) {
wantErrIs: handlers.ApiErrorWithCode(codes.InvalidArgument),
wantErrContains: globals.LastStatusTimeField,
},
{
name: "invalid-worker-config",
service: testSrv,
scopeId: scope.Global.String(),
req: &pbs.CreateWorkerLedRequest{
Item: &workers.Worker{
ScopeId: scope.Global.String(),
WorkerGeneratedAuthToken: &wrapperspb.StringValue{Value: fetchReqFn()},
WorkerProvidedConfiguration: &pb.WorkerProvidedConfiguration{},
},
},
wantErr: true,
wantErrIs: handlers.ApiErrorWithCode(codes.InvalidArgument),
wantErrContains: globals.WorkerProvidedConfigurationField,
},
{
name: "invalid-authorized-actions",
service: testSrv,
@@ -1131,6 +1239,7 @@ func TestCreateWorkerLed(t *testing.T) {
Name: &wrapperspb.StringValue{Value: "success"},
Description: &wrapperspb.StringValue{Value: "success-description"},
Version: 1,
Type: PkiWorkerType,
},
},
},
+5 -4
View File
@@ -157,10 +157,11 @@ func (w *Worker) sendWorkerStatus(cancelCtx context.Context) {
result, err := client.Status(statusCtx, &pbs.StatusRequest{
Jobs: activeJobs,
WorkerStatus: &servers.ServerWorkerStatus{
Name: w.conf.RawConfig.Worker.Name,
Address: w.conf.RawConfig.Worker.PublicAddr,
Tags: tags,
KeyId: keyId,
Name: w.conf.RawConfig.Worker.Name,
Description: w.conf.RawConfig.Worker.Description,
Address: w.conf.RawConfig.Worker.PublicAddr,
Tags: tags,
KeyId: keyId,
},
UpdateTags: w.updateTags.Load(),
})
@@ -27,64 +27,73 @@ create trigger controller_update_time_column before update on server_controller
-- Worker table takes the place of the server table.
-- instead of the private_id we use a wt_public_id field named public_id since
-- workers will now be exposed as resources in boundary.
create table server_worker_type_enm (
name text primary key
constraint only_predefined_types_allowed
check (
name in (
'pki',
'kms'
)
)
);
comment on table server_worker_type_enm is
'server_worker_type_enm is an enumeration table for worker types. '
'It contains rows for representing the pki and kms types.';
insert into server_worker_type_enm (name)
values
('pki'),
('kms');
create table server_worker (
public_id wt_public_id primary key,
scope_id wt_scope_id not null
references iam_scope_global(scope_id)
on delete cascade
on update cascade,
description wt_description,
name wt_name unique,
-- The address can be null since it is an optional value from the API.
address wt_network_address,
description wt_description
constraint description_only_has_printable_characters
check (description is null or description !~ '[^[:print:]]'),
name wt_name -- server_worker_scope_id_name_uq defines an appropriate uniqueness constraint for name
constraint worker_name_must_be_set_by_status
check (
type != 'kms' or name is not null
)
constraint name_must_be_lowercase
check (name is null or lower(trim(name)) = name)
constraint name_only_has_printable_characters
check (name is null or name !~ '[^[:print:]]'),
address wt_network_address
constraint address_must_be_set_by_status
check (
-- address can be null only no status update has been received yet.
(last_status_time is not null and address is not null)
or
(last_status_time is null and address is null)
),
create_time wt_timestamp,
update_time wt_timestamp,
version wt_version,
last_status_time timestamp with time zone,
constraint last_status_time_not_before_create_time
check (last_status_time >= create_time),
-- This is the calculated address that the worker reports it is reachable on.
-- This must be set if the worker has ever received a status update.
worker_reported_address wt_network_address
constraint worker_reported_address_must_be_set_by_status
check (
(last_status_time is null and worker_reported_address is null)
or
(last_status_time is not null and worker_reported_address is not null)
),
-- This is the name that the worker reports in it's status updates.
worker_reported_name wt_name
constraint worker_reported_name_must_be_set_by_status
check (
(last_status_time is null and worker_reported_name is null)
or
(last_status_time is not null and worker_reported_name is not null)
or
(last_status_time is not null and worker_reported_key_id is not null)
)
constraint worker_reported_name_must_be_lowercase
check (lower(trim(worker_reported_name)) = worker_reported_name)
constraint worker_reported_name_only_has_printable_characters
check (worker_reported_name !~ '[^[:print:]]'),
worker_reported_key_id text
constraint worker_reported_key_id_must_be_set_by_status
check (
(last_status_time is null and worker_reported_key_id is null)
or
(last_status_time is not null and worker_reported_name is not null)
or
(last_status_time is not null and worker_reported_key_id is not null)
),
type text not null
constraint server_worker_type_enm_fkey
references server_worker_type_enm (name)
on delete restrict
on update cascade,
last_status_time timestamp with time zone
constraint last_status_time_not_before_create_time
check (last_status_time >= create_time)
constraint last_status_time_always_set_for_kms
check (type != 'kms' or last_status_time is not null),
constraint server_worker_scope_id_name_uq
unique(scope_id, name),
constraint server_worker_scope_id_worker_reported_name_uq
unique(scope_id, worker_reported_name)
unique(scope_id, name)
);
comment on table server_worker is
'server_worker is a table where each row represents a Boundary worker.';
create trigger immutable_columns before update on server_worker
for each row execute procedure immutable_columns('public_id', 'scope_id', 'create_time');
for each row execute procedure immutable_columns('public_id', 'scope_id', 'type', 'create_time');
create trigger default_create_time_column before insert on server_worker
for each row execute procedure default_create_time();
@@ -95,38 +104,78 @@ create trigger worker_insert_time_column before insert on server_worker
create trigger worker_update_time_column before update on server_worker
for each row execute procedure update_time_column();
create trigger update_version_column after update of version, description, name, address on server_worker
-- fixme: we should only update the version column when type = 'pki', but that
-- can be deferred
create trigger update_version_column after update of version, description, name on server_worker
for each row execute procedure update_version_column();
create function update_server_worker_update_last_status_time_column()
create function immutable_kms_name()
returns trigger
as $$
begin
new.last_status_time = now();
if old.type = 'kms' and new.name is distinct from old.name then
raise exception 'immutable column for kms worker: server_worker.name' using
errcode = '23601',
schema = tg_table_schema,
table = tg_table_name,
column = 'name';
end if;
return new;
end;
$$ language plpgsql;
comment on function update_server_worker_update_last_status_time_column is
'function used to update the last_status_time column in server_worker to now';
comment on function immutable_kms_name is
'function used in before update triggers to make name column immutable for kms workers';
create trigger update_server_worker_last_status_time_column before update of worker_reported_address, worker_reported_name on server_worker
for each row execute procedure update_server_worker_update_last_status_time_column();
create trigger immutable_kms_name before update on server_worker
for each row execute procedure immutable_kms_name();
create function insert_server_worker_update_last_status_time_column()
create function update_kms_server_worker_update_last_status_time_column()
returns trigger
as $$
begin
if new.worker_reported_address is not null or new.worker_reported_name is not null then
if new.type = 'kms' then
new.last_status_time = now();
end if;
return new;
end;
$$ language plpgsql;
comment on function insert_server_worker_update_last_status_time_column is
'function used to update the last_status_time column in server_worker to now';
comment on function update_kms_server_worker_update_last_status_time_column is
'function used to update the last_status_time column in server_worker with type kms to now';
create trigger update_kms_server_worker_last_status_time_column before update of address, name, description on server_worker
for each row execute procedure update_kms_server_worker_update_last_status_time_column();
create function update_pki_server_worker_update_last_status_time_column()
returns trigger
as $$
begin
if new.type = 'pki' then
new.last_status_time = now();
end if;
return new;
end;
$$ language plpgsql;
comment on function update_pki_server_worker_update_last_status_time_column is
'function used to update the last_status_time column in server_worker with type pki to now';
create trigger update_pki_server_worker_last_status_time_column before update of address on server_worker
for each row execute procedure update_pki_server_worker_update_last_status_time_column();
create function insert_kms_server_worker_update_last_status_time_column()
returns trigger
as $$
begin
if new.type = 'kms' then
new.last_status_time = now();
end if;
return new;
end;
$$ language plpgsql;
comment on function insert_kms_server_worker_update_last_status_time_column is
'function used to update the last_status_time column in server_worker with type kms to now';
create trigger insert_server_worker_last_update_time_column before insert on server_worker
for each row execute procedure insert_server_worker_update_last_status_time_column();
for each row execute procedure insert_kms_server_worker_update_last_status_time_column();
-- Create table worker tag
create table server_worker_tag_enm (
@@ -112,6 +112,8 @@ create table worker_auth_authorized(
on update cascade,
nonce bytea -- encrypted value
);
comment on table worker_auth_authorized is
'worker_auth_authorized is a table where each row represents key and cert data associated with an authorized worker.';
create trigger
immutable_columns
@@ -120,8 +122,22 @@ create trigger
for each row execute procedure immutable_columns('worker_key_identifier', 'worker_id', 'worker_signing_pub_key',
'worker_encryption_pub_key', 'controller_encryption_priv_key', 'key_id', 'nonce');
comment on table worker_auth_authorized is
'worker_auth_authorized is a table where each row represents key and cert data associated with an authorized worker.';
create function insert_worker_auth_authorized_type_check()
returns trigger
as $$
begin
perform from server_worker where type = 'pki' and public_id = new.worker_id;
if not found then
raise exception 'invalid type: non pki worker cannot be authorized in worker_auth_authorized table';
end if;
return new;
end;
$$ language plpgsql;
comment on function insert_worker_auth_authorized_type_check is
'function used to only allow workers of type pki to be authorized';
create trigger insert_worker_auth_authorized_type_check before insert on worker_auth_authorized
for each row execute procedure insert_worker_auth_authorized_type_check();
create table worker_auth_certificate_bundle(
root_certificate_public_key bytea not null
@@ -29,9 +29,8 @@ select
w.create_time,
w.update_time,
w.version,
w.worker_reported_name,
w.worker_reported_address,
w.last_status_time,
w.type,
cc.count as active_connection_count,
-- keys and tags can be any lowercase printable character so use uppercase characters as delimitors.
wt.tags as api_tags,
@@ -46,7 +45,6 @@ from server_worker w
comment on view server_worker_aggregate is
'server_worker_aggregate contains the worker resource with its worker provided config values and its configuration and api provided tags.';
-- Replaces the view created in 9/01.
-- Remove the worker id from this view. In actuality this is almost a no-op
-- because no server information was ever getting populated here due to a bug
+20 -51
View File
@@ -5524,11 +5524,11 @@
},
"name": {
"type": "string",
"description": "Optional name for identification purposes."
"description": "Optional name for identification purposes. Can only be set through the API\nfor `pki`-type workers; read-only for `kms`-type workers."
},
"description": {
"type": "string",
"description": "Optional user-set description for identification purposes."
"description": "Optional user-set description for identification purposes. Can only be set\nthrough the API for `pki`-type workers; read-only for `kms`-type workers."
},
"created_time": {
"type": "string",
@@ -5549,22 +5549,7 @@
},
"address": {
"type": "string",
"description": "The address that this worker is reachable at."
},
"canonical_address": {
"type": "string",
"description": "Output only. This is the address used by authorized session. The value\nis the same as the address field if set. Otherwise it uses the address the\nworker reports.",
"readOnly": true
},
"tags": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object"
}
},
"description": "Output only. The tags attached to this worker.",
"description": "Output only. The address that this worker is reachable at, as sourced from\nthe worker's configuration file.",
"readOnly": true
},
"canonical_tags": {
@@ -5575,7 +5560,18 @@
"type": "object"
}
},
"description": "Output only. The deduplicated union of the tags reported by the worker and\nthe tags added through the user facing api. This is used when applying\nworker filters.",
"description": "Output only. The deduplicated union of the tags reported by the worker from\nits configuration and any tags added through other means. This is used\nwhen applying worker filters.",
"readOnly": true
},
"config_tags": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object"
}
},
"description": "Output only. The tags set in the worker's configuration file.",
"readOnly": true
},
"last_status_time": {
@@ -5584,11 +5580,6 @@
"description": "Output only. The time this worker daemon last reported its status.",
"readOnly": true
},
"worker_provided_configuration": {
"$ref": "#/definitions/controller.api.resources.workers.v1.WorkerProvidedConfiguration",
"description": "Output only. The set of information the worker daemon has reported about\nitself.",
"readOnly": true
},
"worker_generated_auth_token": {
"type": "string",
"title": "worker_generated_auth_token is input only. Supports the worker led node\nenrollment flow where this credentials token is produced by a worker. This\ntoken is a base58 encoded types.FetchNodeCredentialsRequest from\nhttps://github.com/hashicorp/nodeenrollment"
@@ -5599,6 +5590,11 @@
"description": "Output only. The number of connections that this worker is currently handling.",
"readOnly": true
},
"type": {
"type": "string",
"description": "Output only. The type of the worker, denoted by how it authenticates: `pki`\nor `kms`.",
"readOnly": true
},
"authorized_actions": {
"type": "array",
"items": {
@@ -5610,33 +5606,6 @@
},
"title": "Worker contains all fields related to a Worker resource"
},
"controller.api.resources.workers.v1.WorkerProvidedConfiguration": {
"type": "object",
"properties": {
"address": {
"type": "string",
"description": "Output only. The address the worker daemon reports itself as reachable at.",
"readOnly": true
},
"name": {
"type": "string",
"description": "Output only. The name the worker daemon reports itself having.",
"readOnly": true
},
"tags": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "object"
}
},
"description": "Output only. The tags reporteed by the worker daemon.",
"readOnly": true
}
},
"description": "WorkerProvidedConfiguration contains configuration values reported by the worker daemon."
},
"controller.api.services.v1.AddGroupMembersResponse": {
"type": "object",
"properties": {
@@ -10,18 +10,6 @@ import "google/protobuf/wrappers.proto";
option go_package = "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/workers;workers";
// WorkerProvidedConfiguration contains configuration values reported by the worker daemon.
message WorkerProvidedConfiguration {
// Output only. The address the worker daemon reports itself as reachable at.
string address = 10;
// Output only. The name the worker daemon reports itself having.
string name = 20;
// Output only. The tags reporteed by the worker daemon.
map<string, google.protobuf.ListValue> tags = 40;
}
// Worker contains all fields related to a Worker resource
message Worker {
// Output only. The ID of the User.
@@ -33,7 +21,8 @@ message Worker {
// Output only. Scope information for this resource.
resources.scopes.v1.ScopeInfo scope = 30;
// Optional name for identification purposes.
// Optional name for identification purposes. Can only be set through the API
// for `pki`-type workers; read-only for `kms`-type workers.
google.protobuf.StringValue name = 40 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
@@ -42,7 +31,8 @@ message Worker {
}
]; // @gotags: `class:"sensitive"`
// Optional user-set description for identification purposes.
// Optional user-set description for identification purposes. Can only be set
// through the API for `pki`-type workers; read-only for `kms`-type workers.
google.protobuf.StringValue description = 50 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
@@ -61,34 +51,20 @@ message Worker {
// The mutation will fail if the version does not match the latest known good version.
uint32 version = 80; // @gotags: `class:"public"`
// The address that this worker is reachable at.
google.protobuf.StringValue address = 90 [
(custom_options.v1.generate_sdk_option) = true,
(custom_options.v1.mask_mapping) = {
this: "address"
that: "address"
}
]; // @gotags: `class:"public"`
// Output only. The address that this worker is reachable at, as sourced from
// the worker's configuration file.
string address = 90; // @gotags: `class:"public"`
// Output only. This is the address used by authorized session. The value
// is the same as the address field if set. Otherwise it uses the address the
// worker reports.
string canonical_address = 100 [json_name = "canonical_address"]; // @gotags: `class:"public"`
// Output only. The tags attached to this worker.
map<string, google.protobuf.ListValue> tags = 110; // @gotags: `class:"public"`
// Output only. The deduplicated union of the tags reported by the worker and
// the tags added through the user facing api. This is used when applying
// worker filters.
// Output only. The deduplicated union of the tags reported by the worker from
// its configuration and any tags added through other means. This is used
// when applying worker filters.
map<string, google.protobuf.ListValue> canonical_tags = 120 [json_name = "canonical_tags"]; // @gotags: `class:"public"`
// Output only. The time this worker daemon last reported its status.
google.protobuf.Timestamp last_status_time = 130 [json_name = "last_status_time"]; // @gotags: `class:"public"`
// Output only. The tags set in the worker's configuration file.
map<string, google.protobuf.ListValue> config_tags = 130 [json_name = "config_tags"]; // @gotags: `class:"public"`
// Output only. The set of information the worker daemon has reported about
// itself.
WorkerProvidedConfiguration worker_provided_configuration = 140 [json_name = "worker_provided_configuration"];
// Output only. The time this worker daemon last reported its status.
google.protobuf.Timestamp last_status_time = 140 [json_name = "last_status_time"]; // @gotags: `class:"public"`
// worker_generated_auth_token is input only. Supports the worker led node
// enrollment flow where this credentials token is produced by a worker. This
@@ -99,6 +75,10 @@ message Worker {
// Output only. The number of connections that this worker is currently handling.
google.protobuf.UInt32Value active_connection_count = 160 [json_name = "active_connection_count"]; // @gotags: `class:"public"`
// Output only. The type of the worker, denoted by how it authenticates: `pki`
// or `kms`.
string type = 170;
// Output only. The available actions on this resource for the requester.
repeated string authorized_actions = 300 [json_name = "authorized_actions"]; // @gotags: `class:"public"`
}
@@ -18,6 +18,9 @@ message ServerWorkerStatus {
// Name of the resource (optional)
string name = 20; // @gotags: `class:"public"`
// Description of the resource (optional)
string description = 25; // @gotags: `class:"public"`
// Address for the worker. This must be set.
string address = 30; // @gotags: `class:"public"`
@@ -29,10 +29,7 @@ message Worker {
// Address for the worker. This is optional.
// @inject_tag: `gorm:"default:null"`
string address = 40 [(custom_options.v1.mask_mapping) = {
this: "address"
that: "address"
}];
string address = 40;
// The create_time is set by the database.
// @inject_tag: `gorm:"default:current_timestamp"`
@@ -50,22 +47,13 @@ message Worker {
// @inject_tag: `gorm:"default:null"`
uint32 version = 80;
// Name of the resource (optional)
// @inject_tag: `gorm:"default:null"`
string worker_reported_name = 90;
// Address for the worker. This must be set when the worker has received
// at least 1 status update fromt he worker daemon.
// @inject_tag: `gorm:"default:null"`
string worker_reported_address = 100;
// The last_status_time is the last time a worker daemon sent a status update.
// @inject_tag: `gorm:"default:null"`
timestamp.v1.Timestamp last_status_time = 110;
// keyId reported by a PKI worker (optional)
// @inject_tag: `gorm:"default:null"`
string worker_reported_key_id = 120;
// The type of the worker, denoted by how it authenticates: pki or kms.
// @inject_tag: `gorm:"not_null"`
string type = 130;
}
// WorkerTag is a tag for a worker. The primary key is comprised of the
+12
View File
@@ -36,6 +36,8 @@ type options struct {
withNonce []byte
withNewIdFunc func(context.Context) (string, error)
withFetchNodeCredentialsRequest *types.FetchNodeCredentialsRequest
withTestPkiWorkerAuthorized bool
withTestPkiWorkerKeyId *string
}
func getDefaultOptions() options {
@@ -151,3 +153,13 @@ func WithFetchNodeCredentialsRequest(req *types.FetchNodeCredentialsRequest) Opt
o.withFetchNodeCredentialsRequest = req
}
}
// WithTestPkiWorkerAuthorizedKeyId should only be used in tests.
// It specifies that the test worker should be authorized when returned and
// assigns the key id for that worker to the string pointer in this option.
func WithTestPkiWorkerAuthorizedKeyId(id *string) Option {
return func(o *options) {
o.withTestPkiWorkerAuthorized = true
o.withTestPkiWorkerKeyId = id
}
}
+13
View File
@@ -145,4 +145,17 @@ func Test_GetOpts(t *testing.T) {
runtime.FuncForPC(reflect.ValueOf(testOpts.withNewIdFunc).Pointer()).Name(),
)
})
t.Run("WithTestPkiWorkerAuthorizedKeyId", func(t *testing.T) {
assert := assert.New(t)
testOpts := getDefaultOptions()
var keyId string
opts := getOpts(WithTestPkiWorkerAuthorizedKeyId(&keyId))
testOpts = getDefaultOptions()
testOpts.withTestPkiWorkerAuthorized = true
testOpts.withTestPkiWorkerKeyId = &keyId
testOpts.withNewIdFunc = nil
opts.withNewIdFunc = nil
assert.Equal(opts, testOpts)
})
}
+12
View File
@@ -19,3 +19,15 @@ func newWorkerId(ctx context.Context) (string, error) {
}
return id, nil
}
// newWorkerIdFromScopeAndName generates a predictable public id based on the
// scope and the worker name. This should only be used on kms workers at
// upsert time.
func newWorkerIdFromScopeAndName(ctx context.Context, scope, name string) (string, error) {
const op = "servers.newWorkerIdFromScopeAndName"
id, err := db.NewPublicId(WorkerPrefix, db.WithPrngValues([]string{scope, name}))
if err != nil {
return "", errors.Wrap(ctx, err, "servers.newWorkerId")
}
return id, nil
}
+102 -64
View File
@@ -57,19 +57,32 @@ func (r *Repository) DeleteWorker(ctx context.Context, publicId string, _ ...Opt
return rowsDeleted, nil
}
// LookupWorkerByWorkerReportedName returns the worker which has had a status update
// where the worker has reported this name. This is different from the name
// on the resource itself which is set over the API. In the event that no
// worker is found that matches then nil, nil will be returned.
func (r *Repository) LookupWorkerByWorkerReportedName(ctx context.Context, name string) (*Worker, error) {
const op = "servers.(Repository).LookupWorkerByWorkerReportedName"
// LookupWorkerByName returns the worker with the provided name. In the event
// that no worker is found that matches then nil, nil will be returned.
func (r *Repository) LookupWorkerByName(ctx context.Context, name string) (*Worker, error) {
const op = "servers.(Repository).LookupWorkerByName"
switch {
case name == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "name is empty")
}
w, err := lookupWorkerByName(ctx, r.reader, name)
if err != nil {
return nil, errors.Wrap(ctx, err, op)
}
return w, nil
}
func lookupWorkerByName(ctx context.Context, reader db.Reader, name string) (*Worker, error) {
const op = "servers.lookupWorkerByName"
switch {
case isNil(reader):
return nil, errors.New(ctx, errors.InvalidParameter, op, "reader is nil")
case name == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "name is empty")
}
wAgg := &workerAggregate{}
err := r.reader.LookupWhere(ctx, &wAgg, "worker_reported_name = ?", []interface{}{name})
err := reader.LookupWhere(ctx, &wAgg, "name = ?", []interface{}{name})
if err != nil {
if errors.IsNotFoundError(err) {
return nil, nil
@@ -83,8 +96,8 @@ func (r *Repository) LookupWorkerByWorkerReportedName(ctx context.Context, name
return w, nil
}
func (r *Repository) LookupWorkerIdByWorkerReportedKeyId(ctx context.Context, keyId string) (string, error) {
const op = "servers.(Repository).LookupWorkerIdByWorkerReportedKeyId"
func (r *Repository) LookupWorkerIdByKeyId(ctx context.Context, keyId string) (string, error) {
const op = "servers.(Repository).LookupWorkerIdByKeyId"
switch {
case keyId == "":
return "", errors.New(ctx, errors.InvalidParameter, op, "keyId is empty")
@@ -200,62 +213,51 @@ func (r *Repository) ListWorkers(ctx context.Context, scopeIds []string, opt ...
return workers, nil
}
// UpsertWorkerStatus creates a new worker if one with the provided public id
// doesn't already exist. If it does, UpsertWorkerStatus updates the worker
// status. This returns the Worker object with the updated WorkerStatus applied.
// The WithPublicId and WithUpdateTags options are the only ones used. All others are ignored.
// UpsertWorkerStatus will update the address and last status time for a worker.
// If the worker is a kms worker that hasn't been seen yet, it'll attempt to
// create a new one, but will return an error if another worker (kms or other)
// has the same name. This returns the Worker object with the changes applied.
// The WithPublicId, WithKeyId, and WithUpdateTags options are
// the only ones used. All others are ignored.
// Workers are intentionally not oplogged.
func (r *Repository) UpsertWorkerStatus(ctx context.Context, worker *Worker, opt ...Option) (*Worker, error) {
const op = "servers.UpsertWorkerStatus"
opts := getOpts(opt...)
switch {
case worker == nil:
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker is nil")
case worker.GetWorkerReportedAddress() == "":
case worker.GetAddress() == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker reported address is empty")
case worker.ScopeId == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "scope id is empty")
case worker.PublicId != "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker id is not empty")
case worker.GetWorkerReportedName() == "" && worker.WorkerReportedKeyId == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker keyId and reported name are both empty; at least one is required")
case len(worker.apiTags) > 0:
return nil, errors.New(ctx, errors.InvalidParameter, op, "api tags is not empty")
case worker.GetName() == "" && opts.withKeyId == "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker keyId and reported name are both empty; one is required")
case worker.GetName() != "" && opts.withKeyId != "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker keyId and reported name are both set; no more than one is allowed")
}
// Only retain the worker reported fields.
worker = NewWorkerForStatus(worker.GetScopeId(),
WithName(worker.GetWorkerReportedName()),
WithAddress(worker.GetWorkerReportedAddress()),
WithWorkerTags(worker.configTags...),
WithKeyId(worker.WorkerReportedKeyId))
opts := getOpts(opt...)
var workerId string
var err error
switch {
case opts.withPublicId != "":
worker.PublicId = opts.withPublicId
case worker.WorkerReportedKeyId != "":
workerId, err := r.LookupWorkerIdByWorkerReportedKeyId(ctx, worker.WorkerReportedKeyId)
workerId = opts.withPublicId
case opts.withKeyId != "":
workerId, err = r.LookupWorkerIdByKeyId(ctx, opts.withKeyId)
if err != nil || workerId == "" {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error finding worker by keyId"))
}
worker.PublicId = workerId
default:
// Attempt to find workerId by name. If not found, generate an id
w, err := r.LookupWorkerByWorkerReportedName(ctx, worker.GetWorkerReportedName())
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error finding worker by name"))
}
if w != nil {
worker.PublicId = w.PublicId
} else {
workerId, err := newWorkerId(ctx)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error error generating worker id"))
}
worker.PublicId = workerId
// generating the worker id based off of the scope and name ensures
// that if 2 kms workers are making requests with the same name they
// are treated as the same worker. Allowing this only for kms workers
// also ensures that we maintain the unique name constraint between pki
// workers and kms workers.
workerId, err = newWorkerIdFromScopeAndName(ctx, worker.GetScopeId(), worker.GetName())
if err != nil || workerId == "" {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("error creating a worker id"))
}
}
@@ -266,13 +268,52 @@ func (r *Repository) UpsertWorkerStatus(ctx context.Context, worker *Worker, opt
db.ExpBackoff{},
func(reader db.Reader, w db.Writer) error {
worker := worker.clone()
workerCreateConflict := &db.OnConflict{
Target: db.Columns{"public_id"},
Action: append(db.SetColumns([]string{"worker_reported_name", "worker_reported_address"}),
db.SetColumnValues(map[string]interface{}{"last_status_time": "now()"})...),
}
if err := w.Create(ctx, worker, db.WithOnConflict(workerCreateConflict)); err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("error creating a worker"))
worker.PublicId = workerId
switch {
case opts.withKeyId != "":
// This case goes first in case we want to relax the restriction
// around both name and key ID being supplied to account for
// e.g. config processing bugs. In that case, a key ID being
// supplied should be a clear indicator that we are working with
// a PKI worker, and a lack of one a clear indication we are
// working with a KMS worker.
//
// Note: unlike in the below case, this purposefully leaves out
// "description" since we want description changes for PKI-based
// workers to come via API only. We can't really guard on this
// in the DB so we need to be sure to not include it here.
n, err := w.Update(ctx, worker, []string{"address"}, nil)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update status of pki worker"))
}
switch n {
case 0:
return errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("failed to find worker with key id %q", opts.withKeyId))
case 1:
break
default:
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("multiple records found when updating worker with id %q", worker.GetPublicId()))
}
case worker.GetName() != "":
worker.Type = KmsWorkerType.String()
workerCreateConflict := &db.OnConflict{
Target: db.Columns{"public_id"},
Action: append(db.SetColumns([]string{"description", "address"}),
db.SetColumnValues(map[string]interface{}{"last_status_time": "now()"})...),
}
var withRowsAffected int64
err := w.Create(ctx, worker, db.WithOnConflict(workerCreateConflict), db.WithReturnRowsAffected(&withRowsAffected),
// The intent of this WithWhere option is to operate with the OnConflict such that the action
// taken by the OnConflict only applies if the conflict is on a row that is returned by this where
// statement, otherwise it should error out.
db.WithWhere("server_worker.type = 'kms'"))
switch {
case err != nil:
return errors.Wrap(ctx, err, op, errors.WithMsg("error creating a worker"))
case withRowsAffected == 0:
return errors.New(ctx, errors.NotUnique, op, "error updating worker")
}
}
// If we've been told to update tags, we need to clean out old
@@ -280,7 +321,9 @@ func (r *Repository) UpsertWorkerStatus(ctx context.Context, worker *Worker, opt
// delete all tags for the given worker, then add the new ones
// we've been sent.
if opts.withUpdateTags {
setWorkerTags(ctx, w, worker.GetPublicId(), ConfigurationTagSource, worker.configTags)
if err := setWorkerTags(ctx, w, worker.GetPublicId(), ConfigurationTagSource, worker.inputTags); err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("error setting worker tags"))
}
}
wAgg := &workerAggregate{PublicId: worker.GetPublicId()}
@@ -355,9 +398,8 @@ func setWorkerTags(ctx context.Context, w db.Writer, id string, ts TagSource, ta
// the path then an error is returned.
func (r *Repository) UpdateWorker(ctx context.Context, worker *Worker, version uint32, fieldMaskPaths []string, opt ...Option) (*Worker, int, error) {
const (
nameField = "name"
descField = "description"
addressField = "address"
nameField = "name"
descField = "description"
)
const op = "servers.(Repository).UpdateWorker"
switch {
@@ -373,7 +415,6 @@ func (r *Repository) UpdateWorker(ctx context.Context, worker *Worker, version u
switch {
case strings.EqualFold(nameField, f):
case strings.EqualFold(descField, f):
case strings.EqualFold(addressField, f):
default:
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, fmt.Sprintf("invalid field mask: %s", f))
}
@@ -382,9 +423,8 @@ func (r *Repository) UpdateWorker(ctx context.Context, worker *Worker, version u
var dbMask, nullFields []string
dbMask, nullFields = dbcommon.BuildUpdatePaths(
map[string]interface{}{
nameField: worker.Name,
descField: worker.Description,
addressField: worker.Address,
nameField: worker.Name,
descField: worker.Description,
},
fieldMaskPaths,
nil,
@@ -448,10 +488,8 @@ func (r *Repository) CreateWorker(ctx context.Context, worker *Worker, opt ...Op
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
case worker.ScopeId != scope.Global.String():
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("scope id must be %q", scope.Global.String()))
case worker.WorkerReportedAddress != "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker reported address is not empty")
case worker.WorkerReportedName != "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "worker reported name is not empty")
case worker.Address != "":
return nil, errors.New(ctx, errors.InvalidParameter, op, "address is not empty")
case worker.LastStatusTime != nil:
return nil, errors.New(ctx, errors.InvalidParameter, op, "last status time is not nil")
}
@@ -476,7 +514,6 @@ func (r *Repository) CreateWorker(ctx context.Context, worker *Worker, opt ...Op
if err != nil {
return nil, errors.Wrap(ctx, err, op)
}
}
var returnedWorker *Worker
@@ -486,6 +523,7 @@ func (r *Repository) CreateWorker(ctx context.Context, worker *Worker, opt ...Op
db.ExpBackoff{},
func(read db.Reader, w db.Writer) error {
returnedWorker = worker.clone()
returnedWorker.Type = PkiWorkerType.String()
if err := w.Create(
ctx,
returnedWorker,
+211 -207
View File
@@ -2,7 +2,6 @@ package servers_test
import (
"context"
"crypto/rand"
"fmt"
"strings"
"testing"
@@ -21,8 +20,6 @@ import (
"github.com/hashicorp/boundary/internal/types/scope"
"github.com/hashicorp/go-dbw"
"github.com/hashicorp/go-kms-wrapping/extras/kms/v2/migrations"
"github.com/hashicorp/nodeenrollment"
"github.com/hashicorp/nodeenrollment/registration"
"github.com/hashicorp/nodeenrollment/rotation"
"github.com/hashicorp/nodeenrollment/storage/file"
"github.com/hashicorp/nodeenrollment/types"
@@ -54,7 +51,7 @@ func TestDeleteWorker(t *testing.T) {
{
name: "valid",
args: args{
worker: servers.TestWorker(t, conn, wrapper),
worker: servers.TestKmsWorker(t, conn, wrapper),
},
wantRowsDeleted: 1,
wantErr: false,
@@ -108,7 +105,7 @@ func TestDeleteWorker(t *testing.T) {
}
}
func TestLookupWorkerByWorkerReportedName(t *testing.T) {
func TestLookupWorkerByName(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -117,14 +114,14 @@ func TestLookupWorkerByWorkerReportedName(t *testing.T) {
require.NoError(t, err)
ctx := context.Background()
w := servers.TestWorker(t, conn, wrapper)
w := servers.TestKmsWorker(t, conn, wrapper)
t.Run("success", func(t *testing.T) {
got, err := repo.LookupWorkerByWorkerReportedName(ctx, w.GetWorkerReportedName())
got, err := repo.LookupWorkerByName(ctx, w.GetName())
require.NoError(t, err)
assert.Empty(t, cmp.Diff(w.Worker, got.Worker, protocmp.Transform()))
})
t.Run("not found", func(t *testing.T) {
got, err := repo.LookupWorkerByWorkerReportedName(ctx, "unknown_name")
got, err := repo.LookupWorkerByName(ctx, "unknown_name")
require.NoError(t, err)
assert.Nil(t, got)
})
@@ -134,14 +131,14 @@ func TestLookupWorkerByWorkerReportedName(t *testing.T) {
mock.ExpectQuery(`SELECT`).WillReturnError(errors.New(context.Background(), errors.Internal, "test", "lookup-error"))
r, err := servers.NewRepository(rw, rw, kms)
require.NoError(t, err)
got, err := r.LookupWorkerByWorkerReportedName(ctx, w.GetWorkerReportedName())
got, err := r.LookupWorkerByName(ctx, w.GetName())
assert.NoError(t, mock.ExpectationsWereMet())
assert.Truef(t, errors.Match(errors.T(errors.Op("servers.(Repository).LookupWorkerByWorkerReportedName")), err), "got error %v", err)
assert.Truef(t, errors.Match(errors.T(errors.Op("servers.(Repository).LookupWorkerByName")), err), "got error %v", err)
assert.Nil(t, got)
})
}
func TestLookupWorkerByWorkerReportedKeyId(t *testing.T) {
func TestLookupWorkerIdByKeyId(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -149,39 +146,15 @@ func TestLookupWorkerByWorkerReportedKeyId(t *testing.T) {
repo, err := servers.NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
ctx := context.Background()
// Ensures the global scope contains a valid root key
err = kmsCache.CreateKeys(context.Background(), scope.Global.String(), kms.WithRandomReader(rand.Reader))
require.NoError(t, err)
w := servers.TestWorker(t, conn, wrapper)
rootStorage, err := servers.NewRepositoryStorage(ctx, rw, rw, kmsCache)
require.NoError(t, err)
_, err = rotation.RotateRootCertificates(ctx, rootStorage)
require.NoError(t, err)
// Create struct to pass in with workerId that will be passed along to storage
state, err := servers.AttachWorkerIdToState(ctx, w.PublicId)
require.NoError(t, err)
// This happens on the worker
fileStorage, err := file.New(ctx)
require.NoError(t, err)
nodeCreds, err := types.NewNodeCredentials(ctx, fileStorage)
require.NoError(t, err)
// Create request using worker id
fetchReq, err := nodeCreds.CreateFetchNodeCredentialsRequest(ctx)
require.NoError(t, err)
// The AuthorizeNode request will result in a WorkerAuth record being stored
registeredNode, err := registration.AuthorizeNode(ctx, rootStorage, fetchReq, nodeenrollment.WithState(state))
require.NoError(t, err)
var workerKeyId string
w := servers.TestPkiWorker(t, conn, wrapper, servers.WithTestPkiWorkerAuthorizedKeyId(&workerKeyId))
t.Run("success", func(t *testing.T) {
got, err := repo.LookupWorkerIdByWorkerReportedKeyId(ctx, registeredNode.Id)
got, err := repo.LookupWorkerIdByKeyId(ctx, workerKeyId)
require.NoError(t, err)
assert.Equal(t, w.PublicId, got)
})
t.Run("not found", func(t *testing.T) {
got, err := repo.LookupWorkerIdByWorkerReportedKeyId(ctx, "unknown_key")
got, err := repo.LookupWorkerIdByKeyId(ctx, "unknown_key")
require.NoError(t, err)
assert.Empty(t, got)
})
@@ -191,9 +164,9 @@ func TestLookupWorkerByWorkerReportedKeyId(t *testing.T) {
mock.ExpectQuery(`SELECT`).WillReturnError(errors.New(context.Background(), errors.Internal, "test", "lookup-error"))
r, err := servers.NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
got, err := r.LookupWorkerIdByWorkerReportedKeyId(ctx, w.GetWorkerReportedName())
got, err := r.LookupWorkerIdByKeyId(ctx, "somekey")
assert.NoError(t, mock.ExpectationsWereMet())
assert.Truef(t, errors.Match(errors.T(errors.Op("servers.(Repository).LookupWorkerIdByWorkerReportedKeyId")), err), "got error %v", err)
assert.Truef(t, errors.Match(errors.T(errors.Op("servers.(Repository).LookupWorkerIdByKeyId")), err), "got error %v", err)
assert.Empty(t, got)
})
}
@@ -207,21 +180,11 @@ func TestLookupWorker(t *testing.T) {
require.NoError(t, err)
ctx := context.Background()
w := servers.TestWorker(t, conn, wrapper,
w := servers.TestKmsWorker(t, conn, wrapper,
servers.WithName("name"),
servers.WithDescription("description"),
servers.WithAddress("address"),
servers.WithWorkerTags(&servers.Tag{"key", "val"}))
w, err = repo.UpsertWorkerStatus(context.Background(),
servers.NewWorkerForStatus(w.GetScopeId(),
servers.WithName(w.GetWorkerReportedName()),
servers.WithAddress(w.GetWorkerReportedAddress()),
servers.WithWorkerTags(&servers.Tag{
Key: "config",
Value: "test",
})),
servers.WithUpdateTags(true),
servers.WithPublicId(w.GetPublicId()))
require.NoError(t, err)
sessRepo, err := session.NewRepository(rw, rw, kms)
@@ -261,12 +224,10 @@ func TestLookupWorker(t *testing.T) {
require.NoError(t, err)
assert.Empty(t, cmp.Diff(w, got, protocmp.Transform()))
assert.Equal(t, uint32(3), got.ActiveConnectionCount())
assert.Equal(t, map[string][]string{"key": {"val"}}, got.GetApiTags())
assert.Equal(t, map[string][]string{"config": {"test"}}, got.GetConfigTags())
assert.Equal(t, map[string][]string{
"key": {"val"},
"config": {"test"},
"key": {"val"},
}, got.CanonicalTags())
assert.Equal(t, got.CanonicalTags(), got.GetConfigTags())
})
t.Run("not found", func(t *testing.T) {
got, err := repo.LookupWorker(ctx, "w_unknownid")
@@ -290,35 +251,83 @@ func TestUpsertWorkerStatus(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
kms := kms.TestKms(t, conn, wrapper)
repo, err := servers.NewRepository(rw, rw, kms)
kmsCache := kms.TestKms(t, conn, wrapper)
repo, err := servers.NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
ctx := context.Background()
wStatus1 := servers.NewWorkerForStatus(scope.Global.String(),
servers.WithAddress("address"), servers.WithName("config_name1"))
worker, err := repo.UpsertWorkerStatus(ctx, wStatus1)
require.NoError(t, err)
{
t.Run("create an initial kms worker and update status", func(t *testing.T) {
wStatus1 := servers.NewWorker(scope.Global.String(),
servers.WithAddress("address"), servers.WithName("config_name1"),
servers.WithDescription("kms_description1"))
worker, err := repo.UpsertWorkerStatus(ctx, wStatus1)
require.NoError(t, err)
assert.True(t, strings.HasPrefix(worker.GetPublicId(), "w_"))
assert.Equal(t, wStatus1.GetWorkerReportedAddress(), worker.CanonicalAddress())
assert.Empty(t, worker.Name)
assert.Equal(t, worker.GetLastStatusTime(), worker.UpdateTime)
assert.Equal(t, wStatus1.GetAddress(), worker.GetAddress())
assert.Equal(t, "config_name1", worker.Name)
assert.Equal(t, "kms_description1", worker.Description)
assert.Equal(t, worker.GetLastStatusTime().AsTime(), worker.GetUpdateTime().AsTime())
assert.Equal(t, uint32(1), worker.Version)
assert.Empty(t, worker.Address)
assert.Empty(t, worker.Description)
}
assert.Equal(t, "address", worker.GetAddress())
// update again and see updated last status time
wStatus2 := servers.NewWorker(scope.Global.String(),
servers.WithAddress("new_address"), servers.WithName("config_name1"),
servers.WithDescription("kms_description2"))
worker, err = repo.UpsertWorkerStatus(ctx, wStatus2)
require.NoError(t, err)
assert.Greater(t, worker.GetLastStatusTime().AsTime(), worker.GetCreateTime().AsTime())
assert.Equal(t, "config_name1", worker.Name)
assert.Equal(t, "kms_description2", worker.Description)
assert.Equal(t, worker.GetLastStatusTime().AsTime(), worker.GetUpdateTime().AsTime())
assert.Equal(t, uint32(2), worker.Version)
assert.Equal(t, "new_address", worker.GetAddress())
})
// Setup and use a pki worker
var pkiWorkerKeyId string
pkiWorker := servers.TestPkiWorker(t, conn, wrapper, servers.WithName("pki"), servers.WithDescription("pki_description1"), servers.WithTestPkiWorkerAuthorizedKeyId(&pkiWorkerKeyId))
t.Run("update status for pki worker", func(t *testing.T) {
wStatus1 := servers.NewWorker(scope.Global.String(),
servers.WithAddress("pki_address"), servers.WithDescription("pki_description2"))
worker, err := repo.UpsertWorkerStatus(ctx, wStatus1, servers.WithKeyId(pkiWorkerKeyId))
require.NoError(t, err)
assert.True(t, strings.HasPrefix(worker.GetPublicId(), "w_"))
assert.Equal(t, wStatus1.GetAddress(), worker.GetAddress())
assert.Equal(t, "pki", worker.Name)
assert.Equal(t, "pki_description1", worker.Description) // PKI workers don't update description via status
assert.Greater(t, worker.GetLastStatusTime().AsTime(), worker.GetCreateTime().AsTime())
assert.Equal(t, worker.GetLastStatusTime().AsTime(), worker.GetUpdateTime().AsTime())
assert.Equal(t, uint32(1), worker.Version)
assert.Equal(t, "pki_address", worker.GetAddress())
})
failureCases := []struct {
name string
repo *servers.Repository
status *servers.Worker
options []servers.Option
errAssert func(*testing.T, error)
}{
{
name: "conflicting name with pki",
repo: repo,
status: servers.NewWorker(scope.Global.String(),
servers.WithName(pkiWorker.GetName()),
servers.WithAddress("someaddress")),
errAssert: func(t *testing.T, err error) {
t.Helper()
assert.True(t, errors.Match(errors.T(errors.NotUnique), err), err)
},
},
{
name: "no address",
repo: repo,
status: servers.NewWorkerForStatus(scope.Global.String(),
status: servers.NewWorker(scope.Global.String(),
servers.WithName("worker_with_no_address")),
errAssert: func(t *testing.T, err error) {
t.Helper()
@@ -326,10 +335,10 @@ func TestUpsertWorkerStatus(t *testing.T) {
},
},
{
name: "cant specifying public id",
name: "cant specify public id",
repo: repo,
status: func() *servers.Worker {
w := servers.NewWorkerForStatus(scope.Global.String(),
w := servers.NewWorker(scope.Global.String(),
servers.WithName("worker_with_no_address"),
servers.WithAddress("workeraddress"))
w.PublicId = "w_specified"
@@ -341,9 +350,21 @@ func TestUpsertWorkerStatus(t *testing.T) {
},
},
{
name: "no name",
name: "name and key id provided",
repo: repo,
status: servers.NewWorkerForStatus(scope.Global.String(),
status: servers.NewWorker(scope.Global.String(),
servers.WithName("name and key id provided"),
servers.WithAddress("someaddress")),
options: []servers.Option{servers.WithKeyId(pkiWorkerKeyId)},
errAssert: func(t *testing.T, err error) {
t.Helper()
assert.True(t, errors.Match(errors.T(errors.InvalidParameter), err), err)
},
},
{
name: "no name or key id",
repo: repo,
status: servers.NewWorker(scope.Global.String(),
servers.WithAddress("no_name_address")),
errAssert: func(t *testing.T, err error) {
t.Helper()
@@ -362,7 +383,7 @@ func TestUpsertWorkerStatus(t *testing.T) {
{
name: "empty scope",
repo: repo,
status: servers.NewWorkerForStatus("",
status: servers.NewWorker("",
servers.WithAddress("address"),
servers.WithName("config_name1")),
errAssert: func(t *testing.T, err error) {
@@ -370,21 +391,6 @@ func TestUpsertWorkerStatus(t *testing.T) {
assert.True(t, errors.Match(errors.T(errors.InvalidParameter), err))
},
},
{
name: "providing api tags",
repo: repo,
status: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String(),
servers.WithWorkerTags(&servers.Tag{Key: "test", Value: "test"}))
w.WorkerReportedAddress = "some_address"
w.WorkerReportedName = "providing api tags"
return w
}(),
errAssert: func(t *testing.T, err error) {
t.Helper()
assert.True(t, errors.Match(errors.T(errors.InvalidParameter), err))
},
},
{
name: "database failure",
repo: func() *servers.Repository {
@@ -393,11 +399,11 @@ func TestUpsertWorkerStatus(t *testing.T) {
mock.ExpectBegin()
mock.ExpectQuery(`INSERT`).WillReturnError(errors.New(context.Background(), errors.Internal, "test", "create-error"))
mock.ExpectRollback()
r, err := servers.NewRepository(rw, rw, kms)
r, err := servers.NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
return r
}(),
status: servers.NewWorkerForStatus(scope.Global.String(),
status: servers.NewWorker(scope.Global.String(),
servers.WithName("database failure"),
servers.WithAddress("address")),
errAssert: func(t *testing.T, err error) {
@@ -408,29 +414,28 @@ func TestUpsertWorkerStatus(t *testing.T) {
}
for _, tc := range failureCases {
t.Run(fmt.Sprintf("Failures %s", tc.name), func(t *testing.T) {
_, err = tc.repo.UpsertWorkerStatus(ctx, tc.status)
_, err = tc.repo.UpsertWorkerStatus(ctx, tc.status, tc.options...)
assert.Error(t, err)
tc.errAssert(t, err)
// Still only the original worker exists.
workers, err := repo.ListWorkers(ctx, []string{scope.Global.String()})
require.NoError(t, err)
assert.Len(t, workers, 1)
assert.Len(t, workers, 2)
})
}
{
anotherStatus := servers.NewWorkerForStatus(scope.Global.String(),
t.Run("add another status", func(t *testing.T) {
anotherStatus := servers.NewWorker(scope.Global.String(),
servers.WithName("another_test_worker"),
servers.WithAddress("address"))
_, err = repo.UpsertWorkerStatus(ctx, anotherStatus)
require.NoError(t, err)
{
workers, err := repo.ListWorkers(ctx, []string{scope.Global.String()})
require.NoError(t, err)
assert.Len(t, workers, 2)
}
}
workers, err := repo.ListWorkers(ctx, []string{scope.Global.String()})
require.NoError(t, err)
assert.Len(t, workers, 3)
})
}
func TestTagUpdatingListing(t *testing.T) {
@@ -443,10 +448,10 @@ func TestTagUpdatingListing(t *testing.T) {
require.NoError(err)
ctx := context.Background()
worker1 := servers.TestWorker(t, conn, wrapper)
wStatus := servers.NewWorkerForStatus(scope.Global.String(),
servers.WithName(worker1.GetWorkerReportedName()),
servers.WithAddress("127.0.0.1"),
worker1 := servers.TestKmsWorker(t, conn, wrapper)
wStatus := servers.NewWorker(scope.Global.String(),
servers.WithName(worker1.GetName()),
servers.WithAddress("somethingnew"),
servers.WithWorkerTags(
&servers.Tag{
Key: "tag1",
@@ -464,9 +469,9 @@ func TestTagUpdatingListing(t *testing.T) {
assert.ElementsMatch(t, []string{"value1", "value2"}, worker1.CanonicalTags()["tag1"])
// Update without saying to update tags
wStatus = servers.NewWorkerForStatus(scope.Global.String(),
servers.WithName(worker1.GetWorkerReportedName()),
servers.WithAddress(worker1.GetWorkerReportedAddress()),
wStatus = servers.NewWorker(scope.Global.String(),
servers.WithName(worker1.GetName()),
servers.WithAddress(worker1.GetAddress()),
servers.WithWorkerTags(
&servers.Tag{
Key: "tag22",
@@ -542,7 +547,7 @@ func TestListWorkers(t *testing.T) {
w := servers.NewWorker(scope.Global.String())
db.TestDeleteWhere(t, conn, w, "true")
for i := 0; i < tt.createCnt; i++ {
servers.TestWorker(t, conn, wrapper)
servers.TestKmsWorker(t, conn, wrapper)
}
// the purpose of these tests isn't to check liveness, so disable
// liveness checking.
@@ -569,18 +574,20 @@ func TestListWorkers_WithLiveness(t *testing.T) {
require.NoError(err)
ctx := context.Background()
worker1 := servers.TestWorker(t, conn, wrapper)
worker2 := servers.TestWorker(t, conn, wrapper)
worker3 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
worker2 := servers.TestKmsWorker(t, conn, wrapper)
worker3 := servers.TestKmsWorker(t, conn, wrapper)
// 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.
_, err = serversRepo.UpsertWorkerStatus(ctx, servers.NewWorkerForStatus(scope.Global.String(),
servers.WithName(worker1.GetWorkerReportedName()),
servers.WithAddress(worker1.GetWorkerReportedAddress())))
_, err = serversRepo.UpsertWorkerStatus(ctx,
servers.NewWorker(scope.Global.String(),
servers.WithName(worker1.GetName()),
servers.WithAddress(worker1.GetAddress())),
servers.WithPublicId(worker1.GetPublicId()))
require.NoError(err)
requireIds := func(expected []string, actual []*servers.Worker) {
@@ -605,9 +612,11 @@ func TestListWorkers_WithLiveness(t *testing.T) {
requireIds([]string{worker1.GetPublicId()}, result)
// Upsert second server.
_, err = serversRepo.UpsertWorkerStatus(ctx, servers.NewWorkerForStatus(scope.Global.String(),
servers.WithName(worker2.GetWorkerReportedName()),
servers.WithAddress(worker1.GetWorkerReportedAddress())))
_, err = serversRepo.UpsertWorkerStatus(ctx,
servers.NewWorker(scope.Global.String(),
servers.WithName(worker2.GetName()),
servers.WithAddress(worker2.GetAddress())),
servers.WithPublicId(worker2.GetPublicId()))
require.NoError(err)
// Static liveness. Should get two, so long as this did not take
@@ -641,6 +650,8 @@ func TestRepository_CreateWorker(t *testing.T) {
return "", errors.New(testCtx, errors.Internal, "test", "testNewIdFn-error")
}
kmsWorker := servers.TestKmsWorker(t, conn, wrapper)
rootStorage, err := servers.NewRepositoryStorage(testCtx, rw, rw, testKms)
require.NoError(t, err)
_, err = rotation.RotateRootCertificates(testCtx, rootStorage)
@@ -739,25 +750,13 @@ func TestRepository_CreateWorker(t *testing.T) {
name: "no worker reported address",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.WorkerReportedAddress = "foo"
w.Address = "foo"
return w
},
repo: testRepo,
wantErr: true,
wantErrIs: errors.InvalidParameter,
wantErrContains: "worker reported address is not empty",
},
{
name: "no worker reported name",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.WorkerReportedName = "foo"
return w
},
repo: testRepo,
wantErr: true,
wantErrIs: errors.InvalidParameter,
wantErrContains: "worker reported name is not empty",
wantErrContains: "address is not empty",
},
{
name: "no last status update",
@@ -815,10 +814,46 @@ func TestRepository_CreateWorker(t *testing.T) {
wantErr: true,
wantErrContains: "unable to authorize node",
},
{
name: "unique name violation with kms worker",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.Name = kmsWorker.GetName()
return w
},
reader: rw,
repo: testRepo,
wantErr: true,
wantErrIs: errors.NotUnique,
},
{
name: "success",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.Name = "success"
return w
},
reader: rw,
repo: testRepo,
},
// This case must follow the one above it.
{
name: "unique name violation with pki worker",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.Name = "success"
return w
},
reader: rw,
repo: testRepo,
wantErr: true,
wantErrIs: errors.NotUnique,
},
{
name: "success-with-fetch-node-req",
setup: func() *servers.Worker {
w := servers.NewWorker(scope.Global.String())
w.Name = "success-with-fetch-node-req"
return w
},
reader: rw,
@@ -893,28 +928,13 @@ func TestRepository_UpdateWorker(t *testing.T) {
repo, err := servers.NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
setCases := []struct {
pkiCases := []struct {
name string
modifyWorker func(*testing.T, *servers.Worker)
path []string
assertGot func(*testing.T, *servers.Worker)
wantErr bool
}{
{
name: "update address",
modifyWorker: func(t *testing.T, w *servers.Worker) {
t.Helper()
w.Address = "foo"
},
path: []string{"address"},
assertGot: func(t *testing.T, w *servers.Worker) {
t.Helper()
assert.Equal(t, "foo", w.GetAddress())
assert.Equal(t, uint32(2), w.GetVersion())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
{
name: "update name",
modifyWorker: func(t *testing.T, w *servers.Worker) {
@@ -926,7 +946,7 @@ func TestRepository_UpdateWorker(t *testing.T) {
t.Helper()
assert.Equal(t, "foo", w.GetName())
assert.Equal(t, uint32(2), w.GetVersion())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Nil(t, w.GetLastStatusTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
@@ -941,39 +961,18 @@ func TestRepository_UpdateWorker(t *testing.T) {
t.Helper()
assert.Equal(t, "foo", w.GetDescription())
assert.Equal(t, uint32(2), w.GetVersion())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Nil(t, w.GetLastStatusTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
{
name: "update worker reported name",
modifyWorker: func(t *testing.T, w *servers.Worker) {
t.Helper()
w.WorkerReportedName = "foo"
},
path: []string{"WorkerReportedName"},
wantErr: true,
},
{
name: "update worker reported name and name",
modifyWorker: func(t *testing.T, w *servers.Worker) {
t.Helper()
w.WorkerReportedName = "foo"
w.Name = "another"
},
path: []string{"WorkerReportedName", "Name"},
wantErr: true,
},
{
name: "Clear worker reported name",
modifyWorker: func(t *testing.T, w *servers.Worker) {},
path: []string{"WorkerReportedName"},
wantErr: true,
},
}
for _, tt := range setCases {
for _, tt := range pkiCases {
t.Run(tt.name, func(t *testing.T) {
wkr := servers.TestWorker(t, conn, wrapper)
wkr := servers.TestPkiWorker(t, conn, wrapper)
defer func() {
_, err := repo.DeleteWorker(ctx, wkr.GetPublicId())
require.NoError(t, err)
}()
tt.modifyWorker(t, wkr)
got, _, err := repo.UpdateWorker(ctx, wkr, 1, tt.path)
if tt.wantErr {
@@ -994,20 +993,6 @@ func TestRepository_UpdateWorker(t *testing.T) {
assertGot func(*testing.T, *servers.Worker)
wantErr bool
}{
{
name: "clear address",
modifyWorker: func(t *testing.T, w *servers.Worker) {
t.Helper()
w.Address = ""
},
path: []string{"address"},
assertGot: func(t *testing.T, w *servers.Worker) {
t.Helper()
assert.Empty(t, w.GetAddress())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
{
name: "clear name",
modifyWorker: func(t *testing.T, w *servers.Worker) {
@@ -1018,7 +1003,7 @@ func TestRepository_UpdateWorker(t *testing.T) {
assertGot: func(t *testing.T, w *servers.Worker) {
t.Helper()
assert.Empty(t, w.GetName())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Nil(t, w.GetLastStatusTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
@@ -1032,18 +1017,17 @@ func TestRepository_UpdateWorker(t *testing.T) {
assertGot: func(t *testing.T, w *servers.Worker) {
t.Helper()
assert.Empty(t, w.GetDescription())
assert.Equal(t, w.GetLastStatusTime().AsTime(), w.GetCreateTime().AsTime())
assert.Nil(t, w.GetLastStatusTime())
assert.Greater(t, w.GetUpdateTime().AsTime(), w.GetCreateTime().AsTime())
},
},
}
for _, tt := range clearCases {
t.Run(tt.name, func(t *testing.T) {
wkr := servers.TestWorker(t, conn, wrapper)
wkr := servers.TestPkiWorker(t, conn, wrapper)
wkr.Name = tt.name
wkr.Description = tt.name
wkr.Address = tt.name
wkr, _, err := repo.UpdateWorker(ctx, wkr, 1, []string{"name", "description", "address"})
wkr, _, err := repo.UpdateWorker(ctx, wkr, 1, []string{"name", "description"})
require.NoError(t, err)
tt.modifyWorker(t, wkr)
@@ -1059,9 +1043,9 @@ func TestRepository_UpdateWorker(t *testing.T) {
}
t.Run("version is wrong", func(t *testing.T) {
wkr := servers.TestWorker(t, conn, wrapper)
wkr.Address = "version is wrong"
result, numUpdated, err := repo.UpdateWorker(ctx, wkr, 2, []string{"address"})
wkr := servers.TestPkiWorker(t, conn, wrapper)
wkr.Name = "version is wrong"
result, numUpdated, err := repo.UpdateWorker(ctx, wkr, 2, []string{"name"})
require.NoError(t, err)
assert.Zero(t, numUpdated)
assert.Equal(t, wkr.GetUpdateTime().AsTime(), result.GetUpdateTime().AsTime())
@@ -1082,21 +1066,41 @@ func TestRepository_UpdateWorker(t *testing.T) {
},
{
name: "empty path",
input: servers.TestWorker(t, conn, wrapper),
input: servers.TestPkiWorker(t, conn, wrapper),
version: 1,
wantErr: errors.T(errors.EmptyFieldMask),
},
{
name: "0 version",
input: servers.TestWorker(t, conn, wrapper),
input: servers.TestPkiWorker(t, conn, wrapper),
path: []string{"name"},
version: 0,
wantErr: errors.T(errors.InvalidParameter),
},
{
name: "changing kms name",
input: func() *servers.Worker {
w := servers.TestKmsWorker(t, conn, wrapper)
w.Name = "some change"
return w
}(), path: []string{"name"},
version: 1,
wantErr: errors.T(errors.NotSpecificIntegrity),
},
{
name: "clearing kms name",
input: func() *servers.Worker {
w := servers.TestKmsWorker(t, conn, wrapper)
w.Name = ""
return w
}(), path: []string{"name"},
version: 1,
wantErr: errors.T(errors.NotSpecificIntegrity),
},
{
name: "no public id",
input: func() *servers.Worker {
w := servers.TestWorker(t, conn, wrapper)
w := servers.TestPkiWorker(t, conn, wrapper)
w.PublicId = ""
return w
}(),
@@ -1106,7 +1110,7 @@ func TestRepository_UpdateWorker(t *testing.T) {
},
{
name: "unrecognized path",
input: servers.TestWorker(t, conn, wrapper),
input: servers.TestPkiWorker(t, conn, wrapper),
path: []string{"UnrecognizedField"},
version: 1,
wantErr: errors.T(errors.InvalidFieldMask),
@@ -1114,7 +1118,7 @@ func TestRepository_UpdateWorker(t *testing.T) {
{
name: "not found worker",
input: func() *servers.Worker {
w := servers.TestWorker(t, conn, wrapper)
w := servers.TestPkiWorker(t, conn, wrapper)
w.PublicId = "w_notfoundworker"
return w
}(),
@@ -1125,11 +1129,11 @@ func TestRepository_UpdateWorker(t *testing.T) {
{
name: "duplicate name",
input: func() *servers.Worker {
w1 := servers.TestWorker(t, conn, wrapper)
w1 := servers.TestPkiWorker(t, conn, wrapper)
w1.Name = "somenamethatijustmadeup"
w1, _, err := repo.UpdateWorker(ctx, w1, w1.Version, []string{"name"}, nil)
require.NoError(t, err)
w2 := servers.TestWorker(t, conn, wrapper)
w2 := servers.TestPkiWorker(t, conn, wrapper)
w2.Name = w1.Name
return w2
}(),
@@ -146,7 +146,7 @@ func TestStoreWorkerAuth(t *testing.T) {
require.NoError(err)
require.NotNil(wrapper)
worker := TestWorker(t, conn, wrapper)
worker := TestPkiWorker(t, conn, wrapper)
rw := db.New(conn)
rootStorage, err := NewRepositoryStorage(ctx, rw, rw, kmsCache)
@@ -266,7 +266,7 @@ func TestStoreNodeInformationTx(t *testing.T) {
// Create struct to pass in with workerId that will be passed along to
// storage
testWorker := TestWorker(t, conn, testWrapper)
testWorker := TestPkiWorker(t, conn, testWrapper)
testState, err := AttachWorkerIdToState(testCtx, testWorker.PublicId)
require.NoError(t, err)
+23 -12
View File
@@ -86,6 +86,8 @@ type ServerWorkerStatus struct {
PublicId string `protobuf:"bytes,10,opt,name=public_id,json=publicId,proto3" json:"public_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Name of the resource (optional)
Name string `protobuf:"bytes,20,opt,name=name,proto3" json:"name,omitempty" class:"public"` // @gotags: `class:"public"`
// Description of the resource (optional)
Description string `protobuf:"bytes,25,opt,name=description,proto3" json:"description,omitempty" class:"public"` // @gotags: `class:"public"`
// Address for the worker. This must be set.
Address string `protobuf:"bytes,30,opt,name=address,proto3" json:"address,omitempty" class:"public"` // @gotags: `class:"public"`
// Tags for workers
@@ -140,6 +142,13 @@ func (x *ServerWorkerStatus) GetName() string {
return ""
}
func (x *ServerWorkerStatus) GetDescription() string {
if x != nil {
return x.Description
}
return ""
}
func (x *ServerWorkerStatus) GetAddress() string {
if x != nil {
return x.Address
@@ -171,21 +180,23 @@ var file_controller_servers_v1_servers_proto_rawDesc = []byte{
0x54, 0x61, 0x67, 0x50, 0x61, 0x69, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,
0xaa, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0xcc, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x28, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x65, 0x72,
0x76, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x50, 0x61, 0x69, 0x72, 0x52,
0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18,
0x32, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x42, 0x38, 0x5a, 0x36,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69,
0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x3b, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72,
0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x28, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x67, 0x50, 0x61, 0x69,
0x72, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69,
0x64, 0x18, 0x32, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x42, 0x38,
0x5a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73,
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,
0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
+39 -70
View File
@@ -52,19 +52,12 @@ type Worker struct {
// version allows optimistic locking of the resource.
// @inject_tag: `gorm:"default:null"`
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"`
// Name of the resource (optional)
// @inject_tag: `gorm:"default:null"`
WorkerReportedName string `protobuf:"bytes,90,opt,name=worker_reported_name,json=workerReportedName,proto3" json:"worker_reported_name,omitempty" gorm:"default:null"`
// Address for the worker. This must be set when the worker has received
// at least 1 status update fromt he worker daemon.
// @inject_tag: `gorm:"default:null"`
WorkerReportedAddress string `protobuf:"bytes,100,opt,name=worker_reported_address,json=workerReportedAddress,proto3" json:"worker_reported_address,omitempty" gorm:"default:null"`
// The last_status_time is the last time a worker daemon sent a status update.
// @inject_tag: `gorm:"default:null"`
LastStatusTime *timestamp.Timestamp `protobuf:"bytes,110,opt,name=last_status_time,json=lastStatusTime,proto3" json:"last_status_time,omitempty" gorm:"default:null"`
// keyId reported by a PKI worker (optional)
// @inject_tag: `gorm:"default:null"`
WorkerReportedKeyId string `protobuf:"bytes,120,opt,name=worker_reported_key_id,json=workerReportedKeyId,proto3" json:"worker_reported_key_id,omitempty" gorm:"default:null"`
// The type of the worker, denoted by how it authenticates: pki or kms.
// @inject_tag: `gorm:"not_null"`
Type string `protobuf:"bytes,130,opt,name=type,proto3" json:"type,omitempty" gorm:"not_null"`
}
func (x *Worker) Reset() {
@@ -155,20 +148,6 @@ func (x *Worker) GetVersion() uint32 {
return 0
}
func (x *Worker) GetWorkerReportedName() string {
if x != nil {
return x.WorkerReportedName
}
return ""
}
func (x *Worker) GetWorkerReportedAddress() string {
if x != nil {
return x.WorkerReportedAddress
}
return ""
}
func (x *Worker) GetLastStatusTime() *timestamp.Timestamp {
if x != nil {
return x.LastStatusTime
@@ -176,9 +155,9 @@ func (x *Worker) GetLastStatusTime() *timestamp.Timestamp {
return nil
}
func (x *Worker) GetWorkerReportedKeyId() string {
func (x *Worker) GetType() string {
if x != nil {
return x.WorkerReportedKeyId
return x.Type
}
return ""
}
@@ -278,7 +257,7 @@ var file_controller_storage_servers_store_v1_worker_proto_rawDesc = []byte{
0x6f, 0x74, 0x6f, 0x1a, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f,
0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
0x70, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x83, 0x05, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe1, 0x03, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12,
0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd, 0x29, 0x0c,
@@ -287,49 +266,39 @@ var file_controller_storage_servers_store_v1_worker_proto_rawDesc = []byte{
0x6e, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x28, 0x20, 0x01, 0x28, 0x09, 0x42, 0x16, 0xc2, 0xdd, 0x29, 0x12, 0x0a, 0x07, 0x61, 0x64, 0x64,
0x72, 0x65, 0x73, 0x73, 0x12, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65,
0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69,
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54,
0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69,
0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69,
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65,
0x12, 0x19, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x46, 0x20, 0x01,
0x28, 0x09, 0x52, 0x07, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f,
0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x5a, 0x20,
0x01, 0x28, 0x09, 0x52, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x77, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12,
0x54, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x16, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f,
0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18,
0x78, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x70,
0x6f, 0x72, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x68, 0x0a, 0x09, 0x57, 0x6f,
0x72, 0x6b, 0x65, 0x72, 0x54, 0x61, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x14, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75,
0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f,
0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4b,
0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x32, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72,
0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75,
0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74,
0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e,
0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70,
0x65, 0x5f, 0x69, 0x64, 0x18, 0x46, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x63, 0x6f, 0x70,
0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x54, 0x0a,
0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54,
0x69, 0x6d, 0x65, 0x12, 0x13, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x82, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x68, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b,
0x65, 0x72, 0x54, 0x61, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f,
0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52,
0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x1e, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x73, 0x65, 0x72,
0x76, 0x65, 0x72, 0x73, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
+94 -24
View File
@@ -2,18 +2,25 @@ package servers
import (
"context"
"math/rand"
"crypto/rand"
mathRand "math/rand"
"strings"
"testing"
"time"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/timestamp"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/servers/store"
"github.com/hashicorp/boundary/internal/types/scope"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/nodeenrollment"
"github.com/hashicorp/nodeenrollment/registration"
"github.com/hashicorp/nodeenrollment/rotation"
"github.com/hashicorp/nodeenrollment/storage/file"
"github.com/hashicorp/nodeenrollment/types"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -51,15 +58,16 @@ func TestRootCertificate(ctx context.Context, t *testing.T, conn *db.DB, kmsKey
privateKey: populateBytes(defaultLength),
}
cert, err := newRootCertificate(ctx, rand.Uint64(), populateBytes(defaultLength), beforeTimestamp, afterTimestamp,
cert, err := newRootCertificate(ctx, mathRand.Uint64(), populateBytes(defaultLength), beforeTimestamp, afterTimestamp,
rootCertKeys, kmsKey, CurrentState)
err = rw.Create(ctx, cert)
require.NoError(t, err)
return cert
}
func TestWorkerAuth(ctx context.Context, t *testing.T, conn *db.DB, worker *Worker, kmsKey string) *WorkerAuth {
func TestWorkerAuth(t *testing.T, conn *db.DB, worker *Worker, kmsKey string) *WorkerAuth {
t.Helper()
ctx := context.Background()
rw := db.New(conn)
wSignPubKey := populateBytes(defaultLength)
wEncPubKey := populateBytes(defaultLength)
@@ -81,30 +89,34 @@ func TestWorkerAuth(ctx context.Context, t *testing.T, conn *db.DB, worker *Work
return workerAuth
}
// TestWorker inserts a worker into the db to satisfy foreign key constraints.
// The worker provided fields are auto generated. WithName, WithDescription,
// and WithAddress are applied to the resource name, description and address if
// present.
func TestWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Option) *Worker {
// TestKmsWorker inserts a worker into the db to satisfy foreign key constraints.
// The worker provided fields are auto generated. if WithName is not present a
// random name will be generated and assigned to the worker.
func TestKmsWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Option) *Worker {
t.Helper()
rw := db.New(conn)
kms := kms.TestKms(t, conn, wrapper)
serversRepo, err := NewRepository(rw, rw, kms)
require.NoError(t, err)
ctx := context.Background()
opts := getOpts(opt...)
namePart, err := newWorkerId(ctx)
require.NoError(t, err)
name := "test-worker-" + strings.ToLower(namePart)
id, err := newWorkerId(ctx)
require.NoError(t, err)
wrk := NewWorkerForStatus(scope.Global.String(),
if opts.withName != "" {
name = opts.withName
}
address := "127.0.0.1"
if opts.withAddress != "" {
address = opts.withAddress
}
wrk := NewWorker(scope.Global.String(),
WithName(name),
WithAddress("127.0.0.1"))
wrk, err = serversRepo.UpsertWorkerStatus(ctx, wrk, WithPublicId(id))
WithAddress(address))
wrk, err = serversRepo.UpsertWorkerStatus(ctx, wrk)
require.NoError(t, err)
require.NotNil(t, wrk)
opts := getOpts(opt...)
if len(opts.withWorkerTags) > 0 {
var tags []interface{}
@@ -113,24 +125,16 @@ func TestWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Opti
WorkerId: wrk.GetPublicId(),
Key: t.Key,
Value: t.Value,
Source: "api",
Source: "configuration",
})
}
require.NoError(t, rw.CreateItems(ctx, tags))
}
var mask []string
if opts.withName != "" {
wrk.Name = opts.withName
mask = append(mask, "name")
}
if opts.withDescription != "" {
wrk.Description = opts.withDescription
mask = append(mask, "description")
}
if opts.withAddress != "" {
wrk.Address = opts.withAddress
mask = append(mask, "address")
}
if len(mask) > 0 {
var n int
wrk, n, err = serversRepo.UpdateWorker(ctx, wrk, wrk.Version, mask)
@@ -138,6 +142,72 @@ func TestWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Opti
require.Equal(t, 1, n)
require.NotNil(t, wrk)
}
wrk, err = serversRepo.LookupWorker(ctx, wrk.GetPublicId())
require.NoError(t, err)
return wrk
}
// TestPkiWorker inserts a worker into the db to satisfy foreign key constraints.
// The worker provided fields are auto generated. WithName and WithDescription,
// are applied to the resource name, description if present. WithTestPkiWorkerAuthorizedKeyId
// can be used to make the PkiWorker authorized in which case the string pointer
// passed to WithTestPkiWorkerAuthorizedKeyId is set to the key id.
func TestPkiWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Option) *Worker {
t.Helper()
rw := db.New(conn)
kmsCache := kms.TestKms(t, conn, wrapper)
serversRepo, err := NewRepository(rw, rw, kmsCache)
require.NoError(t, err)
ctx := context.Background()
opts := getOpts(opt...)
require.NoError(t, err)
wrk := NewWorker(scope.Global.String(),
opt...)
wrk, err = serversRepo.CreateWorker(ctx, wrk, opt...)
require.NoError(t, err)
require.NotNil(t, wrk)
if len(opts.withWorkerTags) > 0 {
var tags []interface{}
for _, t := range opts.withWorkerTags {
tags = append(tags, &store.WorkerTag{
WorkerId: wrk.GetPublicId(),
Key: t.Key,
Value: t.Value,
Source: "configuration",
})
}
require.NoError(t, rw.CreateItems(ctx, tags))
}
if opts.withTestPkiWorkerAuthorized {
err = kmsCache.CreateKeys(context.Background(), scope.Global.String(), kms.WithRandomReader(rand.Reader))
// We always try to create root global scope keys, but if it already exists, just continue...
require.True(t, err == nil || errors.IsUniqueError(err), err)
rootStorage, err := NewRepositoryStorage(ctx, rw, rw, kmsCache)
require.NoError(t, err)
_, err = rotation.RotateRootCertificates(ctx, rootStorage)
require.NoError(t, err)
// Create struct to pass in with workerId that will be passed along to storage
state, err := AttachWorkerIdToState(ctx, wrk.PublicId)
require.NoError(t, err)
// This happens on the worker
fileStorage, err := file.New(ctx)
require.NoError(t, err)
nodeCreds, err := types.NewNodeCredentials(ctx, fileStorage)
require.NoError(t, err)
// Create request using worker id
fetchReq, err := nodeCreds.CreateFetchNodeCredentialsRequest(ctx)
require.NoError(t, err)
registeredNode, err := registration.AuthorizeNode(ctx, rootStorage, fetchReq, nodeenrollment.WithState(state))
require.NoError(t, err)
if opts.withTestPkiWorkerKeyId != nil {
*opts.withTestPkiWorkerKeyId = registeredNode.Id
}
}
wrk, err = serversRepo.LookupWorker(ctx, wrk.GetPublicId())
require.NoError(t, err)
return wrk
}
+31 -2
View File
@@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
)
func TestTestWorker(t *testing.T) {
func TestTestKmsWorker(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
const (
@@ -19,7 +19,7 @@ func TestTestWorker(t *testing.T) {
description = "test description"
address = "test address"
)
tWorker := TestWorker(t, conn, wrapper, WithName(name), WithDescription(description), WithAddress(address))
tWorker := TestKmsWorker(t, conn, wrapper, WithName(name), WithDescription(description), WithAddress(address))
assert.NotNil(t, tWorker)
assert.True(t, strings.HasPrefix(tWorker.GetPublicId(), WorkerPrefix))
@@ -29,7 +29,36 @@ func TestTestWorker(t *testing.T) {
require.NoError(t, rw.LookupById(context.Background(), lkpWorker))
assert.NotNil(t, lkpWorker)
assert.NotNil(t, lkpWorker.GetLastStatusTime())
assert.Equal(t, KmsWorkerType.String(), lkpWorker.GetType())
assert.Equal(t, name, lkpWorker.GetName())
assert.Equal(t, description, lkpWorker.GetDescription())
assert.Equal(t, address, lkpWorker.GetAddress())
}
func TestTestPkiWorker(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
const (
name = "test name"
description = "test description"
)
tWorker := TestPkiWorker(t, conn, wrapper, WithName(name), WithDescription(description))
assert.NotNil(t, tWorker)
assert.True(t, strings.HasPrefix(tWorker.GetPublicId(), WorkerPrefix))
lkpWorker := NewWorker(scope.Global.String())
lkpWorker.PublicId = tWorker.GetPublicId()
rw := db.New(conn)
require.NoError(t, rw.LookupById(context.Background(), lkpWorker))
assert.NotNil(t, lkpWorker)
assert.Equal(t, PkiWorkerType.String(), lkpWorker.GetType())
assert.Equal(t, name, lkpWorker.GetName())
assert.Equal(t, description, lkpWorker.GetDescription())
assert.Nil(t, lkpWorker.GetLastStatusTime())
var keyId string
authorizedWorker := TestPkiWorker(t, conn, wrapper, WithTestPkiWorkerAuthorizedKeyId(&keyId))
assert.NotNil(t, authorizedWorker)
assert.True(t, strings.HasPrefix(authorizedWorker.GetPublicId(), WorkerPrefix))
assert.NotEmpty(t, keyId)
}
+47 -56
View File
@@ -12,6 +12,26 @@ import (
"google.golang.org/protobuf/types/known/structpb"
)
type WorkerType string
const (
UnknownWorkerType WorkerType = "unknown"
KmsWorkerType WorkerType = "kms"
PkiWorkerType WorkerType = "pki"
)
func (t WorkerType) Valid() bool {
switch t {
case KmsWorkerType, PkiWorkerType:
return true
}
return false
}
func (t WorkerType) String() string {
return string(t)
}
type workerAuthWorkerId struct {
WorkerId string `mapstructure:"worker_id"`
}
@@ -40,6 +60,13 @@ type Worker struct {
activeConnectionCount uint32 `gorm:"-"`
apiTags []*Tag `gorm:"-"`
configTags []*Tag `gorm:"-"`
// inputTags is not specified to be api or config tags and is not intended
// to be read by clients. Since config tags and api tags are applied in
// mutually exclusive contexts, inputTags is interpreted to be one or the
// other based on the context in which the worker is passed. As such
// inputTags should only be read when performing mutations on the database.
inputTags []*Tag `gorm:"-"`
}
// NewWorker returns a new Worker. Valid options are WithName, WithDescription
@@ -54,24 +81,7 @@ func NewWorker(scopeId string, opt ...Option) *Worker {
Description: opts.withDescription,
Address: opts.withAddress,
},
apiTags: opts.withWorkerTags,
}
}
// NewWorkerForStatus returns a new Worker usable for status updates.
// Valid options are WithName, WithAddress, and WithWorkerTags, all of which
// are assigned to the worker reported variations of these fields.
// All other options are ignored.
func NewWorkerForStatus(scopeId string, opt ...Option) *Worker {
opts := getOpts(opt...)
return &Worker{
Worker: &store.Worker{
ScopeId: scopeId,
WorkerReportedName: opts.withName,
WorkerReportedAddress: opts.withAddress,
WorkerReportedKeyId: opts.withKeyId,
},
configTags: opts.withWorkerTags,
inputTags: opts.withWorkerTags,
}
}
@@ -100,19 +110,13 @@ func (w *Worker) clone() *Worker {
cWorker.configTags = append(cWorker.configTags, &Tag{Key: t.Key, Value: t.Value})
}
}
return cWorker
}
// CanonicalAddress returns the actual address boundary believes should be used
// to communicate with this worker. This will be the worker resource's address
// unless it is not set in which case it will use address the worker provides
// in its connection status updates. If neither is available, an empty string
// is returned.
func (w *Worker) CanonicalAddress() string {
if w.GetAddress() != "" {
return w.GetAddress()
if w.inputTags != nil {
cWorker.inputTags = make([]*Tag, 0, len(w.inputTags))
for _, t := range w.inputTags {
cWorker.inputTags = append(cWorker.inputTags, &Tag{Key: t.Key, Value: t.Value})
}
}
return w.GetWorkerReportedAddress()
return cWorker
}
// ActiveConnectionCount is the current number of sessions this worker is handling
@@ -138,15 +142,6 @@ func (w *Worker) CanonicalTags() map[string][]string {
return tags
}
// GetApiTags returns the tags for this worker which has been set by the api.
func (w *Worker) GetApiTags() map[string][]string {
tags := make(map[string][]string)
for _, t := range w.apiTags {
tags[t.Key] = append(tags[t.Key], t.Value)
}
return tags
}
// GetConfigTags returns the tags for this worker which has been set through
// the worker daemon's configuration file.
func (w *Worker) GetConfigTags() map[string][]string {
@@ -183,32 +178,28 @@ type workerAggregate struct {
UpdateTime *timestamp.Timestamp
Address string
Version uint32
Type string
ApiTags string
ActiveConnectionCount uint32
// Config Fields
WorkerReportedName string
WorkerReportedAddress string
LastStatusTime *timestamp.Timestamp
WorkerReportedKeyId string
WorkerConfigTags string
LastStatusTime *timestamp.Timestamp
WorkerConfigTags string
}
func (a *workerAggregate) toWorker(ctx context.Context) (*Worker, error) {
const op = "servers.(workerAggregate).toWorker"
worker := &Worker{
Worker: &store.Worker{
PublicId: a.PublicId,
Name: a.Name,
Description: a.Description,
Address: a.Address,
CreateTime: a.CreateTime,
UpdateTime: a.UpdateTime,
ScopeId: a.ScopeId,
Version: a.Version,
WorkerReportedAddress: a.WorkerReportedAddress,
WorkerReportedName: a.WorkerReportedName,
LastStatusTime: a.LastStatusTime,
WorkerReportedKeyId: a.WorkerReportedKeyId,
PublicId: a.PublicId,
Name: a.Name,
Description: a.Description,
Address: a.Address,
CreateTime: a.CreateTime,
UpdateTime: a.UpdateTime,
ScopeId: a.ScopeId,
Version: a.Version,
LastStatusTime: a.LastStatusTime,
Type: a.Type,
},
activeConnectionCount: a.ActiveConnectionCount,
}
+1 -1
View File
@@ -15,7 +15,7 @@ func TestWorkerTags_Create(t *testing.T) {
wrapper := db.TestWrapper(t)
rw := db.New(conn)
worker := TestWorker(t, conn, wrapper)
worker := TestKmsWorker(t, conn, wrapper)
tests := []struct {
name string
+296 -375
View File
@@ -5,31 +5,27 @@ import (
"fmt"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/timestamp"
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/servers/store"
"github.com/hashicorp/boundary/internal/types/scope"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/timestamppb"
)
func TestWorkerCanonicalAddress(t *testing.T) {
worker := NewWorkerForStatus(scope.Global.String(), WithAddress("status"))
assert.Equal(t, "status", worker.CanonicalAddress())
worker.Address = "worker"
assert.Equal(t, "worker", worker.CanonicalAddress())
}
func TestWorkerCanonicalTags(t *testing.T) {
w := NewWorker(scope.Global.String(),
WithWorkerTags(
&Tag{Key: "key", Value: "apis unique"},
&Tag{Key: "key", Value: "shared"},
&Tag{Key: "key2", Value: "apis key2 unique"},
))
w := NewWorker(scope.Global.String())
w.apiTags = []*Tag{
{Key: "key", Value: "apis unique"},
{Key: "key", Value: "shared"},
{Key: "key2", Value: "apis key2 unique"},
}
w.configTags = []*Tag{
{Key: "key", Value: "configs unique"},
{Key: "key", Value: "shared"},
@@ -57,33 +53,36 @@ func TestWorkerAggregate(t *testing.T) {
return got
}
// Worker without a status
{
t.Run("kms worker", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
id = strings.ToLower(id)
w := NewWorker(scope.Global.String(),
WithName(id),
WithAddress("address"))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
got := getAggWorker(id)
assert.Equal(t, KmsWorkerType.String(), got.GetType())
assert.Equal(t, id, got.GetPublicId())
assert.Equal(t, scope.Global.String(), got.GetScopeId())
assert.Equal(t, id, got.GetName())
assert.Equal(t, "address", got.GetAddress())
assert.Equal(t, uint32(1), got.GetVersion())
assert.Nil(t, got.GetLastStatusTime())
assert.NotNil(t, got.GetLastStatusTime())
assert.Empty(t, got.CanonicalTags())
}
})
// Worker with status
{
t.Run("Worker with status", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
w := NewWorkerForStatus(scope.Global.String(),
w := NewWorker(scope.Global.String(),
WithAddress("address"),
WithName(strings.ToLower(id)))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
@@ -91,19 +90,19 @@ func TestWorkerAggregate(t *testing.T) {
assert.Equal(t, id, got.GetPublicId())
assert.Equal(t, uint32(1), got.GetVersion())
assert.NotNil(t, got.GetLastStatusTime())
assert.Equal(t, strings.ToLower(id), got.GetWorkerReportedName())
assert.Equal(t, "address", got.GetWorkerReportedAddress())
}
assert.Equal(t, strings.ToLower(id), got.GetName())
assert.Equal(t, "address", got.GetAddress())
})
// Worker with a config tag
{
t.Run("Worker with a config tag", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
ws := NewWorkerForStatus(scope.Global.String(),
w := NewWorker(scope.Global.String(),
WithAddress("address"),
WithName(strings.ToLower(id)))
ws.PublicId = id
require.NoError(t, rw.Create(ctx, ws))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
require.NoError(t, rw.Create(ctx,
&store.WorkerTag{
WorkerId: id,
@@ -118,17 +117,17 @@ func TestWorkerAggregate(t *testing.T) {
assert.NotNil(t, got.GetLastStatusTime())
assert.Empty(t, got.apiTags)
assert.Equal(t, got.configTags, []*Tag{{Key: "key", Value: "val"}})
}
})
// Worker with many config tag
{
t.Run("Worker with many config tag", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
ws := NewWorkerForStatus(scope.Global.String(),
w := NewWorker(scope.Global.String(),
WithAddress("address"),
WithName(strings.ToLower(id)))
ws.PublicId = id
require.NoError(t, rw.Create(ctx, ws))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
require.NoError(t, rw.Create(ctx, &store.WorkerTag{
WorkerId: id,
Key: "key",
@@ -156,17 +155,17 @@ func TestWorkerAggregate(t *testing.T) {
{Key: "key", Value: "val2"},
{Key: "key2", Value: "val2"},
})
}
})
// Worker with an api tag
{
t.Run("Worker with an api tag", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
ws := NewWorkerForStatus(scope.Global.String(),
w := NewWorker(scope.Global.String(),
WithAddress("address"),
WithName(strings.ToLower(id)))
ws.PublicId = id
require.NoError(t, rw.Create(ctx, ws))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
require.NoError(t, rw.Create(ctx,
&store.WorkerTag{
WorkerId: id,
@@ -181,17 +180,18 @@ func TestWorkerAggregate(t *testing.T) {
assert.NotNil(t, got.GetLastStatusTime())
assert.Empty(t, got.GetConfigTags())
assert.Equal(t, got.apiTags, []*Tag{{Key: "key", Value: "val"}})
}
})
// Worker with mix of tag sources
{
t.Run("Worker with mix of tag sources", func(t *testing.T) {
id, err := newWorkerId(ctx)
require.NoError(t, err)
ws := NewWorkerForStatus(scope.Global.String(),
w := NewWorker(scope.Global.String(),
WithAddress("address"),
WithName(strings.ToLower(id)))
ws.PublicId = id
require.NoError(t, rw.Create(ctx, ws))
w.Type = KmsWorkerType.String()
w.PublicId = id
require.NoError(t, rw.Create(ctx, w))
require.NoError(t, rw.Create(ctx, &store.WorkerTag{
WorkerId: id,
Key: "key",
@@ -220,7 +220,7 @@ func TestWorkerAggregate(t *testing.T) {
assert.ElementsMatch(t, got.configTags, []*Tag{
{Key: "key", Value: "val"},
})
}
})
}
func TestWorker_Update(t *testing.T) {
@@ -245,260 +245,213 @@ func TestWorker_Update(t *testing.T) {
wantUpdateError bool
}{
{
name: "base update with base",
name: "kms update address",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with base",
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "kms update address",
Address: "kms update address",
},
},
update: Worker{
Worker: &store.Worker{
Description: "base update with base updated",
Address: "updated kms update address",
},
},
mask: []string{"Description"},
mask: []string{"Address"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "base update with base updated", up.Description)
assert.Equal(t, "kms update address", up.Name)
assert.Equal(t, "updated kms update address", up.Address)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
},
},
{
name: "kms update name",
initial: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "kms update name",
Address: "kms update name",
},
},
update: Worker{
Worker: &store.Worker{
Name: "updated kms update name",
},
},
mask: []string{"Name"},
wantUpdateError: true,
},
{
name: "kms clear name",
initial: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "kms clear name",
Address: "kms clear name",
},
},
update: Worker{
Worker: &store.Worker{},
},
nullMask: []string{"Name"},
wantUpdateError: true,
},
{
name: "pki update address",
initial: Worker{
Worker: &store.Worker{
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki update address",
},
},
update: Worker{
Worker: &store.Worker{
Address: "updated pki update address",
},
},
mask: []string{"Address"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "pki update address", up.Name)
assert.Equal(t, "updated pki update address", up.Address)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
},
},
{
name: "pki update name",
initial: Worker{
Worker: &store.Worker{
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki update name",
},
},
update: Worker{
Worker: &store.Worker{
Name: "updated pki update name",
},
},
mask: []string{"Name"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "updated pki update name", up.Name)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, uint32(2), up.Version)
assert.Nil(t, up.GetLastStatusTime())
},
},
{
name: "base update with worker reported address and name",
name: "pki update description",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki update description",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedName: "base update with worker reported address and name",
WorkerReportedAddress: "base update with worker reported address and name",
},
},
mask: []string{"WorkerReportedAddress", "WorkerReportedName"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "base update with worker reported address and name", up.WorkerReportedAddress)
assert.Equal(t, "base update with worker reported address and name", up.WorkerReportedName)
assert.Equal(t, uint32(1), up.Version)
assert.NotNil(t, up.GetLastStatusTime())
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
},
},
{
name: "base update with worker reported address and keyId",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedKeyId: "base update with worker reported address and keyId",
WorkerReportedAddress: "base update with worker reported address and keyId",
},
},
mask: []string{"WorkerReportedAddress", "WorkerReportedKeyId"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "base update with worker reported address and keyId", up.WorkerReportedAddress)
assert.Equal(t, "base update with worker reported address and keyId", up.WorkerReportedKeyId)
assert.Equal(t, uint32(1), up.Version)
assert.NotNil(t, up.GetLastStatusTime())
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
},
},
{
name: "base update with worker reported address",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedAddress: "base update with worker reported address",
},
},
mask: []string{"WorkerReportedAddress"},
wantUpdateError: true,
},
{
// If any status fields are set then worker reported address must
// be set.
name: "base update with worker reported name",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedName: "base update with worker reported name",
},
},
mask: []string{"WorkerReportedName"},
wantUpdateError: true,
},
{
// If any status fields are set then worker reported address must
// be set.
name: "base update with worker reported keyId",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedKeyId: "base update with worker reported keyId",
},
},
mask: []string{"WorkerReportedKeyId"},
wantUpdateError: true,
},
{
name: "base update with worker reported fields",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Description: "base update with status",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedName: "base update with worker reported fields",
WorkerReportedAddress: "base update with worker reported fields",
},
},
mask: []string{"WorkerReportedName", "WorkerReportedAddress"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "base update with worker reported fields", up.WorkerReportedAddress)
assert.Equal(t, "base update with worker reported fields", up.WorkerReportedName)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, uint32(1), up.Version)
assert.NotNil(t, up.GetLastStatusTime())
assert.Equal(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
},
},
{
name: "worker reported update with base",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "worker reported update with base",
WorkerReportedName: "worker reported update with base",
},
},
update: Worker{
Worker: &store.Worker{
Description: "worker reported update with base",
Description: "updated pki update description",
},
},
mask: []string{"Description"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "worker reported update with base", up.Description)
assert.Equal(t, "pki update description", up.Name)
assert.Equal(t, "updated pki update description", up.Description)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, uint32(2), up.Version)
assert.NotNil(t, up.GetLastStatusTime())
assert.Equal(t, init.GetLastStatusTime(), up.GetLastStatusTime())
assert.Nil(t, up.GetLastStatusTime())
},
},
{
name: "worker reported update name to unprintable",
name: "pki clear address",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "worker reported update name to unprintable",
WorkerReportedName: "worker reported update name to unprintable",
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedName: "unprintable \u0008 name",
},
},
mask: []string{"WorkerReportedName"},
wantUpdateError: true,
},
{
name: "worker reported clearing address",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "worker reported clearing address",
WorkerReportedName: "worker reported clearing address",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki clear address",
Address: "pki clear address",
LastStatusTime: &timestamp.Timestamp{Timestamp: timestamppb.New(time.Now().Add(time.Hour))},
},
},
update: Worker{
Worker: &store.Worker{},
},
nullMask: []string{"WorkerReportedAddress"},
nullMask: []string{"Address"},
wantUpdateError: true,
},
{
name: "worker reported updating worker reported",
name: "pki clear name",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "start",
WorkerReportedName: "start",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki clear name",
Address: "pki clear name",
LastStatusTime: &timestamp.Timestamp{Timestamp: timestamppb.New(time.Now().Add(time.Hour))},
},
},
update: Worker{
Worker: &store.Worker{
WorkerReportedAddress: "worker reported updating worker reported",
},
Worker: &store.Worker{},
},
mask: []string{"WorkerReportedAddress"},
nullMask: []string{"Name"},
assert: func(t *testing.T, init, up *Worker) {
t.Helper()
assert.Equal(t, "worker reported updating worker reported", up.GetWorkerReportedAddress())
assert.NotNil(t, up.GetLastStatusTime())
assert.Greater(t, up.GetLastStatusTime().AsTime(), init.GetLastStatusTime().AsTime())
// We don't modify the worker version while operating only on the worker fields
assert.Empty(t, up.Name)
assert.Greater(t, up.GetUpdateTime().AsTime(), up.GetCreateTime().AsTime())
assert.Equal(t, uint32(1), up.Version)
assert.Greater(t, up.GetLastStatusTime().AsTime(), up.GetUpdateTime().AsTime())
assert.Less(t, up.GetLastStatusTime().AsTime(), time.Now().Add(time.Hour))
},
},
{
name: "worker reported clearing worker reported name",
name: "pki update name to capital",
initial: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "worker reported clearing worker reported name",
WorkerReportedName: "worker reported clearing worker reported name",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki update name to capital",
},
},
update: Worker{
Worker: &store.Worker{},
Worker: &store.Worker{
Name: "PKI Update Name To Capital",
},
},
nullMask: []string{"WorkerReportedName"},
mask: []string{"Name"},
wantUpdateError: true,
},
{
name: "pki update name to unprintable",
initial: Worker{
Worker: &store.Worker{
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "worker reported update name to unprintable",
},
},
update: Worker{
Worker: &store.Worker{
Name: "unprintable \u0008 name",
},
},
mask: []string{"Name"},
wantUpdateError: true,
},
}
@@ -544,9 +497,88 @@ func TestWorker_Create(t *testing.T) {
want wanted
}{
{
name: "base",
name: "kms base",
in: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Address: "address",
Name: "kms base",
Description: "kms base",
},
},
want: wanted{lastStatusUpdated: true},
},
{
name: "kms with no name field",
in: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Address: "address",
},
},
want: wanted{createError: true},
},
{
name: "kms with no address field",
in: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "kms with no address field",
},
},
want: wanted{createError: true},
},
{
name: "kms with upper case name",
in: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "With Upper Case Worker Reported Name",
Address: "address",
},
},
want: wanted{createError: true},
},
{
name: "kms with unprintable worker reported name",
in: Worker{
Worker: &store.Worker{
Type: KmsWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "unprintable \u0008 worker reported name",
Address: "address",
},
},
want: wanted{createError: true},
},
// PKI workers are not created in a way that should set the address
// or the last_status_time.
{
name: "pki base",
in: Worker{
Worker: &store.Worker{
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "pki base",
},
},
want: wanted{},
},
{
name: "pki with no name field",
in: Worker{
Worker: &store.Worker{
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
},
@@ -554,134 +586,42 @@ func TestWorker_Create(t *testing.T) {
want: wanted{},
},
{
name: "with non status fields",
name: "pki with address field",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "with non status fields",
Description: "with non status fields",
Address: "address",
},
},
want: wanted{},
},
{
name: "with upper case worker reported name",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedName: "With Upper Case Worker Reported Name",
WorkerReportedAddress: "address",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Address: "address",
},
},
want: wanted{createError: true},
},
{
name: "with unprintable worker reported name",
name: "pki with upper case name",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedName: "unprintable \u0008 worker reported name",
WorkerReportedAddress: "address",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "PKI With Upper Case Worker Reported Name",
Address: "address",
},
},
want: wanted{createError: true},
},
{
name: "with status fields",
name: "pki with unprintable worker reported name",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedName: "with non status fields",
WorkerReportedAddress: "with non status fields",
Type: PkiWorkerType.String(),
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "unprintable \u0008 worker reported name",
Address: "address",
},
},
want: wanted{
lastStatusUpdated: true,
},
},
{
name: "with worker reported address",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedAddress: "with worker reported address",
},
},
want: wanted{
createError: true,
},
},
{
// The worker reported address is a required field if any of the
// worker reported fields are set.
name: "with worker reported name",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
WorkerReportedName: "with worker reported name",
},
},
want: wanted{
createError: true,
},
},
{
name: "non status fields with worker reported fields",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "non status fields with worker reported fields",
Description: "non status fields with worker reported fields",
Address: "address",
WorkerReportedAddress: "non status fields with worker reported fields",
WorkerReportedName: "non status fields with worker reported fields",
},
},
want: wanted{
lastStatusUpdated: true,
},
},
{
// The worker reported address is a required field if any of the
// worker reported fields are set.
name: "non status fields with worker reported name",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "non status fields with worker reported name",
Description: "non status fields with worker reported name",
Address: "address",
WorkerReportedName: "non status fields with worker reported name",
},
},
want: wanted{
createError: true,
},
},
{
name: "non status fields with worker reported address",
in: Worker{
Worker: &store.Worker{
ScopeId: scope.Global.String(),
PublicId: newId(),
Name: "non status fields with worker reported address",
Description: "non status fields with worker reported address",
Address: "address",
WorkerReportedAddress: "non status fields with worker reported address",
},
},
want: wanted{
createError: true,
},
want: wanted{createError: true},
},
}
for _, tc := range cases {
@@ -711,7 +651,6 @@ func TestWorker_New(t *testing.T) {
t.Parallel()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
rw := db.New(conn)
org, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
@@ -721,10 +660,9 @@ func TestWorker_New(t *testing.T) {
}
tests := []struct {
name string
args args
want *Worker
wantCreateErr bool
name string
args args
want *Worker
}{
{
name: "missing-scope-id",
@@ -732,7 +670,6 @@ func TestWorker_New(t *testing.T) {
want: &Worker{
Worker: &store.Worker{},
},
wantCreateErr: true,
},
{
name: "global-scope-id",
@@ -755,7 +692,6 @@ func TestWorker_New(t *testing.T) {
ScopeId: org.GetPublicId(),
},
},
wantCreateErr: true,
},
{
name: "project-scope-id",
@@ -767,7 +703,6 @@ func TestWorker_New(t *testing.T) {
ScopeId: prj.GetPublicId(),
},
},
wantCreateErr: true,
},
{
name: "with name",
@@ -829,7 +764,7 @@ func TestWorker_New(t *testing.T) {
Worker: &store.Worker{
ScopeId: scope.Global.String(),
},
apiTags: []*Tag{
inputTags: []*Tag{
{
Key: "key",
Value: "val",
@@ -845,20 +780,6 @@ func TestWorker_New(t *testing.T) {
assert := assert.New(t)
got := NewWorker(tt.args.scopeId, tt.args.opts...)
assert.Empty(cmp.Diff(tt.want, got.clone(), protocmp.Transform()))
id, err := newWorkerId(context.Background())
assert.NoError(err)
tt.want.PublicId = id
got.PublicId = id
err2 := rw.Create(context.Background(), got)
if tt.wantCreateErr {
assert.Error(err2)
} else {
assert.NoError(err2)
assert.Equal(uint32(1), got.Version)
}
})
}
}
+3 -3
View File
@@ -291,7 +291,7 @@ func TestWorkerAuthStore(t *testing.T) {
testKey, err := databaseWrapper.KeyId(ctx)
require.NoError(t, err)
worker := TestWorker(t, conn, wrapper)
worker := TestPkiWorker(t, conn, wrapper)
wSignPubKey := populateBytes(defaultLength)
wEncPubKey := populateBytes(defaultLength)
@@ -430,8 +430,8 @@ func TestWorkerCertBundle(t *testing.T) {
wrapper := db.TestWrapper(t)
testKey := TestKmsKey(ctx, t, conn, wrapper)
worker := TestWorker(t, conn, wrapper)
workerAuth := TestWorkerAuth(ctx, t, conn, worker, testKey)
worker := TestPkiWorker(t, conn, wrapper)
workerAuth := TestWorkerAuth(t, conn, worker, testKey)
rootCA := TestRootCertificate(ctx, t, conn, testKey)
certBundle := populateBytes(defaultLength)
+14 -15
View File
@@ -45,8 +45,8 @@ func TestSessionConnectionCleanupJob(t *testing.T) {
// Create two "workers". One will remain untouched while the other "goes
// away and comes back" (worker 2).
worker1 := servers.TestWorker(t, conn, wrapper)
worker2 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
worker2 := servers.TestKmsWorker(t, conn, wrapper)
// Create a few sessions on each, activate, and authorize a connection
var connIds []string
@@ -109,9 +109,10 @@ func TestSessionConnectionCleanupJob(t *testing.T) {
// Push an upsert to the first worker so that its status has been
// updated.
_, err = serversRepo.UpsertWorkerStatus(ctx, servers.NewWorkerForStatus(scope.Global.String(),
servers.WithName(worker1.GetWorkerReportedName()),
servers.WithAddress(worker1.GetWorkerReportedAddress())))
_, err = serversRepo.UpsertWorkerStatus(ctx, servers.NewWorker(scope.Global.String(),
servers.WithName(worker1.GetName()),
servers.WithAddress(worker1.GetAddress())),
servers.WithPublicId(worker1.GetPublicId()))
require.NoError(err)
// Run the job.
@@ -198,10 +199,10 @@ func TestCloseConnectionsForDeadWorkers(t *testing.T) {
// firstly, the last worker will have no connections at all, and we will be
// closing the others in stages to test multiple servers being closed at
// once.
worker1 := servers.TestWorker(t, conn, wrapper)
worker2 := servers.TestWorker(t, conn, wrapper)
worker3 := servers.TestWorker(t, conn, wrapper)
worker4 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
worker2 := servers.TestKmsWorker(t, conn, wrapper)
worker3 := servers.TestKmsWorker(t, conn, wrapper)
worker4 := servers.TestKmsWorker(t, conn, wrapper)
// Create sessions on the first three, activate, and authorize connections
var worker1ConnIds, worker2ConnIds, worker3ConnIds []string
@@ -292,11 +293,9 @@ func TestCloseConnectionsForDeadWorkers(t *testing.T) {
// the most up-to-date fields.
updateServer := func(t *testing.T, w *servers.Worker) *servers.Worker {
t.Helper()
// The worker provided name will derive the WorkerId every time
// UpsertWorkerStatus is called. Setting the Worker Id on the caller
// side is an error.
pubId := w.GetPublicId()
w.PublicId = ""
wkr, err := serversRepo.UpsertWorkerStatus(ctx, w)
wkr, err := serversRepo.UpsertWorkerStatus(ctx, w, servers.WithPublicId(pubId))
require.NoError(err)
return wkr
}
@@ -465,7 +464,7 @@ func TestCloseWorkerlessConnections(t *testing.T) {
}
// Setup deleted worker connections
deletedWorker := servers.TestWorker(t, conn, wrapper)
deletedWorker := servers.TestKmsWorker(t, conn, wrapper)
dActiveConn := createConnection(deletedWorker.GetPublicId())
dClosedConn := createConnection(deletedWorker.GetPublicId())
connRepo.closeConnections(ctx, []CloseWith{{
@@ -478,7 +477,7 @@ func TestCloseWorkerlessConnections(t *testing.T) {
require.NoError(err)
// Non deleted worker case
activeWorker := servers.TestWorker(t, conn, wrapper)
activeWorker := servers.TestKmsWorker(t, conn, wrapper)
activeConn := createConnection(activeWorker.GetPublicId())
closedConn := createConnection(activeWorker.GetPublicId())
connRepo.closeConnections(ctx, []CloseWith{{
@@ -359,8 +359,8 @@ func TestRepository_orphanedConnections(t *testing.T) {
// Create two "workers". One will remain untouched while the other "goes
// away and comes back" (worker 2).
worker1 := servers.TestWorker(t, conn, wrapper)
worker2 := servers.TestWorker(t, conn, wrapper)
worker1 := servers.TestKmsWorker(t, conn, wrapper)
worker2 := servers.TestKmsWorker(t, conn, wrapper)
// Create a few sessions on each, activate, and authorize a connection
var connIds []string
@@ -36,7 +36,7 @@ func TestService_AuthorizeConnection(t *testing.T) {
composedOf.ExpirationTime = exp
}
s := TestSession(t, conn, wrapper, composedOf)
srv := servers.TestWorker(t, conn, wrapper)
srv := servers.TestKmsWorker(t, conn, wrapper)
testServer = srv.PublicId
tofu := TestTofu(t)
_, _, err := repo.ActivateSession(context.Background(), s.PublicId, s.Version, tofu)
@@ -14,7 +14,6 @@ import (
"github.com/hashicorp/boundary/internal/session"
"github.com/hashicorp/boundary/internal/target"
"github.com/hashicorp/boundary/internal/target/tcp"
"github.com/hashicorp/boundary/internal/types/scope"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -28,12 +27,11 @@ func TestWorkerStatusReport(t *testing.T) {
org, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
serverRepo, _ := servers.NewRepository(rw, rw, kms)
serverRepo.UpsertController(ctx, &store.Controller{
_, err := serverRepo.UpsertController(ctx, &store.Controller{
PrivateId: "test_controller1",
Address: "127.0.0.1",
})
serverRepo.UpsertWorkerStatus(ctx, servers.NewWorkerForStatus(scope.Global.String(),
servers.WithAddress("127.0.0.1")))
require.NoError(t, err)
repo, err := session.NewRepository(rw, rw, kms)
require.NoError(t, err)
@@ -66,7 +64,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "No Sessions",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
return testCase{
worker: worker,
req: []session.StateReport{},
@@ -77,7 +75,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "No Sessions already canceled",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
@@ -109,7 +107,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "Still Active",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
@@ -143,7 +141,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "SessionClosed",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
@@ -183,7 +181,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "MultipleSessionsClosed",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
@@ -250,7 +248,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "OrphanedConnection",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
@@ -301,7 +299,7 @@ func TestWorkerStatusReport(t *testing.T) {
{
name: "MultipleSessionsAndOrphanedConnections",
caseFn: func(t *testing.T) testCase {
worker := servers.TestWorker(t, conn, wrapper)
worker := servers.TestKmsWorker(t, conn, wrapper)
sess := session.TestSession(t, conn, wrapper, session.ComposedOf{
UserId: uId,
HostId: h.GetPublicId(),
+1 -1
View File
@@ -74,7 +74,7 @@ func Test_TestWorker(t *testing.T) {
require := require.New(t)
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
w := servers.TestWorker(t, conn, wrapper)
w := servers.TestKmsWorker(t, conn, wrapper)
require.NotNil(w)
}
@@ -25,73 +25,6 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// WorkerProvidedConfiguration contains configuration values reported by the worker daemon.
type WorkerProvidedConfiguration struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Output only. The address the worker daemon reports itself as reachable at.
Address string `protobuf:"bytes,10,opt,name=address,proto3" json:"address,omitempty"`
// Output only. The name the worker daemon reports itself having.
Name string `protobuf:"bytes,20,opt,name=name,proto3" json:"name,omitempty"`
// Output only. The tags reporteed by the worker daemon.
Tags map[string]*structpb.ListValue `protobuf:"bytes,40,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (x *WorkerProvidedConfiguration) Reset() {
*x = WorkerProvidedConfiguration{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WorkerProvidedConfiguration) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WorkerProvidedConfiguration) ProtoMessage() {}
func (x *WorkerProvidedConfiguration) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WorkerProvidedConfiguration.ProtoReflect.Descriptor instead.
func (*WorkerProvidedConfiguration) Descriptor() ([]byte, []int) {
return file_controller_api_resources_workers_v1_worker_proto_rawDescGZIP(), []int{0}
}
func (x *WorkerProvidedConfiguration) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *WorkerProvidedConfiguration) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *WorkerProvidedConfiguration) GetTags() map[string]*structpb.ListValue {
if x != nil {
return x.Tags
}
return nil
}
// Worker contains all fields related to a Worker resource
type Worker struct {
state protoimpl.MessageState
@@ -104,9 +37,11 @@ type Worker struct {
ScopeId string `protobuf:"bytes,20,opt,name=scope_id,proto3" json:"scope_id,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. Scope information for this resource.
Scope *scopes.ScopeInfo `protobuf:"bytes,30,opt,name=scope,proto3" json:"scope,omitempty"`
// Optional name for identification purposes.
// Optional name for identification purposes. Can only be set through the API
// for `pki`-type workers; read-only for `kms`-type workers.
Name *wrapperspb.StringValue `protobuf:"bytes,40,opt,name=name,proto3" json:"name,omitempty" class:"sensitive"` // @gotags: `class:"sensitive"`
// Optional user-set description for identification purposes.
// Optional user-set description for identification purposes. Can only be set
// through the API for `pki`-type workers; read-only for `kms`-type workers.
Description *wrapperspb.StringValue `protobuf:"bytes,50,opt,name=description,proto3" json:"description,omitempty" class:"sensitive"` // @gotags: `class:"sensitive"`
// Output only. The time this resource was created.
CreatedTime *timestamppb.Timestamp `protobuf:"bytes,60,opt,name=created_time,proto3" json:"created_time,omitempty" class:"public"` // @gotags: `class:"public"`
@@ -115,23 +50,17 @@ type Worker struct {
// Version is used in mutation requests, after the initial creation, to ensure this resource has not changed.
// The mutation will fail if the version does not match the latest known good version.
Version uint32 `protobuf:"varint,80,opt,name=version,proto3" json:"version,omitempty" class:"public"` // @gotags: `class:"public"`
// The address that this worker is reachable at.
Address *wrapperspb.StringValue `protobuf:"bytes,90,opt,name=address,proto3" json:"address,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. This is the address used by authorized session. The value
// is the same as the address field if set. Otherwise it uses the address the
// worker reports.
CanonicalAddress string `protobuf:"bytes,100,opt,name=canonical_address,proto3" json:"canonical_address,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The tags attached to this worker.
Tags map[string]*structpb.ListValue `protobuf:"bytes,110,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" class:"public"` // @gotags: `class:"public"`
// Output only. The deduplicated union of the tags reported by the worker and
// the tags added through the user facing api. This is used when applying
// worker filters.
// Output only. The address that this worker is reachable at, as sourced from
// the worker's configuration file.
Address string `protobuf:"bytes,90,opt,name=address,proto3" json:"address,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The deduplicated union of the tags reported by the worker from
// its configuration and any tags added through other means. This is used
// when applying worker filters.
CanonicalTags map[string]*structpb.ListValue `protobuf:"bytes,120,rep,name=canonical_tags,proto3" json:"canonical_tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" class:"public"` // @gotags: `class:"public"`
// Output only. The tags set in the worker's configuration file.
ConfigTags map[string]*structpb.ListValue `protobuf:"bytes,130,rep,name=config_tags,proto3" json:"config_tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3" class:"public"` // @gotags: `class:"public"`
// Output only. The time this worker daemon last reported its status.
LastStatusTime *timestamppb.Timestamp `protobuf:"bytes,130,opt,name=last_status_time,proto3" json:"last_status_time,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The set of information the worker daemon has reported about
// itself.
WorkerProvidedConfiguration *WorkerProvidedConfiguration `protobuf:"bytes,140,opt,name=worker_provided_configuration,proto3" json:"worker_provided_configuration,omitempty"`
LastStatusTime *timestamppb.Timestamp `protobuf:"bytes,140,opt,name=last_status_time,proto3" json:"last_status_time,omitempty" class:"public"` // @gotags: `class:"public"`
// worker_generated_auth_token is input only. Supports the worker led node
// enrollment flow where this credentials token is produced by a worker. This
// token is a base58 encoded types.FetchNodeCredentialsRequest from
@@ -139,6 +68,9 @@ type Worker struct {
WorkerGeneratedAuthToken *wrapperspb.StringValue `protobuf:"bytes,150,opt,name=worker_generated_auth_token,proto3" json:"worker_generated_auth_token,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The number of connections that this worker is currently handling.
ActiveConnectionCount *wrapperspb.UInt32Value `protobuf:"bytes,160,opt,name=active_connection_count,proto3" json:"active_connection_count,omitempty" class:"public"` // @gotags: `class:"public"`
// Output only. The type of the worker, denoted by how it authenticates: `pki`
// or `kms`.
Type string `protobuf:"bytes,170,opt,name=type,proto3" json:"type,omitempty"`
// Output only. The available actions on this resource for the requester.
AuthorizedActions []string `protobuf:"bytes,300,rep,name=authorized_actions,proto3" json:"authorized_actions,omitempty" class:"public"` // @gotags: `class:"public"`
}
@@ -146,7 +78,7 @@ type Worker struct {
func (x *Worker) Reset() {
*x = Worker{}
if protoimpl.UnsafeEnabled {
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[1]
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -159,7 +91,7 @@ func (x *Worker) String() string {
func (*Worker) ProtoMessage() {}
func (x *Worker) ProtoReflect() protoreflect.Message {
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[1]
mi := &file_controller_api_resources_workers_v1_worker_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -172,7 +104,7 @@ func (x *Worker) ProtoReflect() protoreflect.Message {
// Deprecated: Use Worker.ProtoReflect.Descriptor instead.
func (*Worker) Descriptor() ([]byte, []int) {
return file_controller_api_resources_workers_v1_worker_proto_rawDescGZIP(), []int{1}
return file_controller_api_resources_workers_v1_worker_proto_rawDescGZIP(), []int{0}
}
func (x *Worker) GetId() string {
@@ -231,27 +163,13 @@ func (x *Worker) GetVersion() uint32 {
return 0
}
func (x *Worker) GetAddress() *wrapperspb.StringValue {
func (x *Worker) GetAddress() string {
if x != nil {
return x.Address
}
return nil
}
func (x *Worker) GetCanonicalAddress() string {
if x != nil {
return x.CanonicalAddress
}
return ""
}
func (x *Worker) GetTags() map[string]*structpb.ListValue {
if x != nil {
return x.Tags
}
return nil
}
func (x *Worker) GetCanonicalTags() map[string]*structpb.ListValue {
if x != nil {
return x.CanonicalTags
@@ -259,16 +177,16 @@ func (x *Worker) GetCanonicalTags() map[string]*structpb.ListValue {
return nil
}
func (x *Worker) GetLastStatusTime() *timestamppb.Timestamp {
func (x *Worker) GetConfigTags() map[string]*structpb.ListValue {
if x != nil {
return x.LastStatusTime
return x.ConfigTags
}
return nil
}
func (x *Worker) GetWorkerProvidedConfiguration() *WorkerProvidedConfiguration {
func (x *Worker) GetLastStatusTime() *timestamppb.Timestamp {
if x != nil {
return x.WorkerProvidedConfiguration
return x.LastStatusTime
}
return nil
}
@@ -287,6 +205,13 @@ func (x *Worker) GetActiveConnectionCount() *wrapperspb.UInt32Value {
return nil
}
func (x *Worker) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Worker) GetAuthorizedActions() []string {
if x != nil {
return x.AuthorizedActions
@@ -314,83 +239,53 @@ var file_controller_api_resources_workers_v1_worker_proto_rawDesc = []byte{
0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x80, 0x02, 0x0a, 0x1b, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x50, 0x72, 0x6f,
0x76, 0x69, 0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x12, 0x5e, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x28, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4a,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x76, 0x69,
0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73,
0x1a, 0x53, 0x0a, 0x09, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xe5, 0x0a, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05,
0x73, 0x63, 0x6f, 0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31,
0x2e, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70,
0x65, 0x12, 0x46, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x14, 0xa0,
0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x0b, 0x64, 0x65, 0x73,
0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x22, 0xa0, 0xda,
0x29, 0x01, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a,
0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x0c, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a,
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x46, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
0x0c, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a,
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x18, 0x5a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e,
0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x1a, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29, 0x12,
0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x63,
0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61,
0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x49, 0x0a, 0x04, 0x74, 0x61, 0x67,
0x73, 0x18, 0x6e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x73, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f,
0x72, 0x6b, 0x65, 0x72, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04,
0x74, 0x61, 0x67, 0x73, 0x12, 0x66, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61,
0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x78, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x63,
0x74, 0x6f, 0x22, 0xa3, 0x09, 0x0a, 0x06, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a,
0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x12, 0x43, 0x0a, 0x05, 0x73, 0x63, 0x6f,
0x70, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x63,
0x6f, 0x70, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x12, 0x46,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x14, 0xa0, 0xda, 0x29, 0x01,
0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x22, 0xa0, 0xda, 0x29, 0x01, 0xc2,
0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64,
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0c, 0x63, 0x72,
0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x3c, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x63, 0x72,
0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x75, 0x70,
0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65,
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x50, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x5a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x66,
0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73,
0x18, 0x78, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72,
0x6b, 0x65, 0x72, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x54, 0x61, 0x67,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61,
0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x5e, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x82, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x2e,
0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69,
0x63, 0x61, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x61,
0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x47, 0x0a, 0x10,
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x18, 0x82, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x8c, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72,
0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x76, 0x69,
0x64, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x52, 0x1d, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x76, 0x31, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x47, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x8c, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x10, 0x6c,
0x61, 0x73, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x12,
0x5f, 0x0a, 0x1b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
0x74, 0x65, 0x64, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x96,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
@@ -402,27 +297,29 @@ var file_controller_api_resources_workers_v1_worker_proto_rawDesc = []byte{
0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65,
0x52, 0x17, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x53, 0x0a, 0x09, 0x54, 0x61,
0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56,
0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a,
0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x13, 0x0a, 0x04, 0x74, 0x79, 0x70,
0x65, 0x18, 0xaa, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2f,
0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a,
0x5c, 0x0a, 0x12, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x54, 0x61, 0x67, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c,
0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x50, 0x5a,
0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73,
0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f,
0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x3b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x59, 0x0a,
0x0f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x50, 0x5a, 0x4e, 0x67, 0x69, 0x74, 0x68,
0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70,
0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62,
0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69,
0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x65,
0x72, 0x73, 0x3b, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
@@ -437,41 +334,35 @@ func file_controller_api_resources_workers_v1_worker_proto_rawDescGZIP() []byte
return file_controller_api_resources_workers_v1_worker_proto_rawDescData
}
var file_controller_api_resources_workers_v1_worker_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_controller_api_resources_workers_v1_worker_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_controller_api_resources_workers_v1_worker_proto_goTypes = []interface{}{
(*WorkerProvidedConfiguration)(nil), // 0: controller.api.resources.workers.v1.WorkerProvidedConfiguration
(*Worker)(nil), // 1: controller.api.resources.workers.v1.Worker
nil, // 2: controller.api.resources.workers.v1.WorkerProvidedConfiguration.TagsEntry
nil, // 3: controller.api.resources.workers.v1.Worker.TagsEntry
nil, // 4: controller.api.resources.workers.v1.Worker.CanonicalTagsEntry
(*scopes.ScopeInfo)(nil), // 5: controller.api.resources.scopes.v1.ScopeInfo
(*wrapperspb.StringValue)(nil), // 6: google.protobuf.StringValue
(*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp
(*wrapperspb.UInt32Value)(nil), // 8: google.protobuf.UInt32Value
(*structpb.ListValue)(nil), // 9: google.protobuf.ListValue
(*Worker)(nil), // 0: controller.api.resources.workers.v1.Worker
nil, // 1: controller.api.resources.workers.v1.Worker.CanonicalTagsEntry
nil, // 2: controller.api.resources.workers.v1.Worker.ConfigTagsEntry
(*scopes.ScopeInfo)(nil), // 3: controller.api.resources.scopes.v1.ScopeInfo
(*wrapperspb.StringValue)(nil), // 4: google.protobuf.StringValue
(*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp
(*wrapperspb.UInt32Value)(nil), // 6: google.protobuf.UInt32Value
(*structpb.ListValue)(nil), // 7: google.protobuf.ListValue
}
var file_controller_api_resources_workers_v1_worker_proto_depIdxs = []int32{
2, // 0: controller.api.resources.workers.v1.WorkerProvidedConfiguration.tags:type_name -> controller.api.resources.workers.v1.WorkerProvidedConfiguration.TagsEntry
5, // 1: controller.api.resources.workers.v1.Worker.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
6, // 2: controller.api.resources.workers.v1.Worker.name:type_name -> google.protobuf.StringValue
6, // 3: controller.api.resources.workers.v1.Worker.description:type_name -> google.protobuf.StringValue
7, // 4: controller.api.resources.workers.v1.Worker.created_time:type_name -> google.protobuf.Timestamp
7, // 5: controller.api.resources.workers.v1.Worker.updated_time:type_name -> google.protobuf.Timestamp
6, // 6: controller.api.resources.workers.v1.Worker.address:type_name -> google.protobuf.StringValue
3, // 7: controller.api.resources.workers.v1.Worker.tags:type_name -> controller.api.resources.workers.v1.Worker.TagsEntry
4, // 8: controller.api.resources.workers.v1.Worker.canonical_tags:type_name -> controller.api.resources.workers.v1.Worker.CanonicalTagsEntry
7, // 9: controller.api.resources.workers.v1.Worker.last_status_time:type_name -> google.protobuf.Timestamp
0, // 10: controller.api.resources.workers.v1.Worker.worker_provided_configuration:type_name -> controller.api.resources.workers.v1.WorkerProvidedConfiguration
6, // 11: controller.api.resources.workers.v1.Worker.worker_generated_auth_token:type_name -> google.protobuf.StringValue
8, // 12: controller.api.resources.workers.v1.Worker.active_connection_count:type_name -> google.protobuf.UInt32Value
9, // 13: controller.api.resources.workers.v1.WorkerProvidedConfiguration.TagsEntry.value:type_name -> google.protobuf.ListValue
9, // 14: controller.api.resources.workers.v1.Worker.TagsEntry.value:type_name -> google.protobuf.ListValue
9, // 15: controller.api.resources.workers.v1.Worker.CanonicalTagsEntry.value:type_name -> google.protobuf.ListValue
16, // [16:16] is the sub-list for method output_type
16, // [16:16] is the sub-list for method input_type
16, // [16:16] is the sub-list for extension type_name
16, // [16:16] is the sub-list for extension extendee
0, // [0:16] is the sub-list for field type_name
3, // 0: controller.api.resources.workers.v1.Worker.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
4, // 1: controller.api.resources.workers.v1.Worker.name:type_name -> google.protobuf.StringValue
4, // 2: controller.api.resources.workers.v1.Worker.description:type_name -> google.protobuf.StringValue
5, // 3: controller.api.resources.workers.v1.Worker.created_time:type_name -> google.protobuf.Timestamp
5, // 4: controller.api.resources.workers.v1.Worker.updated_time:type_name -> google.protobuf.Timestamp
1, // 5: controller.api.resources.workers.v1.Worker.canonical_tags:type_name -> controller.api.resources.workers.v1.Worker.CanonicalTagsEntry
2, // 6: controller.api.resources.workers.v1.Worker.config_tags:type_name -> controller.api.resources.workers.v1.Worker.ConfigTagsEntry
5, // 7: controller.api.resources.workers.v1.Worker.last_status_time:type_name -> google.protobuf.Timestamp
4, // 8: controller.api.resources.workers.v1.Worker.worker_generated_auth_token:type_name -> google.protobuf.StringValue
6, // 9: controller.api.resources.workers.v1.Worker.active_connection_count:type_name -> google.protobuf.UInt32Value
7, // 10: controller.api.resources.workers.v1.Worker.CanonicalTagsEntry.value:type_name -> google.protobuf.ListValue
7, // 11: controller.api.resources.workers.v1.Worker.ConfigTagsEntry.value:type_name -> google.protobuf.ListValue
12, // [12:12] is the sub-list for method output_type
12, // [12:12] is the sub-list for method input_type
12, // [12:12] is the sub-list for extension type_name
12, // [12:12] is the sub-list for extension extendee
0, // [0:12] is the sub-list for field type_name
}
func init() { file_controller_api_resources_workers_v1_worker_proto_init() }
@@ -481,18 +372,6 @@ func file_controller_api_resources_workers_v1_worker_proto_init() {
}
if !protoimpl.UnsafeEnabled {
file_controller_api_resources_workers_v1_worker_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WorkerProvidedConfiguration); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_controller_api_resources_workers_v1_worker_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Worker); i {
case 0:
return &v.state
@@ -511,7 +390,7 @@ func file_controller_api_resources_workers_v1_worker_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_controller_api_resources_workers_v1_worker_proto_rawDesc,
NumEnums: 0,
NumMessages: 5,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
@@ -22,7 +22,6 @@ import (
"github.com/hashicorp/boundary/internal/session"
"github.com/hashicorp/boundary/internal/target"
"github.com/hashicorp/boundary/internal/target/tcp"
"github.com/hashicorp/boundary/internal/types/scope"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require"
"golang.org/x/sync/errgroup"
@@ -130,11 +129,7 @@ func TestGenerateSessionBenchmarkTemplateDumps(t *testing.T) {
require.NoError(err)
connRepo, err := session.NewConnectionRepository(ctx, rw, rw, kms)
require.NoError(err)
serversRepo, err := servers.NewRepository(rw, rw, kms)
require.NoError(err)
_, err = serversRepo.UpsertWorkerStatus(ctx, servers.NewWorkerForStatus(scope.Global.String(),
servers.WithAddress("127.0.0.1")))
require.NoError(err)
_ = servers.TestKmsWorker(t, conn, wrap)
usersStart := time.Now()
t.Logf("Populating %d users", scenario.users)