diff --git a/internal/cmd/commands/dev/dev.go b/internal/cmd/commands/dev/dev.go index b6de8cd7c..f8b2fad60 100644 --- a/internal/cmd/commands/dev/dev.go +++ b/internal/cmd/commands/dev/dev.go @@ -10,6 +10,7 @@ import ( "runtime" "strings" "syscall" + "time" "github.com/hashicorp/boundary/internal/auth/oidc" "github.com/hashicorp/boundary/internal/auth/password" @@ -556,6 +557,7 @@ func (c *Command) Run(args []string) int { var opts []base.Option if c.flagCreateLoopbackHostCatalogPlugin { opts = append(opts, base.WithHostPlugin("pl_1234567890", plugin.NewWrappingPluginClient(plugin.NewLoopbackPlugin()))) + c.Config.Controller.SchedulerRunJobInterval = 100 * time.Millisecond } switch c.flagDatabaseUrl { case "": diff --git a/internal/cmd/commands/hostscmd/funcs.go b/internal/cmd/commands/hostscmd/funcs.go index ed6c292d9..95c61b5cb 100644 --- a/internal/cmd/commands/hostscmd/funcs.go +++ b/internal/cmd/commands/hostscmd/funcs.go @@ -56,7 +56,7 @@ func (c *Command) extraHelpFunc(helpMap map[string]func() string) string { func (c *Command) printListTable(items []*hosts.Host) string { if len(items) == 0 { - return "No host sets found" + return "No hosts found" } var output []string diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go index 86360a124..59a3bb1b5 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service.go @@ -23,6 +23,7 @@ import ( "github.com/hashicorp/boundary/internal/types/action" "github.com/hashicorp/boundary/internal/types/resource" "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/internal/types/subtypes" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins" "google.golang.org/grpc/codes" @@ -50,13 +51,16 @@ var ( action.List, } - collectionTypeMap = map[string]map[resource.Type]action.ActionSet{ - "static": { + collectionTypeMap = map[subtypes.Subtype]map[resource.Type]action.ActionSet{ + static.Subtype: { resource.HostSet: host_sets.CollectionActions, resource.Host: hosts.CollectionActions, }, - "plugin": { + plugin.Subtype: { resource.HostSet: host_sets.CollectionActions, + resource.Host: action.ActionSet{ + action.List, + }, }, } ) @@ -160,15 +164,15 @@ func (s Service) ListHostCatalogs(ctx context.Context, req *pbs.ListHostCatalogs outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authorizedActions)) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { - var collType string + var subtype subtypes.Subtype switch item.(type) { case *static.HostCatalog: - collType = "static" + subtype = static.Subtype case *plugin.HostCatalog: - collType = "plugin" + subtype = plugin.Subtype } - if collType != "" { - collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[collType], authResults.Scope.Id, item.GetPublicId()) + if subtype != "" { + collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, item.GetPublicId()) if err != nil { return nil, err } @@ -224,15 +228,15 @@ func (s Service) GetHostCatalog(ctx context.Context, req *pbs.GetHostCatalogRequ outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hc.GetPublicId(), IdActions).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { - var collType string + var subtype subtypes.Subtype switch hc.(type) { case *static.HostCatalog: - collType = "static" + subtype = static.Subtype case *plugin.HostCatalog: - collType = "plugin" + subtype = plugin.Subtype } - if collType != "" { - collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[collType], authResults.Scope.Id, hc.GetPublicId()) + if subtype != "" { + collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, hc.GetPublicId()) if err != nil { return nil, err } @@ -281,15 +285,15 @@ func (s Service) CreateHostCatalog(ctx context.Context, req *pbs.CreateHostCatal outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hc.GetPublicId(), IdActions).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { - var collType string + var subtype subtypes.Subtype switch hc.(type) { case *static.HostCatalog: - collType = "static" + subtype = static.Subtype case *plugin.HostCatalog: - collType = "plugin" + subtype = plugin.Subtype } - if collType != "" { - collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[collType], authResults.Scope.Id, hc.GetPublicId()) + if subtype != "" { + collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, hc.GetPublicId()) if err != nil { return nil, err } @@ -341,7 +345,7 @@ func (s Service) UpdateHostCatalog(ctx context.Context, req *pbs.UpdateHostCatal outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hc.GetPublicId(), IdActions).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { - collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap["static"], authResults.Scope.Id, hc.GetPublicId()) + collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[static.Subtype], authResults.Scope.Id, hc.GetPublicId()) if err != nil { return nil, err } diff --git a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go index 8574272ff..9e8193ed2 100644 --- a/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go +++ b/internal/servers/controller/handlers/host_catalogs/host_catalog_service_test.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/hashicorp/boundary/internal/servers/controller/handlers/host_catalogs" "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/internal/types/subtypes" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins" scopepb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes" @@ -37,8 +38,8 @@ import ( "github.com/stretchr/testify/require" ) -var authorizedCollectionActions = map[string]map[string]*structpb.ListValue{ - "static": { +var authorizedCollectionActions = map[subtypes.Subtype]map[string]*structpb.ListValue{ + static.Subtype: { "host-sets": { Values: []*structpb.Value{ structpb.NewStringValue("create"), @@ -52,13 +53,18 @@ var authorizedCollectionActions = map[string]map[string]*structpb.ListValue{ }, }, }, - "plugin": { + plugin.Subtype: { "host-sets": { Values: []*structpb.Value{ structpb.NewStringValue("create"), structpb.NewStringValue("list"), }, }, + "hosts": { + Values: []*structpb.Value{ + structpb.NewStringValue("list"), + }, + }, }, } @@ -98,7 +104,7 @@ func TestGet_Static(t *testing.T) { UpdatedTime: hc.UpdateTime.GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], } cases := []struct { @@ -200,7 +206,7 @@ func TestGet_Plugin(t *testing.T) { UpdatedTime: hc.UpdateTime.GetTimestamp(), Type: plugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["plugin"], + AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], } cases := []struct { @@ -291,7 +297,7 @@ func TestList(t *testing.T) { Version: 1, Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }) } @@ -315,7 +321,7 @@ func TestList(t *testing.T) { Version: 1, Type: plugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["plugin"], + AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], } wantSomeCatalogs = append(wantSomeCatalogs, cat) testPluginCatalogs = append(testPluginCatalogs, cat) @@ -332,7 +338,7 @@ func TestList(t *testing.T) { Version: 1, Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }) } @@ -355,7 +361,7 @@ func TestList(t *testing.T) { Version: 1, Type: plugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["plugin"], + AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], }) } @@ -685,7 +691,7 @@ func TestCreate_Static(t *testing.T) { Description: &wrappers.StringValue{Value: "desc"}, Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -853,7 +859,7 @@ func TestCreate_Plugin(t *testing.T) { Description: &wrappers.StringValue{Value: "desc"}, Type: plugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["plugin"], + AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], }, }, }, @@ -1041,7 +1047,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -1067,7 +1073,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -1122,7 +1128,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -1145,7 +1151,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -1170,7 +1176,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, @@ -1195,7 +1201,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hc.GetCreateTime().GetTimestamp(), Type: "static", AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions["static"], + AuthorizedCollectionActions: authorizedCollectionActions[static.Subtype], }, }, }, diff --git a/internal/servers/controller/handlers/host_sets/host_set_service.go b/internal/servers/controller/handlers/host_sets/host_set_service.go index a56a569ec..4d44777e5 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/hashicorp/boundary/internal/types/action" "github.com/hashicorp/boundary/internal/types/resource" + "github.com/hashicorp/boundary/internal/types/subtypes" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins" "github.com/hashicorp/go-secure-stdlib/strutil" @@ -35,14 +36,22 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources - IdActions = action.ActionSet{ - action.NoOp, - action.Read, - action.Update, - action.Delete, - action.AddHosts, - action.SetHosts, - action.RemoveHosts, + idActionsTypeMap = map[subtypes.Subtype]action.ActionSet{ + static.Subtype: action.ActionSet{ + action.NoOp, + action.Read, + action.Update, + action.Delete, + action.AddHosts, + action.SetHosts, + action.RemoveHosts, + }, + plugin.Subtype: action.ActionSet{ + action.NoOp, + action.Read, + action.Update, + action.Delete, + }, } // CollectionActions contains the set of actions that can be performed on @@ -115,7 +124,8 @@ func (s Service) ListHostSetsWithOptions(ctx context.Context, req *pbs.ListHostS } for _, item := range hl { res.Id = item.GetPublicId() - authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), IdActions, auth.WithResource(&res)).Strings() + idActions := idActionsTypeMap[host.SubtypeFromId(res.Id)] + authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), idActions, auth.WithResource(&res)).Strings() if len(authorizedActions) == 0 { continue } @@ -172,7 +182,8 @@ func (s Service) GetHostSet(ctx context.Context, req *pbs.GetHostSetRequest) (*p outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } if plg != nil { outputOpts = append(outputOpts, handlers.WithPlugin(plg)) @@ -213,7 +224,8 @@ func (s Service) CreateHostSet(ctx context.Context, req *pbs.CreateHostSetReques outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetItem().GetHostCatalogId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } if plg != nil { outputOpts = append(outputOpts, handlers.WithPlugin(plg)) @@ -257,7 +269,8 @@ func (s Service) UpdateHostSet(ctx context.Context, req *pbs.UpdateHostSetReques outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, hs, hosts, outputOpts...) @@ -311,7 +324,8 @@ func (s Service) AddHostSetHosts(ctx context.Context, req *pbs.AddHostSetHostsRe outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, hs, hosts, outputOpts...) @@ -348,7 +362,8 @@ func (s Service) SetHostSetHosts(ctx context.Context, req *pbs.SetHostSetHostsRe outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, hs, hosts, outputOpts...) @@ -386,7 +401,8 @@ func (s Service) RemoveHostSetHosts(ctx context.Context, req *pbs.RemoveHostSetH outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, hs.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, hs, hosts, outputOpts...) diff --git a/internal/servers/controller/handlers/host_sets/host_set_service_test.go b/internal/servers/controller/handlers/host_sets/host_set_service_test.go index b7c36ecdc..7fac8c530 100644 --- a/internal/servers/controller/handlers/host_sets/host_set_service_test.go +++ b/internal/servers/controller/handlers/host_sets/host_set_service_test.go @@ -23,6 +23,7 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/hashicorp/boundary/internal/servers/controller/handlers/host_sets" "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/internal/types/subtypes" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes" @@ -38,7 +39,10 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"} +var testAuthorizedActions = map[subtypes.Subtype][]string{ + static.Subtype: {"no-op", "read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + plugin.Subtype: {"no-op", "read", "update", "delete"}, +} func TestGet_Static(t *testing.T) { t.Parallel() @@ -78,7 +82,7 @@ func TestGet_Static(t *testing.T) { Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], } cases := []struct { @@ -181,7 +185,7 @@ func TestGet_Plugin(t *testing.T) { Description: plg.GetDescription(), }, PreferredEndpoints: prefEndpoints, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], } cases := []struct { @@ -272,7 +276,7 @@ func TestList_Static(t *testing.T) { UpdatedTime: h.GetUpdateTime().GetTimestamp(), Version: h.GetVersion(), Type: static.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }) } @@ -383,7 +387,7 @@ func TestList_Plugin(t *testing.T) { UpdatedTime: h.GetUpdateTime().GetTimestamp(), Version: h.GetVersion(), Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], PreferredEndpoints: preferredEndpoints, }) } @@ -683,7 +687,7 @@ func TestCreate_Static(t *testing.T) { Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, Type: "static", - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -712,7 +716,7 @@ func TestCreate_Static(t *testing.T) { Name: &wrappers.StringValue{Value: "no type name"}, Description: &wrappers.StringValue{Value: "no type desc"}, Type: "static", - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -864,7 +868,7 @@ func TestCreate_Plugin(t *testing.T) { Name: &wrappers.StringValue{Value: "No Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], }, }, }, @@ -890,7 +894,7 @@ func TestCreate_Plugin(t *testing.T) { Name: &wrappers.StringValue{Value: "With Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], Attributes: testAttrs, }, }, @@ -918,7 +922,7 @@ func TestCreate_Plugin(t *testing.T) { Description: &wrappers.StringValue{Value: "desc"}, Type: plugin.Subtype.String(), PreferredEndpoints: prefEndpoints, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], }, }, }, @@ -963,7 +967,7 @@ func TestCreate_Plugin(t *testing.T) { Name: &wrappers.StringValue{Value: "no type name"}, Description: &wrappers.StringValue{Value: "no type desc"}, Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], }, }, }, @@ -1114,7 +1118,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1140,7 +1144,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1209,7 +1213,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1232,7 +1236,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1257,7 +1261,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1282,7 +1286,7 @@ func TestUpdate(t *testing.T) { CreatedTime: hs.GetCreateTime().GetTimestamp(), Type: "static", HostIds: hIds, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, diff --git a/internal/servers/controller/handlers/hosts/host_service.go b/internal/servers/controller/handlers/hosts/host_service.go index e62cfffc7..70ea91358 100644 --- a/internal/servers/controller/handlers/hosts/host_service.go +++ b/internal/servers/controller/handlers/hosts/host_service.go @@ -33,11 +33,17 @@ var ( // IdActions contains the set of actions that can be performed on // individual resources - IdActions = action.ActionSet{ - action.NoOp, - action.Read, - action.Update, - action.Delete, + idActionsTypeMap = map[subtypes.Subtype]action.ActionSet{ + static.Subtype: { + action.NoOp, + action.Read, + action.Update, + action.Delete, + }, + plugin.Subtype: { + action.NoOp, + action.Read, + }, } // CollectionActions contains the set of actions that can be performed on @@ -106,7 +112,8 @@ func (s Service) ListHosts(ctx context.Context, req *pbs.ListHostsRequest) (*pbs } for _, item := range hl { res.Id = item.GetPublicId() - authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), IdActions, auth.WithResource(&res)).Strings() + idActions := idActionsTypeMap[host.SubtypeFromId(res.Id)] + authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), idActions, auth.WithResource(&res)).Strings() if len(authorizedActions) == 0 { continue } @@ -171,7 +178,8 @@ func (s Service) GetHost(ctx context.Context, req *pbs.GetHostRequest) (*pbs.Get outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), idActions).Strings())) } var hostSetIds []string @@ -214,7 +222,8 @@ func (s Service) CreateHost(ctx context.Context, req *pbs.CreateHostRequest) (*p outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetItem().GetHostCatalogId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, h, nil, outputOpts...) @@ -255,7 +264,8 @@ func (s Service) UpdateHost(ctx context.Context, req *pbs.UpdateHostRequest) (*p outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), IdActions).Strings())) + idActions := idActionsTypeMap[host.SubtypeFromId(req.GetId())] + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, h.GetPublicId(), idActions).Strings())) } item, err := toProto(ctx, h, nil, outputOpts...) diff --git a/internal/servers/controller/handlers/hosts/host_service_test.go b/internal/servers/controller/handlers/hosts/host_service_test.go index 61b7d58fd..93dbe0d2d 100644 --- a/internal/servers/controller/handlers/hosts/host_service_test.go +++ b/internal/servers/controller/handlers/hosts/host_service_test.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/hashicorp/boundary/internal/servers/controller/handlers/hosts" "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/internal/types/subtypes" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hosts" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins" "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes" @@ -37,7 +38,10 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -var testAuthorizedActions = []string{"no-op", "read", "update", "delete"} +var testAuthorizedActions = map[subtypes.Subtype][]string{ + static.Subtype: {"no-op", "read", "update", "delete"}, + plugin.Subtype: {"no-op", "read"}, +} func TestGet_Static(t *testing.T) { t.Parallel() @@ -73,7 +77,7 @@ func TestGet_Static(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue(h.GetAddress()), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], } cases := []struct { @@ -158,19 +162,19 @@ func TestGet_Plugin(t *testing.T) { plugin.TestSetMembers(t, conn, hs.GetPublicId(), []*plugin.Host{h}) pHost := &pb.Host{ - HostCatalogId: hc.GetPublicId(), - Id: h.GetPublicId(), - CreatedTime: h.CreateTime.GetTimestamp(), - UpdatedTime: h.UpdateTime.GetTimestamp(), - Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, - Type: plugin.Subtype.String(), + HostCatalogId: hc.GetPublicId(), + Id: h.GetPublicId(), + CreatedTime: h.CreateTime.GetTimestamp(), + UpdatedTime: h.UpdateTime.GetTimestamp(), + Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, + Type: plugin.Subtype.String(), Plugin: &plugins.PluginInfo{ Id: plg.GetPublicId(), Name: plg.GetName(), Description: plg.GetDescription(), }, - HostSetIds: []string{hs.GetPublicId()}, - AuthorizedActions: testAuthorizedActions, + HostSetIds: []string{hs.GetPublicId()}, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], } cases := []struct { @@ -260,7 +264,7 @@ func TestList_Static(t *testing.T) { Type: static.Subtype.String(), Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue(h.GetAddress()), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }) } @@ -358,8 +362,8 @@ func TestList_Plugin(t *testing.T) { h := plugin.TestHost(t, conn, hc.GetPublicId(), fmt.Sprintf("host %d", i)) plugin.TestSetMembers(t, conn, hs.GetPublicId(), []*plugin.Host{h}) wantHs = append(wantHs, &pb.Host{ - Id: h.GetPublicId(), - HostCatalogId: h.GetCatalogId(), + Id: h.GetPublicId(), + HostCatalogId: h.GetCatalogId(), Plugin: &plugins.PluginInfo{ Id: plg.GetPublicId(), Name: plg.GetName(), @@ -368,10 +372,10 @@ func TestList_Plugin(t *testing.T) { Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, CreatedTime: h.GetCreateTime().GetTimestamp(), UpdatedTime: h.GetUpdateTime().GetTimestamp(), - HostSetIds: []string{hs.GetPublicId()}, + HostSetIds: []string{hs.GetPublicId()}, Version: 1, Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[plugin.Subtype], }) } sort.Slice(wantHs, func(i, j int) bool { @@ -620,7 +624,7 @@ func TestCreate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("123.456.789"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -687,7 +691,7 @@ func TestCreate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("123.456.789"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -829,7 +833,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -857,7 +861,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -927,7 +931,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -952,7 +956,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -979,7 +983,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, }, @@ -1006,7 +1010,7 @@ func TestUpdate(t *testing.T) { Attributes: &structpb.Struct{Fields: map[string]*structpb.Value{ "address": structpb.NewStringValue("defaultaddress"), }}, - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedActions[static.Subtype], }, }, },