diff --git a/Makefile b/Makefile index ec96a5b4e..5c7931da3 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,6 @@ protobuild: @protoc-go-inject-tag -input=./internal/host/store/host.pb.go @protoc-go-inject-tag -input=./internal/host/static/store/static.pb.go @protoc-go-inject-tag -input=./internal/host/plugin/store/host.pb.go - @protoc-go-inject-tag -input=./internal/plugin/host/store/plugin.pb.go @protoc-go-inject-tag -input=./internal/plugin/store/plugin.pb.go @protoc-go-inject-tag -input=./internal/authtoken/store/authtoken.pb.go @protoc-go-inject-tag -input=./internal/auth/store/account.pb.go @@ -194,6 +193,7 @@ protobuild: @protoc-go-inject-tag -input=./internal/kms/store/audit_key.pb.go @protoc-go-inject-tag -input=./internal/auth/ldap/store/ldap.pb.go @protoc-go-inject-tag -input=./internal/gen/controller/servers/services/upstream_message_service.pb.go + @protoc-go-inject-tag -input=./internal/storage/plugin/store/storage.pb.go # inject classification tags (see: https://github.com/hashicorp/go-eventlogger/tree/main/filters/encrypt) @protoc-go-inject-tag -input=./internal/gen/controller/api/services/auth_method_service.pb.go diff --git a/globals/prefixes.go b/globals/prefixes.go index fab266f1b..2fc53f1d5 100644 --- a/globals/prefixes.go +++ b/globals/prefixes.go @@ -111,6 +111,9 @@ const ( // WorkerPrefix is the prefix for workers WorkerPrefix = "w" + + // PluginStorageBucketPrefix is the prefix for plugin storage buckets + PluginStorageBucketPrefix = "sb" ) var prefixToResourceType = map[string]resource.Type{ diff --git a/internal/cmd/base/initial_resources.go b/internal/cmd/base/initial_resources.go index aa09fc44c..87291b6e6 100644 --- a/internal/cmd/base/initial_resources.go +++ b/internal/cmd/base/initial_resources.go @@ -11,13 +11,15 @@ import ( "github.com/hashicorp/boundary/globals" "github.com/hashicorp/boundary/internal/auth/password" "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/target" "github.com/hashicorp/boundary/internal/target/tcp" "github.com/hashicorp/boundary/internal/types/scope" + "github.com/hashicorp/boundary/internal/util" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" "github.com/hashicorp/go-secure-stdlib/base62" ) @@ -550,52 +552,77 @@ func (b *Server) CreateInitialTargetWithHostSources(ctx context.Context) (target return tt, nil } -// RegisterHostPlugin creates a host plugin in the database if not present. -// It also registers the plugin in the shared map of running plugins. Since -// all boundary provided host plugins must have a name, a name is required -// when calling RegisterHostPlugin and will be used even if WithName is provided. -func (b *Server) RegisterHostPlugin(ctx context.Context, name string, plg plgpb.HostPluginServiceClient, opt ...hostplugin.Option) (*hostplugin.Plugin, error) { - if name == "" { - return nil, fmt.Errorf("no name provided when creating plugin.") +// RegisterPlugin creates a plugin in the database if not present, and flags +// the plugin type based on the flags parameter. If the PluginTypeHost flag is +// set, it also registers the plugin in the shared map of running plugins. +// Since all boundary provided plugins must have a name, a name is required +// when calling RegisterPlugin and will be used even if WithName is provided. +// hostClient must not be nil when host flag is included. +func (b *Server) RegisterPlugin(ctx context.Context, name string, hostClient plgpb.HostPluginServiceClient, flags []plugin.PluginType, opt ...plugin.Option) (*plugin.Plugin, error) { + const op = "base.(Server).RegisterPlugin" + switch { + case len(flags) == 0: + return nil, errors.New(ctx, errors.InvalidParameter, op, "plugins must be initialized with at least one plugin type") + case name == "": + return nil, errors.New(ctx, errors.InvalidParameter, op, "no name provided when creating plugin") } + rw := db.New(b.Database) - kmsCache, err := kms.New(ctx, rw, rw) - if err != nil { - return nil, fmt.Errorf("error creating kms cache: %w", err) + if b.Kms == nil { + var err error + if b.Kms, err = kms.New(ctx, rw, rw); err != nil { + return nil, fmt.Errorf("error creating kms cache: %w", err) + } } - if err := kmsCache.AddExternalWrappers( + if err := b.Kms.AddExternalWrappers( ctx, kms.WithRootWrapper(b.RootKms), ); err != nil { return nil, fmt.Errorf("error adding config keys to kms: %w", err) } - hpRepo, err := hostplugin.NewRepository(rw, rw, kmsCache) + hpRepo, err := plugin.NewRepository(ctx, rw, rw, b.Kms) if err != nil { - return nil, fmt.Errorf("error creating host plugin repository: %w", err) + return nil, fmt.Errorf("error creating plugin repository: %w", err) } - plugin, err := hpRepo.LookupPluginByName(ctx, name) + plg, err := hpRepo.LookupPluginByName(ctx, name) if err != nil { - return nil, fmt.Errorf("error looking up host plugin by name: %w", err) + return nil, fmt.Errorf("error looking up plugin by name: %w", err) } - if plugin == nil { - opt = append(opt, hostplugin.WithName(name)) - plugin = hostplugin.NewPlugin(opt...) - plugin, err = hpRepo.CreatePlugin(ctx, plugin, opt...) + if plg == nil { + opt = append(opt, plugin.WithName(name)) + plg = plugin.NewPlugin(opt...) + plg, err = hpRepo.CreatePlugin(ctx, plg, opt...) if err != nil { - return nil, fmt.Errorf("error creating host plugin: %w", err) + return nil, fmt.Errorf("error creating plugin: %w", err) } } - if b.HostPlugins == nil { - b.HostPlugins = make(map[string]plgpb.HostPluginServiceClient) + // TODO: support flags should be moved to the create/update repo calls before plugins are exposed to users + for _, flag := range flags { + switch flag { + case plugin.PluginTypeHost: + if util.IsNil(hostClient) { + return nil, errors.New(ctx, errors.InvalidParameter, op, "no host client provided when initializing host plugin") + } + if err := hpRepo.AddSupportFlag(ctx, plg, plugin.PluginTypeHost); err != nil { + return nil, err + } + if b.HostPlugins == nil { + b.HostPlugins = make(map[string]plgpb.HostPluginServiceClient) + } + b.HostPlugins[plg.GetPublicId()] = hostClient + case plugin.PluginTypeStorage: + if err := hpRepo.AddSupportFlag(ctx, plg, plugin.PluginTypeStorage); err != nil { + return nil, err + } + } } - b.HostPlugins[plugin.GetPublicId()] = plg - return plugin, nil + return plg, nil } // unprivilegedDevUserRoleSetup adds dev user to the role that grants diff --git a/internal/daemon/controller/common/common.go b/internal/daemon/controller/common/common.go index 66b62dcb6..5d422e4ad 100644 --- a/internal/daemon/controller/common/common.go +++ b/internal/daemon/controller/common/common.go @@ -12,7 +12,7 @@ import ( pluginhost "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/server" "github.com/hashicorp/boundary/internal/session" ) @@ -28,7 +28,7 @@ type ( ServersRepoFactory func() (*server.Repository, error) StaticRepoFactory func() (*static.Repository, error) PluginHostRepoFactory func() (*pluginhost.Repository, error) - HostPluginRepoFactory func() (*hostplugin.Repository, error) + HostPluginRepoFactory func() (*plugin.Repository, error) ConnectionRepoFactory func() (*session.ConnectionRepository, error) WorkerAuthRepoStorageFactory func() (*server.WorkerAuthRepositoryStorage, error) ) diff --git a/internal/daemon/controller/controller.go b/internal/daemon/controller/controller.go index 27d562a9c..a71a99f5e 100644 --- a/internal/daemon/controller/controller.go +++ b/internal/daemon/controller/controller.go @@ -33,7 +33,7 @@ import ( "github.com/hashicorp/boundary/internal/kms" kmsjob "github.com/hashicorp/boundary/internal/kms/job" "github.com/hashicorp/boundary/internal/observability/event" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/scheduler/cleaner" @@ -44,7 +44,7 @@ import ( "github.com/hashicorp/boundary/internal/target" "github.com/hashicorp/boundary/internal/types/scope" host_plugin_assets "github.com/hashicorp/boundary/plugins/host" - "github.com/hashicorp/boundary/sdk/pbs/plugin" + plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" external_plugins "github.com/hashicorp/boundary/sdk/plugins" "github.com/hashicorp/boundary/version" "github.com/hashicorp/go-hclog" @@ -257,15 +257,15 @@ func New(ctx context.Context, conf *Config) (*Controller, error) { return nil, fmt.Errorf("error creating loopback plugin: %w", err) } plg := loopback.NewWrappingPluginHostClient(lp) - opts := []host.Option{ - host.WithDescription("Provides an initial loopback storage and host plugin in Boundary"), - host.WithPublicId(conf.DevLoopbackPluginId), + opts := []plugin.Option{ + plugin.WithDescription("Provides an initial loopback storage and host plugin in Boundary"), + plugin.WithPublicId(conf.DevLoopbackPluginId), } // TODO(storage): Register loopback as storage supported - if _, err = conf.RegisterHostPlugin(ctx, "loopback", plg, opts...); err != nil { + if _, err = conf.RegisterPlugin(ctx, "loopback", plg, []plugin.PluginType{plugin.PluginTypeHost}, opts...); err != nil { return nil, err } - case base.EnabledPluginHostAzure, base.EnabledPluginAws: + case base.EnabledPluginHostAzure: pluginType := strings.ToLower(enabledPlugin.String()) client, cleanup, err := external_plugins.CreateHostPlugin( ctx, @@ -280,14 +280,32 @@ func New(ctx context.Context, conf *Config) (*Controller, error) { return nil, fmt.Errorf("error creating %s host plugin: %w", pluginType, err) } conf.ShutdownFuncs = append(conf.ShutdownFuncs, cleanup) - if _, err := conf.RegisterHostPlugin(ctx, pluginType, client, host.WithDescription(fmt.Sprintf("Built-in %s host plugin", enabledPlugin.String()))); err != nil { + if _, err := conf.RegisterPlugin(ctx, pluginType, client, []plugin.PluginType{plugin.PluginTypeHost}, plugin.WithDescription(fmt.Sprintf("Built-in %s host plugin", enabledPlugin.String()))); err != nil { + return nil, fmt.Errorf("error registering %s host plugin: %w", pluginType, err) + } + case base.EnabledPluginAws: + pluginType := strings.ToLower(enabledPlugin.String()) + client, cleanup, err := external_plugins.CreateHostPlugin( + ctx, + pluginType, + external_plugins.WithPluginOptions( + pluginutil.WithPluginExecutionDirectory(conf.RawConfig.Plugins.ExecutionDir), + pluginutil.WithPluginsFilesystem(host_plugin_assets.HostPluginPrefix, host_plugin_assets.FileSystem()), + ), + external_plugins.WithLogger(pluginLogger.Named(pluginType)), + ) + if err != nil { + return nil, fmt.Errorf("error creating %s host plugin: %w", pluginType, err) + } + conf.ShutdownFuncs = append(conf.ShutdownFuncs, cleanup) + if _, err := conf.RegisterPlugin(ctx, pluginType, client, []plugin.PluginType{plugin.PluginTypeHost, plugin.PluginTypeStorage}, plugin.WithDescription(fmt.Sprintf("Built-in %s host plugin", enabledPlugin.String()))); err != nil { return nil, fmt.Errorf("error registering %s host plugin: %w", pluginType, err) } } } if conf.HostPlugins == nil { - conf.HostPlugins = make(map[string]plugin.HostPluginServiceClient) + conf.HostPlugins = make(map[string]plgpb.HostPluginServiceClient) } // Set up repo stuff @@ -358,8 +376,8 @@ func New(ctx context.Context, conf *Config) (*Controller, error) { c.PluginHostRepoFn = func() (*pluginhost.Repository, error) { return pluginhost.NewRepository(dbase, dbase, c.kms, c.scheduler, c.conf.HostPlugins) } - c.HostPluginRepoFn = func() (*host.Repository, error) { - return host.NewRepository(dbase, dbase, c.kms) + c.HostPluginRepoFn = func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, dbase, dbase, c.kms) } c.AuthTokenRepoFn = func() (*authtoken.Repository, error) { return authtoken.NewRepository(dbase, dbase, c.kms, diff --git a/internal/daemon/controller/handlers/host_catalogs/host_catalog_service.go b/internal/daemon/controller/handlers/host_catalogs/host_catalog_service.go index 298f80452..f663a7d3a 100644 --- a/internal/daemon/controller/handlers/host_catalogs/host_catalog_service.go +++ b/internal/daemon/controller/handlers/host_catalogs/host_catalog_service.go @@ -17,12 +17,12 @@ import ( "github.com/hashicorp/boundary/internal/errors" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/host" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" pluginstore "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/host/static/store" "github.com/hashicorp/boundary/internal/perms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/types/action" "github.com/hashicorp/boundary/internal/types/resource" @@ -62,7 +62,7 @@ var ( resource.HostSet: host_sets.CollectionActions, resource.Host: hosts.CollectionActions, }, - plugin.Subtype: { + hostplugin.Subtype: { resource.HostSet: host_sets.CollectionActions, resource.Host: action.ActionSet{ action.List, @@ -179,8 +179,8 @@ func (s Service) ListHostCatalogs(ctx context.Context, req *pbs.ListHostCatalogs switch item.(type) { case *static.HostCatalog: subtype = static.Subtype - case *plugin.HostCatalog: - subtype = plugin.Subtype + case *hostplugin.HostCatalog: + subtype = hostplugin.Subtype } if subtype != "" { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, item.GetPublicId()) @@ -191,7 +191,7 @@ func (s Service) ListHostCatalogs(ctx context.Context, req *pbs.ListHostCatalogs } } switch hc := item.(type) { - case *plugin.HostCatalog: + case *hostplugin.HostCatalog: if plgInfo, ok := pluginInfoMap[hc.GetPluginId()]; ok { outputOpts = append(outputOpts, handlers.WithPlugin(plgInfo)) } @@ -249,8 +249,8 @@ func (s Service) GetHostCatalog(ctx context.Context, req *pbs.GetHostCatalogRequ switch hc.(type) { case *static.HostCatalog: subtype = static.Subtype - case *plugin.HostCatalog: - subtype = plugin.Subtype + case *hostplugin.HostCatalog: + subtype = hostplugin.Subtype } if subtype != "" { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, hc.GetPublicId()) @@ -306,8 +306,8 @@ func (s Service) CreateHostCatalog(ctx context.Context, req *pbs.CreateHostCatal switch hc.(type) { case *static.HostCatalog: subtype = static.Subtype - case *plugin.HostCatalog: - subtype = plugin.Subtype + case *hostplugin.HostCatalog: + subtype = hostplugin.Subtype } if subtype != "" { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, hc.GetPublicId()) @@ -369,8 +369,8 @@ func (s Service) UpdateHostCatalog(ctx context.Context, req *pbs.UpdateHostCatal switch hc.(type) { case *static.HostCatalog: subtype = static.Subtype - case *plugin.HostCatalog: - subtype = plugin.Subtype + case *hostplugin.HostCatalog: + subtype = hostplugin.Subtype } if subtype != "" { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, collectionTypeMap[subtype], authResults.Scope.Id, hc.GetPublicId()) @@ -421,7 +421,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (host.Catalog, *plu return nil, nil, handlers.NotFoundErrorf("Host Catalog %q doesn't exist.", id) } cat = hc - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginHostRepoFn() if err != nil { return nil, nil, err @@ -491,7 +491,7 @@ func (s Service) createStaticInRepo(ctx context.Context, projId string, item *pb return out, nil } -func (s Service) createPluginInRepo(ctx context.Context, projId string, req *pbs.CreateHostCatalogRequest) (*plugin.HostCatalog, *plugins.PluginInfo, error) { +func (s Service) createPluginInRepo(ctx context.Context, projId string, req *pbs.CreateHostCatalogRequest) (*hostplugin.HostCatalog, *plugins.PluginInfo, error) { const op = "host_catalogs.(Service).createPluginInRepo" item := req.GetItem() pluginId := item.GetPluginId() @@ -564,7 +564,7 @@ func (s Service) updateStaticInRepo(ctx context.Context, projId, id string, mask return out, nil } -func (s Service) updatePluginInRepo(ctx context.Context, projId, id string, mask []string, item *pb.HostCatalog) (*plugin.HostCatalog, *plugins.PluginInfo, error) { +func (s Service) updatePluginInRepo(ctx context.Context, projId, id string, mask []string, item *pb.HostCatalog) (*hostplugin.HostCatalog, *plugins.PluginInfo, error) { const op = "host_catalogs.(Service).updatePluginInRepo" h, err := toStoragePluginCatalog(ctx, projId, "", item) if err != nil { @@ -596,7 +596,7 @@ func (s Service) updateInRepo(ctx context.Context, projId string, req *pbs.Updat switch subtypes.SubtypeFromId(domain, req.GetId()) { case static.Subtype: hc, err = s.updateStaticInRepo(ctx, projId, req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem()) - case plugin.Subtype: + case hostplugin.Subtype: hc, plg, err = s.updatePluginInRepo(ctx, projId, req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem()) } return @@ -615,7 +615,7 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) { if err != nil { return false, errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete host")) } - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginHostRepoFn() if err != nil { return false, errors.Wrap(ctx, err, op) @@ -669,7 +669,7 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth. } parentId = cat.GetProjectId() opts = append(opts, auth.WithId(id)) - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginHostRepoFn() if err != nil { res.Error = err @@ -692,7 +692,7 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth. return auth.Verify(ctx, opts...) } -func toPluginInfo(plg *hostplugin.Plugin) *plugins.PluginInfo { +func toPluginInfo(plg *plugin.Plugin) *plugins.PluginInfo { if plg == nil { return nil } @@ -722,8 +722,8 @@ func toProto(ctx context.Context, in host.Catalog, opt ...handlers.Option) (*pb. switch in.(type) { case *static.HostCatalog: out.Type = static.Subtype.String() - case *plugin.HostCatalog: - out.Type = plugin.Subtype.String() + case *hostplugin.HostCatalog: + out.Type = hostplugin.Subtype.String() } } if outputFields.Has(globals.DescriptionField) && in.GetDescription() != "" { @@ -754,7 +754,7 @@ func toProto(ctx context.Context, in host.Catalog, opt ...handlers.Option) (*pb. out.AuthorizedCollectionActions = opts.WithAuthorizedCollectionActions } switch h := in.(type) { - case *plugin.HostCatalog: + case *hostplugin.HostCatalog: if outputFields.Has(globals.PluginIdField) { out.PluginId = h.GetPluginId() } @@ -793,22 +793,22 @@ func toStorageStaticCatalog(ctx context.Context, projectId string, item *pb.Host return hc, nil } -func toStoragePluginCatalog(ctx context.Context, projectId, plgId string, item *pb.HostCatalog) (*plugin.HostCatalog, error) { +func toStoragePluginCatalog(ctx context.Context, projectId, plgId string, item *pb.HostCatalog) (*hostplugin.HostCatalog, error) { const op = "host_catalog_service.toStoragePluginCatalog" - var opts []plugin.Option + var opts []hostplugin.Option if name := item.GetName(); name != nil { - opts = append(opts, plugin.WithName(item.GetName().GetValue())) + opts = append(opts, hostplugin.WithName(item.GetName().GetValue())) } if desc := item.GetDescription(); desc != nil { - opts = append(opts, plugin.WithDescription(desc.GetValue())) + opts = append(opts, hostplugin.WithDescription(desc.GetValue())) } if attrs := item.GetAttributes(); attrs != nil { - opts = append(opts, plugin.WithAttributes(attrs)) + opts = append(opts, hostplugin.WithAttributes(attrs)) } if secrets := item.GetSecrets(); secrets != nil { - opts = append(opts, plugin.WithSecrets(secrets)) + opts = append(opts, hostplugin.WithSecrets(secrets)) } - hc, err := plugin.NewHostCatalog(ctx, projectId, plgId, opts...) + hc, err := hostplugin.NewHostCatalog(ctx, projectId, plgId, opts...) if err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to build host set for creation")) } @@ -837,7 +837,7 @@ func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error { } switch subtypes.SubtypeFromType(domain, req.GetItem().GetType()) { case static.Subtype: - case plugin.Subtype: + case hostplugin.Subtype: if req.GetItem().GetPlugin() != nil { badFields[globals.PluginField] = "This is a read only field." } @@ -850,7 +850,7 @@ func validateCreateRequest(req *pbs.CreateHostCatalogRequest) error { badFields[globals.PluginNameField] = "Can't set the plugin id field along with this field." } default: - badFields[globals.TypeField] = fmt.Sprintf("This is a required field and must be either %q or %q.", static.Subtype.String(), plugin.Subtype.String()) + badFields[globals.TypeField] = fmt.Sprintf("This is a required field and must be either %q or %q.", static.Subtype.String(), hostplugin.Subtype.String()) } return badFields }) @@ -870,8 +870,8 @@ func validateUpdateRequest(req *pbs.UpdateHostCatalogRequest) error { if req.GetItem().GetPlugin() != nil { badFields[globals.PluginField] = "This field is unused for this type of host catalog." } - case plugin.Subtype: - if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != plugin.Subtype { + case hostplugin.Subtype: + if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != hostplugin.Subtype { badFields[globals.TypeField] = "Cannot modify resource type." } if req.GetItem().GetPlugin() != nil { diff --git a/internal/daemon/controller/handlers/host_catalogs/host_catalog_service_test.go b/internal/daemon/controller/handlers/host_catalogs/host_catalog_service_test.go index 690558ab4..7b4dc044a 100644 --- a/internal/daemon/controller/handlers/host_catalogs/host_catalog_service_test.go +++ b/internal/daemon/controller/handlers/host_catalogs/host_catalog_service_test.go @@ -20,11 +20,11 @@ import ( "github.com/hashicorp/boundary/internal/daemon/controller/handlers/host_catalogs" "github.com/hashicorp/boundary/internal/db" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/types/scope" @@ -61,7 +61,7 @@ var authorizedCollectionActions = map[subtypes.Subtype]map[string]*structpb.List }, }, }, - plugin.Subtype: { + hostplugin.Subtype: { "host-sets": { Values: []*structpb.Value{ structpb.NewStringValue("create"), @@ -79,6 +79,7 @@ var authorizedCollectionActions = map[subtypes.Subtype]map[string]*structpb.List var testAuthorizedActions = []string{"no-op", "read", "update", "delete"} func TestGet_Static(t *testing.T) { + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -89,11 +90,11 @@ func TestGet_Static(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iam.TestRepo(t, conn, wrapper), nil @@ -169,6 +170,7 @@ func TestGet_Static(t *testing.T) { } func TestGet_Plugin(t *testing.T) { + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -179,19 +181,19 @@ func TestGet_Plugin(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iam.TestRepo(t, conn, wrapper), nil } name := "test" - plg := host.TestPlugin(t, conn, name) - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId(), plugin.WithSecretsHmac([]byte("foobar"))) - hcPrev := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId(), plugin.WithSecretsHmac([]byte("foobar")), plugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostCatalogPreviousPrefix))) + plg := plugin.TestPlugin(t, conn, name) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId(), hostplugin.WithSecretsHmac([]byte("foobar"))) + hcPrev := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId(), hostplugin.WithSecretsHmac([]byte("foobar")), hostplugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostCatalogPreviousPrefix))) toMerge := &pbs.GetHostCatalogRequest{ Id: hc.GetPublicId(), @@ -213,9 +215,9 @@ func TestGet_Plugin(t *testing.T) { }, CreatedTime: hc.CreateTime.GetTimestamp(), UpdatedTime: hc.UpdateTime.GetTimestamp(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], + AuthorizedCollectionActions: authorizedCollectionActions[hostplugin.Subtype], SecretsHmac: base58.Encode([]byte("foobar")), } @@ -284,6 +286,7 @@ func TestGet_Plugin(t *testing.T) { } func TestList(t *testing.T) { + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") rw := db.New(conn) wrapper := db.TestWrapper(t) @@ -292,11 +295,11 @@ func TestList(t *testing.T) { iamRepoFn := func() (*iam.Repository, error) { return iam.TestRepo(t, conn, wrapper), nil } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -324,9 +327,9 @@ func TestList(t *testing.T) { var testPluginCatalogs []*pb.HostCatalog name := "test" - plg := host.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) for i := 0; i < 3; i++ { - hc := plugin.TestCatalog(t, conn, pWithCatalogs.GetPublicId(), plg.GetPublicId()) + hc := hostplugin.TestCatalog(t, conn, pWithCatalogs.GetPublicId(), plg.GetPublicId()) cat := &pb.HostCatalog{ Id: hc.GetPublicId(), ScopeId: hc.GetProjectId(), @@ -340,9 +343,9 @@ func TestList(t *testing.T) { Description: plg.GetDescription(), }, Version: 1, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], + AuthorizedCollectionActions: authorizedCollectionActions[hostplugin.Subtype], } wantSomeCatalogs = append(wantSomeCatalogs, cat) testPluginCatalogs = append(testPluginCatalogs, cat) @@ -364,9 +367,9 @@ func TestList(t *testing.T) { } name = "different" - diffPlg := host.TestPlugin(t, conn, name) + diffPlg := plugin.TestPlugin(t, conn, name) for i := 0; i < 3; i++ { - hc := plugin.TestCatalog(t, conn, pWithOtherCatalogs.GetPublicId(), diffPlg.GetPublicId()) + hc := hostplugin.TestCatalog(t, conn, pWithOtherCatalogs.GetPublicId(), diffPlg.GetPublicId()) wantOtherCatalogs = append(wantOtherCatalogs, &pb.HostCatalog{ Id: hc.GetPublicId(), ScopeId: hc.GetProjectId(), @@ -380,9 +383,9 @@ func TestList(t *testing.T) { Description: diffPlg.GetDescription(), }, Version: 1, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], + AuthorizedCollectionActions: authorizedCollectionActions[hostplugin.Subtype], }) } @@ -488,6 +491,7 @@ func TestList(t *testing.T) { func TestDelete_Static(t *testing.T) { t.Parallel() + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -498,11 +502,11 @@ func TestDelete_Static(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -558,6 +562,7 @@ func TestDelete_Static(t *testing.T) { func TestDelete_Plugin(t *testing.T) { t.Parallel() + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -568,17 +573,17 @@ func TestDelete_Plugin(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil } - plg := host.TestPlugin(t, conn, "test") - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + plg := plugin.TestPlugin(t, conn, "test") + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) s, err := host_catalogs.NewService(repo, pluginHostRepo, pluginRepo, iamRepoFn) require.NoError(t, err, "Couldn't create a new host catalog service.") @@ -640,11 +645,11 @@ func TestDelete_twice(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(context.Background(), rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -666,6 +671,7 @@ func TestDelete_twice(t *testing.T) { func TestCreate_Static(t *testing.T) { t.Parallel() + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -676,11 +682,11 @@ func TestCreate_Static(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -818,6 +824,7 @@ func TestCreate_Static(t *testing.T) { func TestCreate_Plugin(t *testing.T) { t.Parallel() + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -828,17 +835,17 @@ func TestCreate_Plugin(t *testing.T) { repo := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil } name := "test" - plg := host.TestPlugin(t, conn, name) - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, name) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginHostServer{ OnCreateCatalogFn: func(ctx context.Context, req *plgpb.OnCreateCatalogRequest) (*plgpb.OnCreateCatalogResponse, error) { return nil, nil @@ -846,7 +853,7 @@ func TestCreate_Plugin(t *testing.T) { }), }) } - defaultHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + defaultHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) defaultHcCreated := defaultHc.GetCreateTime().GetTimestamp().AsTime() toMerge := &pbs.CreateHostCatalogRequest{} @@ -862,7 +869,7 @@ func TestCreate_Plugin(t *testing.T) { ScopeId: proj.GetPublicId(), Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, res: &pbs.CreateHostCatalogResponse{ @@ -878,9 +885,9 @@ func TestCreate_Plugin(t *testing.T) { }, Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), AuthorizedActions: testAuthorizedActions, - AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype], + AuthorizedCollectionActions: authorizedCollectionActions[hostplugin.Subtype], }, }, }, @@ -888,7 +895,7 @@ func TestCreate_Plugin(t *testing.T) { name: "Cant create in org", req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ ScopeId: org.GetParentId(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -897,7 +904,7 @@ func TestCreate_Plugin(t *testing.T) { name: "Cant create in global", req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ ScopeId: scope.Global.String(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -924,7 +931,7 @@ func TestCreate_Plugin(t *testing.T) { req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ Id: "not allowed to be set", ScopeId: proj.GetPublicId(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, res: nil, @@ -935,7 +942,7 @@ func TestCreate_Plugin(t *testing.T) { req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ CreatedTime: timestamppb.Now(), ScopeId: proj.GetPublicId(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, res: nil, @@ -946,7 +953,7 @@ func TestCreate_Plugin(t *testing.T) { req: &pbs.CreateHostCatalogRequest{Item: &pb.HostCatalog{ UpdatedTime: timestamppb.Now(), ScopeId: proj.GetPublicId(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PluginId: plg.GetPublicId(), }}, res: nil, @@ -995,6 +1002,7 @@ func TestCreate_Plugin(t *testing.T) { func TestUpdate_Static(t *testing.T) { t.Parallel() + ctx := context.Background() conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) kms := kms.TestKms(t, conn, wrapper) @@ -1005,11 +1013,11 @@ func TestUpdate_Static(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(ctx, rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -1372,7 +1380,7 @@ func TestUpdate_Plugin(t *testing.T) { rw := db.New(conn) name := "test" - plg := host.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) lp, err := loopback.NewLoopbackPlugin() require.NoError(t, err) plgm := map[string]plgpb.HostPluginServiceClient{ @@ -1382,11 +1390,11 @@ func TestUpdate_Plugin(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } - pluginRepo := func() (*host.Repository, error) { - return host.NewRepository(rw, rw, kms) + pluginRepo := func() (*plugin.Repository, error) { + return plugin.NewRepository(context.Background(), rw, rw, kms) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -1472,7 +1480,7 @@ func TestUpdate_Plugin(t *testing.T) { check: func(t *testing.T, in *pb.HostCatalog) { assert.Equal(t, "new", in.Name.GetValue()) assert.Equal(t, "desc", in.Description.GetValue()) - assert.Empty(t, cmp.Diff(authorizedCollectionActions[plugin.Subtype], in.GetAuthorizedCollectionActions(), cmpopts.IgnoreUnexported(structpb.ListValue{}, structpb.Value{}))) + assert.Empty(t, cmp.Diff(authorizedCollectionActions[hostplugin.Subtype], in.GetAuthorizedCollectionActions(), cmpopts.IgnoreUnexported(structpb.ListValue{}, structpb.Value{}))) }, }, { diff --git a/internal/daemon/controller/handlers/host_sets/host_set_service.go b/internal/daemon/controller/handlers/host_sets/host_set_service.go index b3d0fc1f5..be60ae273 100644 --- a/internal/daemon/controller/handlers/host_sets/host_set_service.go +++ b/internal/daemon/controller/handlers/host_sets/host_set_service.go @@ -14,13 +14,13 @@ import ( "github.com/hashicorp/boundary/internal/errors" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/host" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" plugstore "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/host/static" staticstore "github.com/hashicorp/boundary/internal/host/static/store" "github.com/hashicorp/boundary/internal/libs/endpoint" "github.com/hashicorp/boundary/internal/perms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/types/action" "github.com/hashicorp/boundary/internal/types/resource" @@ -49,7 +49,7 @@ var ( action.SetHosts, action.RemoveHosts, }, - plugin.Subtype: { + hostplugin.Subtype: { action.NoOp, action.Read, action.Update, @@ -72,7 +72,7 @@ func init() { if maskManager[static.Subtype], err = handlers.NewMaskManager(handlers.MaskDestination{&staticstore.HostSet{}, &staticstore.UnimplementedSetFields{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil { panic(err) } - if maskManager[plugin.Subtype], err = handlers.NewMaskManager(handlers.MaskDestination{&plugstore.HostSet{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil { + if maskManager[hostplugin.Subtype], err = handlers.NewMaskManager(handlers.MaskDestination{&plugstore.HostSet{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil { panic(err) } } @@ -94,7 +94,7 @@ func NewService(staticRepoFn common.StaticRepoFactory, pluginRepoFn common.Plugi return Service{}, errors.NewDeprecated(errors.InvalidParameter, op, "missing static repository") } if pluginRepoFn == nil { - return Service{}, errors.NewDeprecated(errors.InvalidParameter, op, "missing plugin repository") + return Service{}, errors.NewDeprecated(errors.InvalidParameter, op, "missing hostplugin repository") } return Service{staticRepoFn: staticRepoFn, pluginRepoFn: pluginRepoFn}, nil } @@ -451,7 +451,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (host.Set, []host.H hl = append(hl, h) } hs = hset - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginRepoFn() if err != nil { return nil, nil, nil, err @@ -466,7 +466,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (host.Set, []host.H hs = hset plg = toPluginInfo(hsplg) for _, h := range hset.HostIds { - hl = append(hl, &plugin.Host{ + hl = append(hl, &hostplugin.Host{ Host: &plugstore.Host{ PublicId: h, CatalogId: hset.CatalogId, @@ -502,7 +502,7 @@ func (s Service) createInRepo(ctx context.Context, projectId, catalogId string, return nil, nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create host set but no error returned from repository.") } hSet = out - case plugin.Subtype: + case hostplugin.Subtype: h, err := toStoragePluginSet(ctx, catalogId, item) if err != nil { return nil, nil, err @@ -564,7 +564,7 @@ func (s Service) updatePluginInRepo(ctx context.Context, projectId string, req * return nil, nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to build host set for update")) } h.PublicId = req.GetId() - dbMask := maskManager[plugin.Subtype].Translate(req.GetUpdateMask().GetPaths(), "attributes") + dbMask := maskManager[hostplugin.Subtype].Translate(req.GetUpdateMask().GetPaths(), "attributes") if len(dbMask) == 0 { return nil, nil, nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."}) } @@ -591,7 +591,7 @@ func (s Service) updateInRepo(ctx context.Context, projectId, catalogId string, switch subtypes.SubtypeFromId(domain, req.GetId()) { case static.Subtype: hs, hosts, err = s.updateStaticInRepo(ctx, projectId, catalogId, req) - case plugin.Subtype: + case hostplugin.Subtype: hs, hosts, plg, err = s.updatePluginInRepo(ctx, projectId, req) } return @@ -610,7 +610,7 @@ func (s Service) deleteFromRepo(ctx context.Context, projectId, id string) (bool if err != nil { return false, errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete host")) } - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginRepoFn() if err != nil { return false, err @@ -640,7 +640,7 @@ func (s Service) listFromRepo(ctx context.Context, catalogId string, opt ...host for _, a := range sl { sets = append(sets, a) } - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginRepoFn() if err != nil { return nil, nil, err @@ -763,7 +763,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return nil, res } set = ss - case plugin.Subtype: + case hostplugin.Subtype: ps, _, err := pluginRepo.LookupSet(ctx, id) if err != nil { res.Error = err @@ -792,7 +792,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return nil, res } cat = cs - case plugin.Subtype: + case hostplugin.Subtype: pc, _, err := pluginRepo.LookupCatalog(ctx, parentId) if err != nil { res.Error = err @@ -808,7 +808,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return cat, auth.Verify(ctx, opts...) } -func toPluginInfo(plg *hostplugin.Plugin) *plugins.PluginInfo { +func toPluginInfo(plg *plugin.Plugin) *plugins.PluginInfo { if plg == nil { return nil } @@ -838,8 +838,8 @@ func toProto(ctx context.Context, in host.Set, hosts []host.Host, opt ...handler switch in.(type) { case *static.HostSet: out.Type = static.Subtype.String() - case *plugin.HostSet: - out.Type = plugin.Subtype.String() + case *hostplugin.HostSet: + out.Type = hostplugin.Subtype.String() } } if outputFields.Has(globals.DescriptionField) && in.GetDescription() != "" { @@ -873,7 +873,7 @@ func toProto(ctx context.Context, in host.Set, hosts []host.Host, opt ...handler } switch h := in.(type) { - case *plugin.HostSet: + case *hostplugin.HostSet: if outputFields.Has(globals.PreferredEndpointsField) { out.PreferredEndpoints = h.PreferredEndpoints } @@ -913,25 +913,25 @@ func toStorageStaticSet(ctx context.Context, catalogId string, item *pb.HostSet) return hs, nil } -func toStoragePluginSet(ctx context.Context, catalogId string, item *pb.HostSet) (*plugin.HostSet, error) { +func toStoragePluginSet(ctx context.Context, catalogId string, item *pb.HostSet) (*hostplugin.HostSet, error) { const op = "host_set_service.toStoragePluginSet" - var opts []plugin.Option + var opts []hostplugin.Option if item.GetName() != nil { - opts = append(opts, plugin.WithName(item.GetName().GetValue())) + opts = append(opts, hostplugin.WithName(item.GetName().GetValue())) } if item.GetDescription() != nil { - opts = append(opts, plugin.WithDescription(item.GetDescription().GetValue())) + opts = append(opts, hostplugin.WithDescription(item.GetDescription().GetValue())) } if item.GetAttributes() != nil { - opts = append(opts, plugin.WithAttributes(item.GetAttributes())) + opts = append(opts, hostplugin.WithAttributes(item.GetAttributes())) } if item.GetPreferredEndpoints() != nil { - opts = append(opts, plugin.WithPreferredEndpoints(item.GetPreferredEndpoints())) + opts = append(opts, hostplugin.WithPreferredEndpoints(item.GetPreferredEndpoints())) } if item.GetSyncIntervalSeconds() != nil { - opts = append(opts, plugin.WithSyncIntervalSeconds(item.GetSyncIntervalSeconds().GetValue())) + opts = append(opts, hostplugin.WithSyncIntervalSeconds(item.GetSyncIntervalSeconds().GetValue())) } - hs, err := plugin.NewHostSet(ctx, catalogId, opts...) + hs, err := hostplugin.NewHostSet(ctx, catalogId, opts...) if err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to build host set for creation")) } @@ -969,8 +969,8 @@ func validateCreateRequest(ctx context.Context, req *pbs.CreateHostSetRequest) e if len(req.GetItem().PreferredEndpoints) > 0 { badFields[globals.PreferredEndpointsField] = "This field is not yet supported for static host sets." } - case plugin.Subtype: - if req.GetItem().GetType() != "" && req.GetItem().GetType() != plugin.Subtype.String() { + case hostplugin.Subtype: + if req.GetItem().GetType() != "" && req.GetItem().GetType() != hostplugin.Subtype.String() { badFields[globals.TypeField] = "Doesn't match the parent resource's type." } if val := req.GetItem().GetSyncIntervalSeconds(); val != nil { @@ -997,7 +997,7 @@ func validateUpdateRequest(ctx context.Context, req *pbs.UpdateHostSetRequest) e if req.GetItem().GetType() != "" && req.GetItem().GetType() != static.Subtype.String() { badFields[globals.TypeField] = "Cannot modify the resource type." } - case plugin.Subtype: + case hostplugin.Subtype: if val := req.GetItem().GetSyncIntervalSeconds(); val != nil { if val.GetValue() == 0 || val.GetValue() < -1 { badFields[globals.SyncIntervalSecondsField] = "Must be -1 or a positive integer." diff --git a/internal/daemon/controller/handlers/host_sets/host_set_service_test.go b/internal/daemon/controller/handlers/host_sets/host_set_service_test.go index a8f70d846..5b2d8e9fa 100644 --- a/internal/daemon/controller/handlers/host_sets/host_set_service_test.go +++ b/internal/daemon/controller/handlers/host_sets/host_set_service_test.go @@ -20,11 +20,11 @@ import ( "github.com/hashicorp/boundary/internal/db" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/host" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/types/scope" @@ -46,8 +46,8 @@ import ( ) 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"}, + static.Subtype: {"no-op", "read", "update", "delete", "add-hosts", "set-hosts", "remove-hosts"}, + hostplugin.Subtype: {"no-op", "read", "update", "delete"}, } func TestGet_Static(t *testing.T) { @@ -68,8 +68,8 @@ func TestGet_Static(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] @@ -165,17 +165,17 @@ func TestGet_Plugin(t *testing.T) { name := "test" prefEndpoints := []string{"cidr:1.2.3.4", "cidr:2.3.4.5/24"} - plg := hostplugin.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - hs := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(prefEndpoints), plugin.WithSyncIntervalSeconds(-1)) - hsPrev := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(prefEndpoints), plugin.WithSyncIntervalSeconds(-1), plugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostSetPreviousPrefix))) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + hs := hostplugin.TestSet(t, conn, kms, sche, hc, plgm, hostplugin.WithPreferredEndpoints(prefEndpoints), hostplugin.WithSyncIntervalSeconds(-1)) + hsPrev := hostplugin.TestSet(t, conn, kms, sche, hc, plgm, hostplugin.WithPreferredEndpoints(prefEndpoints), hostplugin.WithSyncIntervalSeconds(-1), hostplugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostSetPreviousPrefix))) toMerge := &pbs.GetHostSetRequest{} @@ -184,7 +184,7 @@ func TestGet_Plugin(t *testing.T) { Id: hs.GetPublicId(), CreatedTime: hs.CreateTime.GetTimestamp(), UpdatedTime: hs.UpdateTime.GetTimestamp(), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), Scope: &scopes.ScopeInfo{Id: proj.GetPublicId(), Type: scope.Project.String(), ParentScopeId: org.GetPublicId()}, Plugin: &plugins.PluginInfo{ Id: plg.GetPublicId(), @@ -193,7 +193,7 @@ func TestGet_Plugin(t *testing.T) { }, PreferredEndpoints: prefEndpoints, SyncIntervalSeconds: &wrappers.Int32Value{Value: -1}, - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], } cases := []struct { @@ -279,8 +279,8 @@ func TestList_Static(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } hcs := static.TestCatalogs(t, conn, proj.GetPublicId(), 2) hc, hcNoHosts := hcs[0], hcs[1] @@ -379,20 +379,20 @@ func TestList_Plugin(t *testing.T) { return static.NewRepository(rw, rw, kms) } name := "test" - plg := hostplugin.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - hcNoHosts := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + hcNoHosts := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) preferredEndpoints := []string{"cidr:1.2.3.4", "dns:*.foobar.com"} var wantHs []*pb.HostSet for i := 0; i < 10; i++ { - h := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(preferredEndpoints), plugin.WithSyncIntervalSeconds(5)) + h := hostplugin.TestSet(t, conn, kms, sche, hc, plgm, hostplugin.WithPreferredEndpoints(preferredEndpoints), hostplugin.WithSyncIntervalSeconds(5)) wantHs = append(wantHs, &pb.HostSet{ Id: h.GetPublicId(), HostCatalogId: h.GetCatalogId(), @@ -405,8 +405,8 @@ func TestList_Plugin(t *testing.T) { CreatedTime: h.GetCreateTime().GetTimestamp(), UpdatedTime: h.GetUpdateTime().GetTimestamp(), Version: h.GetVersion(), - Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + Type: hostplugin.Subtype.String(), + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], PreferredEndpoints: preferredEndpoints, SyncIntervalSeconds: &wrappers.Int32Value{Value: 5}, }) @@ -492,8 +492,8 @@ func TestDelete_Static(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] h := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] @@ -563,17 +563,17 @@ func TestDelete_Plugin(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } name := "test" - plg := hostplugin.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - h := plugin.TestSet(t, conn, kms, sche, hc, plgm) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + h := hostplugin.TestSet(t, conn, kms, sche, hc, plgm) s, err := host_sets.NewService(repoFn, pluginRepoFn) require.NoError(t, err, "Couldn't create a new host set service.") @@ -641,8 +641,8 @@ func TestDelete_twice(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] h := static.TestSets(t, conn, hc.GetPublicId(), 1)[0] @@ -678,8 +678,8 @@ func TestCreate_Static(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] prefEndpoints := []string{"cidr:1.2.3.4", "cidr:2.3.4.5/24"} @@ -835,9 +835,9 @@ func TestCreate_Plugin(t *testing.T) { return static.NewRepository(rw, rw, kms) } name := "test" - plg := hostplugin.TestPlugin(t, conn, name) - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, name) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginHostServer{ OnCreateSetFn: func(ctx context.Context, req *plgpb.OnCreateSetRequest) (*plgpb.OnCreateSetResponse, error) { return nil, nil @@ -845,7 +845,7 @@ func TestCreate_Plugin(t *testing.T) { }), }) } - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) attrs := map[string]any{ "int": 1, @@ -891,7 +891,7 @@ func TestCreate_Plugin(t *testing.T) { HostCatalogId: hc.GetPublicId(), Name: &wrappers.StringValue{Value: "No Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), SyncIntervalSeconds: &wrapperspb.Int32Value{Value: -1}, }}, res: &pbs.CreateHostSetResponse{ @@ -906,8 +906,8 @@ func TestCreate_Plugin(t *testing.T) { }, Name: &wrappers.StringValue{Value: "No Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + Type: hostplugin.Subtype.String(), + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], SyncIntervalSeconds: &wrapperspb.Int32Value{Value: -1}, }, }, @@ -918,7 +918,7 @@ func TestCreate_Plugin(t *testing.T) { HostCatalogId: hc.GetPublicId(), Name: &wrappers.StringValue{Value: "With Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), SyncIntervalSeconds: &wrapperspb.Int32Value{Value: 90}, Attrs: &pb.HostSet_Attributes{ Attributes: testInputAttrs, @@ -936,9 +936,9 @@ func TestCreate_Plugin(t *testing.T) { }, Name: &wrappers.StringValue{Value: "With Attributes"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), SyncIntervalSeconds: &wrapperspb.Int32Value{Value: 90}, - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], Attrs: &pb.HostSet_Attributes{ Attributes: testOutputAttrs, }, @@ -951,7 +951,7 @@ func TestCreate_Plugin(t *testing.T) { HostCatalogId: hc.GetPublicId(), Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PreferredEndpoints: prefEndpoints, }}, res: &pbs.CreateHostSetResponse{ @@ -966,9 +966,9 @@ func TestCreate_Plugin(t *testing.T) { }, Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PreferredEndpoints: prefEndpoints, - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], }, }, }, @@ -978,7 +978,7 @@ func TestCreate_Plugin(t *testing.T) { HostCatalogId: hc.GetPublicId(), Name: &wrappers.StringValue{Value: "name"}, Description: &wrappers.StringValue{Value: "desc"}, - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), PreferredEndpoints: append(prefEndpoints, "foobar:1.2.3.4"), }}, err: handlers.ApiErrorWithCode(codes.InvalidArgument), @@ -1012,8 +1012,8 @@ 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[plugin.Subtype], + Type: hostplugin.Subtype.String(), + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], }, }, }, @@ -1130,8 +1130,8 @@ func TestUpdate_Static(t *testing.T) { Id: hs.GetPublicId(), } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } tested, err := host_sets.NewService(repoFn, plgRepoFn) require.NoError(t, err, "Failed to create a new host set service.") @@ -1475,7 +1475,7 @@ func TestUpdate_Plugin(t *testing.T) { rw := db.New(conn) name := "test" - plg := hostplugin.TestPlugin(t, conn, name) + plg := plugin.TestPlugin(t, conn, name) plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } @@ -1483,8 +1483,8 @@ func TestUpdate_Plugin(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepo := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginHostRepo := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } iamRepoFn := func() (*iam.Repository, error) { return iamRepo, nil @@ -1492,7 +1492,7 @@ func TestUpdate_Plugin(t *testing.T) { tested, err := host_sets.NewService(repoFn, pluginHostRepo) require.NoError(t, err, "Failed to create a new host catalog service.") - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) ctx := auth.DisabledAuthTestContext(iamRepoFn, proj.GetPublicId()) freshSet := func(t *testing.T) *pb.HostSet { @@ -1504,7 +1504,7 @@ func TestUpdate_Plugin(t *testing.T) { HostCatalogId: hc.GetPublicId(), Name: wrapperspb.String("default"), Description: wrapperspb.String("default"), - Type: plugin.Subtype.String(), + Type: hostplugin.Subtype.String(), Attrs: &pb.HostSet_Attributes{ Attributes: attr, }, @@ -1820,8 +1820,8 @@ func TestAddHostSetHosts(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } s, err := host_sets.NewService(repoFn, plgRepoFn) require.NoError(t, err, "Error when getting new host set service.") @@ -1941,8 +1941,8 @@ func TestSetHostSetHosts(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } s, err := host_sets.NewService(repoFn, plgRepoFn) require.NoError(t, err, "Error when getting new host set service.") @@ -2058,8 +2058,8 @@ func TestRemoveHostSetHosts(t *testing.T) { repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plgRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + plgRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } s, err := host_sets.NewService(repoFn, plgRepoFn) require.NoError(t, err, "Error when getting new host set service.") diff --git a/internal/daemon/controller/handlers/hosts/host_service.go b/internal/daemon/controller/handlers/hosts/host_service.go index 77cd94cb1..f9d4140c2 100644 --- a/internal/daemon/controller/handlers/hosts/host_service.go +++ b/internal/daemon/controller/handlers/hosts/host_service.go @@ -16,11 +16,11 @@ import ( "github.com/hashicorp/boundary/internal/errors" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" "github.com/hashicorp/boundary/internal/host" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/host/static/store" "github.com/hashicorp/boundary/internal/perms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + plugin "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/types/action" "github.com/hashicorp/boundary/internal/types/resource" @@ -43,7 +43,7 @@ var ( action.Update, action.Delete, }, - plugin.Subtype: { + hostplugin.Subtype: { action.NoOp, action.Read, }, @@ -310,7 +310,7 @@ func (s Service) getFromRepo(ctx context.Context, id string) (host.Host, *plugin if h == nil { return nil, nil, handlers.NotFoundErrorf("Host %q doesn't exist.", id) } - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginRepoFn() if err != nil { return nil, nil, err @@ -425,7 +425,7 @@ func (s Service) listFromRepo(ctx context.Context, catalogId string) ([]host.Hos for _, h := range hl { hosts = append(hosts, h) } - case plugin.Subtype: + case hostplugin.Subtype: repo, err := s.pluginRepoFn() if err != nil { return nil, nil, err @@ -473,7 +473,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return nil, res } parentId = h.GetCatalogId() - case plugin.Subtype: + case hostplugin.Subtype: h, _, err := pluginRepo.LookupHost(ctx, id) if err != nil { res.Error = err @@ -501,7 +501,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return nil, res } cat = stcat - case plugin.Subtype: + case hostplugin.Subtype: plcat, _, err := pluginRepo.LookupCatalog(ctx, parentId) if err != nil { res.Error = err @@ -517,7 +517,7 @@ func (s Service) parentAndAuthResult(ctx context.Context, id string, a action.Ty return cat, auth.Verify(ctx, opts...) } -func toPluginInfo(plg *hostplugin.Plugin) *plugins.PluginInfo { +func toPluginInfo(plg *plugin.Plugin) *plugins.PluginInfo { if plg == nil { return nil } @@ -546,8 +546,8 @@ func toProto(ctx context.Context, in host.Host, opt ...handlers.Option) (*pb.Hos switch in.(type) { case *static.Host: out.Type = static.Subtype.String() - case *plugin.Host: - out.Type = plugin.Subtype.String() + case *hostplugin.Host: + out.Type = hostplugin.Subtype.String() } } if outputFields.Has(globals.DescriptionField) && in.GetDescription() != "" { @@ -588,7 +588,7 @@ func toProto(ctx context.Context, in host.Host, opt ...handlers.Option) (*pb.Hos out.Plugin = opts.WithPlugin } switch h := in.(type) { - case *plugin.Host: + case *hostplugin.Host: if outputFields.Has(globals.IpAddressesField) { out.IpAddresses = h.IpAddresses } @@ -661,7 +661,7 @@ func validateCreateRequest(req *pbs.CreateHostRequest) error { } } } - case plugin.Subtype: + case hostplugin.Subtype: badFields[globals.HostCatalogIdField] = "Cannot manually create hosts for this type of catalog." } return badFields @@ -699,7 +699,7 @@ func validateUpdateRequest(req *pbs.UpdateHostRequest) error { } } } - case plugin.Subtype: + case hostplugin.Subtype: badFields[globals.IdField] = "Cannot modify this type of host." default: badFields["id"] = "Improperly formatted identifier used." @@ -712,7 +712,7 @@ func validateDeleteRequest(req *pbs.DeleteHostRequest) error { return handlers.ValidateDeleteRequest(func() map[string]string { badFields := map[string]string{} switch subtypes.SubtypeFromId(domain, req.GetId()) { - case plugin.Subtype: + case hostplugin.Subtype: badFields[globals.IdField] = "Cannot manually delete this type of host." } return badFields diff --git a/internal/daemon/controller/handlers/hosts/host_service_test.go b/internal/daemon/controller/handlers/hosts/host_service_test.go index 966dae6d5..bc43d095c 100644 --- a/internal/daemon/controller/handlers/hosts/host_service_test.go +++ b/internal/daemon/controller/handlers/hosts/host_service_test.go @@ -19,11 +19,11 @@ import ( "github.com/hashicorp/boundary/internal/daemon/controller/handlers/hosts" "github.com/hashicorp/boundary/internal/db" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/types/scope" @@ -43,8 +43,8 @@ import ( ) var testAuthorizedActions = map[subtypes.Subtype][]string{ - static.Subtype: {"no-op", "read", "update", "delete"}, - plugin.Subtype: {"no-op", "read"}, + static.Subtype: {"no-op", "read", "update", "delete"}, + hostplugin.Subtype: {"no-op", "read"}, } func TestGet_Static(t *testing.T) { @@ -62,8 +62,8 @@ func TestGet_Static(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -152,27 +152,27 @@ func TestGet_Plugin(t *testing.T) { org, proj := iam.TestScopes(t, iamRepo) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - h := plugin.TestHost(t, conn, hc.GetPublicId(), "test", plugin.WithExternalName("test-ext-name")) - hPrev := plugin.TestHost(t, conn, hc.GetPublicId(), "test-prev", - plugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostPreviousPrefix)), - plugin.WithExternalName("test-prev-name"), + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + h := hostplugin.TestHost(t, conn, hc.GetPublicId(), "test", hostplugin.WithExternalName("test-ext-name")) + hPrev := hostplugin.TestHost(t, conn, hc.GetPublicId(), "test-prev", + hostplugin.WithPublicId(fmt.Sprintf("%s_1234567890", globals.PluginHostPreviousPrefix)), + hostplugin.WithExternalName("test-prev-name"), ) - hs := plugin.TestSet(t, conn, kms, sche, hc, plgm) - plugin.TestSetMembers(t, conn, hs.GetPublicId(), []*plugin.Host{h, hPrev}) + hs := hostplugin.TestSet(t, conn, kms, sche, hc, plgm) + hostplugin.TestSetMembers(t, conn, hs.GetPublicId(), []*hostplugin.Host{h, hPrev}) pHost := &pb.Host{ HostCatalogId: hc.GetPublicId(), @@ -180,7 +180,7 @@ func TestGet_Plugin(t *testing.T) { 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(), + Type: hostplugin.Subtype.String(), Plugin: &plugins.PluginInfo{ Id: plg.GetPublicId(), Name: plg.GetName(), @@ -189,7 +189,7 @@ func TestGet_Plugin(t *testing.T) { HostSetIds: []string{hs.GetPublicId()}, ExternalId: "test", ExternalName: "test-ext-name", - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], } cases := []struct { @@ -271,8 +271,8 @@ func TestList_Static(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -383,28 +383,28 @@ func TestList_Plugin(t *testing.T) { } org, proj := iam.TestScopes(t, iamRepo) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - hcs := plugin.TestCatalogs(t, conn, proj.GetPublicId(), plg.GetPublicId(), 2) + hcs := hostplugin.TestCatalogs(t, conn, proj.GetPublicId(), plg.GetPublicId(), 2) hc, hcNoHosts := hcs[0], hcs[1] - hs := plugin.TestSet(t, conn, kms, sche, hc, plgm) + hs := hostplugin.TestSet(t, conn, kms, sche, hc, plgm) var wantHs []*pb.Host for i := 0; i < 10; i++ { extId := fmt.Sprintf("host %d", i) - h := plugin.TestHost(t, conn, hc.GetPublicId(), extId, plugin.WithExternalName(fmt.Sprintf("ext-name-%d", i))) - plugin.TestSetMembers(t, conn, hs.GetPublicId(), []*plugin.Host{h}) + h := hostplugin.TestHost(t, conn, hc.GetPublicId(), extId, hostplugin.WithExternalName(fmt.Sprintf("ext-name-%d", i))) + hostplugin.TestSetMembers(t, conn, hs.GetPublicId(), []*hostplugin.Host{h}) wantHs = append(wantHs, &pb.Host{ Id: h.GetPublicId(), HostCatalogId: h.GetCatalogId(), @@ -420,8 +420,8 @@ func TestList_Plugin(t *testing.T) { Version: 1, ExternalId: extId, ExternalName: fmt.Sprintf("ext-name-%d", i), - Type: plugin.Subtype.String(), - AuthorizedActions: testAuthorizedActions[plugin.Subtype], + Type: hostplugin.Subtype.String(), + AuthorizedActions: testAuthorizedActions[hostplugin.Subtype], }) } sort.Slice(wantHs, func(i, j int) bool { @@ -513,8 +513,8 @@ func TestDelete(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -522,9 +522,9 @@ func TestDelete(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] h := static.TestHosts(t, conn, hc.GetPublicId(), 1)[0] - plg := hostplugin.TestPlugin(t, conn, "test") - pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - pluginH := plugin.TestHost(t, conn, pluginHc.GetPublicId(), "test") + plg := plugin.TestPlugin(t, conn, "test") + pluginHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginH := hostplugin.TestHost(t, conn, pluginHc.GetPublicId(), "test") s, err := hosts.NewService(repoFn, pluginRepoFn) require.NoError(t, err, "Couldn't create a new host set service.") @@ -597,8 +597,8 @@ func TestDelete_twice(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -634,16 +634,16 @@ func TestCreate(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] - plg := hostplugin.TestPlugin(t, conn, "test") - pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + plg := plugin.TestPlugin(t, conn, "test") + pluginHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) defaultHcCreated := hc.GetCreateTime().GetTimestamp().AsTime() @@ -870,8 +870,8 @@ func TestUpdate_Static(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) @@ -1337,16 +1337,16 @@ func TestUpdate_Plugin(t *testing.T) { rw := db.New(conn) sche := scheduler.TestScheduler(t, conn, wrapper) - pluginRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } repoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - plg := hostplugin.TestPlugin(t, conn, "test") - hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - h := plugin.TestHost(t, conn, hc.GetPublicId(), "test") + plg := plugin.TestPlugin(t, conn, "test") + hc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + h := hostplugin.TestHost(t, conn, hc.GetPublicId(), "test") tested, err := hosts.NewService(repoFn, pluginRepoFn) require.NoError(t, err) diff --git a/internal/daemon/controller/handlers/targets/tcp/target_service_test.go b/internal/daemon/controller/handlers/targets/tcp/target_service_test.go index e48844533..dd4662206 100644 --- a/internal/daemon/controller/handlers/targets/tcp/target_service_test.go +++ b/internal/daemon/controller/handlers/targets/tcp/target_service_test.go @@ -33,11 +33,11 @@ import ( "github.com/hashicorp/boundary/internal/db" pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services" authpb "github.com/hashicorp/boundary/internal/gen/controller/auth" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/requests" "github.com/hashicorp/boundary/internal/scheduler" @@ -104,8 +104,8 @@ func testService(t *testing.T, ctx context.Context, conn *db.DB, kms *kms.Kms, w staticHostRepoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } vaultCredRepoFn := func() (*vault.Repository, error) { return vault.NewRepository(rw, rw, kms, sche) @@ -1366,9 +1366,9 @@ func TestAddTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) - plg := host.TestPlugin(t, conn, "test") - pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - pluginHs := plugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, "test") + pluginHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := hostplugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), }) @@ -1528,9 +1528,9 @@ func TestSetTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) - plg := host.TestPlugin(t, conn, "test") - pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - pluginHs := plugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, "test") + pluginHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := hostplugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), }) @@ -1678,9 +1678,9 @@ func TestRemoveTargetHostSources(t *testing.T) { hc := static.TestCatalogs(t, conn, proj.GetPublicId(), 1)[0] hs := static.TestSets(t, conn, hc.GetPublicId(), 2) - plg := host.TestPlugin(t, conn, "test") - pluginHc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - pluginHs := plugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, "test") + pluginHc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + pluginHs := hostplugin.TestSet(t, conn, kms, sche, pluginHc, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), }) @@ -2455,7 +2455,7 @@ func TestAuthorizeSession(t *testing.T) { return ldap.NewRepository(ctx, rw, rw, kms) } - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(loopback.TestPluginHostServer{ ListHostsFn: func(_ context.Context, req *plgpb.ListHostsRequest) (*plgpb.ListHostsResponse, error) { @@ -2480,8 +2480,8 @@ func TestAuthorizeSession(t *testing.T) { }, }), } - pluginHostRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, plgm) + pluginHostRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, plgm) } loginName := "foo@bar.com" @@ -2527,11 +2527,11 @@ func TestAuthorizeSession(t *testing.T) { hWithPort, _, err = staticRepo.UpdateHost(ctx, hcWithPort.GetProjectId(), hWithPort, hWithPort.GetVersion(), []string{"address"}) require.NoError(t, err) - phc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) - phs := plugin.TestSet(t, conn, kms, sche, phc, plgm, plugin.WithPreferredEndpoints([]string{"cidr:10.0.0.0/24"})) + phc := hostplugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId()) + phs := hostplugin.TestSet(t, conn, kms, sche, phc, plgm, hostplugin.WithPreferredEndpoints([]string{"cidr:10.0.0.0/24"})) // Sync the boundary db from the plugins - plugin.TestRunSetSync(t, conn, kms, plgm) + hostplugin.TestRunSetSync(t, conn, kms, plgm) v := vault.NewTestVaultServer(t) v.MountPKI(t, vault.WithTestMountPath("pki/"+userName)) @@ -2740,8 +2740,8 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) { atRepoFn := func() (*authtoken.Repository, error) { return authtoken.NewRepository(rw, rw, kms) } - pluginHostRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } org, proj := iam.TestScopes(t, iamRepo) @@ -3320,8 +3320,8 @@ func TestAuthorizeSession_Errors(t *testing.T) { staticHostRepoFn := func() (*static.Repository, error) { return static.NewRepository(rw, rw, kms) } - pluginHostRepoFn := func() (*plugin.Repository, error) { - return plugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) + pluginHostRepoFn := func() (*hostplugin.Repository, error) { + return hostplugin.NewRepository(rw, rw, kms, sche, map[string]plgpb.HostPluginServiceClient{}) } vaultCredRepoFn := func() (*vault.Repository, error) { return vault.NewRepository(rw, rw, kms, sche) diff --git a/internal/db/schema/migrations/oss/postgres/68/02_add_storage_bucket.up.sql b/internal/db/schema/migrations/oss/postgres/68/02_add_storage_bucket.up.sql deleted file mode 100644 index f02ddc68a..000000000 --- a/internal/db/schema/migrations/oss/postgres/68/02_add_storage_bucket.up.sql +++ /dev/null @@ -1,22 +0,0 @@ --- Copyright (c) HashiCorp, Inc. --- SPDX-License-Identifier: MPL-2.0 - -begin; - - -- Stub for storage plugin storage bucket table - create table storage_plugin_storage_bucket ( - public_id wt_public_id primary key, - worker_filter wt_bexprfilter not null - ); - - -- Stub for storage bucket table - create table storage_bucket ( - public_id wt_public_id primary key, - scope_id wt_scope_id - constraint iam_scope_fkey - references iam_scope (public_id) - on delete restrict -- Scopes with storage buckets cannot be deleted - on update cascade - ); - -commit; diff --git a/internal/db/schema/migrations/oss/postgres/68/02_plugins_restructure.up.sql b/internal/db/schema/migrations/oss/postgres/68/02_plugins_restructure.up.sql new file mode 100644 index 000000000..cb6342781 --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/68/02_plugins_restructure.up.sql @@ -0,0 +1,69 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: MPL-2.0 + +begin; + +alter table plugin add column description text; +alter table plugin add column create_time wt_timestamp; +alter table plugin add column update_time wt_timestamp; +alter table plugin add column version wt_version; + +update plugin as p +set description = ph.description, + create_time = ph.create_time, + update_time = ph.update_time, + version = ph.version +from plugin_host as ph +where p.public_id = ph.public_id; + +-- create new triggers on plugin +create trigger update_version_column after update on plugin + for each row execute procedure update_version_column(); + +create trigger update_time_column before update on plugin + for each row execute procedure update_time_column(); + +create trigger default_create_time_column before insert on plugin + for each row execute procedure default_create_time(); + +drop trigger immutable_columns on plugin; +create trigger immutable_columns before update on plugin + for each row execute procedure immutable_columns('public_id', 'create_time'); + +drop trigger insert_plugin_subtype on plugin_host; +drop trigger update_plugin_subtype on plugin_host; +drop trigger delete_plugin_subtype on plugin_host; + +create table plugin_host_supported ( + public_id wt_plugin_id primary key + references plugin(public_id) + on delete cascade + on update cascade +); +comment on table plugin_host_supported is + 'plugin_storage_supported entries indicate that a given plugin is flagged as a host plugin.'; + +-- flag all existing host plugins as being host plugins +insert into plugin_host_supported +(public_id) +select public_id +from plugin_host; + +-- drop existing references to plugin_host, remake to plugin +alter table host_plugin_catalog +drop constraint plugin_host_fkey; + +alter table host_plugin_catalog + add constraint plugin_host_supported_fkey + foreign key (plugin_id) + references plugin_host_supported (public_id) + on delete cascade + on update cascade; + +-- create a comment for host_plugin_catalog since it doesn't exist yet +comment on table host_plugin_catalog is + 'host_plugin_catalog joins host catalogs to the host plugin that manage them.'; + +drop table plugin_host; + +commit; diff --git a/internal/db/schema/migrations/oss/postgres/68/03_storage_bucket.up.sql b/internal/db/schema/migrations/oss/postgres/68/03_storage_bucket.up.sql new file mode 100644 index 000000000..be8790cc8 --- /dev/null +++ b/internal/db/schema/migrations/oss/postgres/68/03_storage_bucket.up.sql @@ -0,0 +1,184 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: MPL-2.0 + +begin; + + create table storage_bucket ( + public_id wt_public_id primary key, + scope_id wt_scope_id + constraint iam_scope_fkey + references iam_scope (public_id) + on delete restrict -- Scopes with storage buckets cannot be deleted + on update cascade + ); + comment on table storage_bucket is 'storage_bucket entries represent external storage buckets that boundary has access to.'; + + create table plugin_storage_supported ( + public_id wt_plugin_id primary key + references plugin(public_id) + on delete cascade + on update cascade + ); + comment on table plugin_storage_supported is + 'plugin_storage_supported entries indicate that a given plugin is flagged as a storage plugin.'; + + -- flag aws plugin as supporting storage + insert into plugin_storage_supported + (public_id) + select public_id + from plugin + where name = 'aws'; + + create table storage_plugin_storage_bucket ( + public_id wt_public_id primary key + references storage_bucket(public_id) + on delete cascade + on update cascade, + scope_id wt_scope_id not null + constraint iam_scope_fkey + references iam_scope(public_id) + on delete restrict + on update cascade, + name wt_name, + description wt_description, + create_time wt_timestamp, + update_time wt_timestamp, + version wt_version, + plugin_id wt_public_id not null + constraint plugin_storage_supported_fkey + references plugin_storage_supported(public_id) + on delete cascade + on update cascade, + bucket_name text not null + constraint bucket_name_must_not_be_empty + check(length(trim(bucket_name)) > 0), + bucket_prefix text, + worker_filter wt_bexprfilter not null, + attributes bytea, + secrets_hmac bytea not null + constraint secrets_hmac_must_not_be_empty + check(length(secrets_hmac) > 0), + constraint storage_plugin_storage_bucket_scope_id_name_uq + unique(scope_id, name) + ); + comment on table storage_plugin_storage_bucket is + 'storage_plugin_storage_bucket entries refer to a specific storage bucket that a storage plugin uses for all external storage.'; + + create trigger update_time_column before update on storage_plugin_storage_bucket + for each row execute procedure update_time_column(); + + create trigger default_create_time_column before insert on storage_plugin_storage_bucket + for each row execute procedure default_create_time(); + + create trigger update_version_column after update on storage_plugin_storage_bucket + for each row execute procedure update_version_column(); + + create trigger immutable_columns before update on storage_plugin_storage_bucket + for each row execute procedure immutable_columns('public_id', 'scope_id', 'create_time', 'bucket_name'); + + -- insert_storage_bucket_subtype() is a trigger function for + -- subtypes of storage_bucket + create or replace function insert_storage_bucket_subtype() returns trigger + as $$ + begin + + insert into storage_bucket + (public_id, scope_id) + values + (new.public_id, new.scope_id); + + return new; + + end; + $$ language plpgsql; + comment on function insert_storage_bucket_subtype is + 'insert_storage_bucket_subtype is a trigger function for subtypes of storage_bucket that ensures values exist in the parent storage_bucket table.'; + + create trigger insert_storage_bucket_subtype before insert on storage_plugin_storage_bucket + for each row execute procedure insert_storage_bucket_subtype(); + + -- delete_storage_bucket_subtype() is a trigger function for + -- subtypes of storage_bucket + create or replace function delete_storage_bucket_subtype() returns trigger + as $$ + begin + + delete from storage_bucket + where public_id = old.public_id; + return null; -- result is ignored since this is an after trigger + + end; + $$ language plpgsql; + comment on function delete_storage_bucket_subtype is + 'delete_storage_bucket_subtype is a trigger function for subtypes of storage_bucket that removes the associated values in the storage_bucket table on delete.'; + + create trigger delete_storage_bucket_subtype after delete on storage_plugin_storage_bucket + for each row execute procedure delete_storage_bucket_subtype(); + + -- storage_bucket_scope_id_valid() is a trigger function for + -- subtypes of storage_bucket + create or replace function storage_bucket_scope_id_valid() returns trigger + as $$ + begin + + perform from iam_scope where public_id = new.scope_id and type in ('global', 'org'); + if not found then + raise exception 'invalid scope type for storage bucket creation'; + end if; + return new; + + end; + $$ language plpgsql; + comment on function storage_bucket_scope_id_valid is + 'storage_bucket_scope_id_valid is a trigger function for subtypes of storage_bucket that checks if the scope_id being inserted is a global or org level scope.'; + + create trigger storage_bucket_scope_id_valid before insert on storage_plugin_storage_bucket + for each row execute procedure storage_bucket_scope_id_valid(); + + -- allow operations on storage bucket to be oplogged + insert into oplog_ticket + (name, version) + values + ('storage_plugin_storage_bucket', 1); + + create table storage_plugin_storage_bucket_secret ( + storage_bucket_id wt_public_id primary key + references storage_plugin_storage_bucket(public_id) + on delete cascade + on update cascade, + secrets_encrypted bytea not null + constraint secrets_must_not_be_empty + check(length(secrets_encrypted) > 0), + key_id text not null + constraint kms_data_key_version_fkey + references kms_data_key_version(private_id) + on delete restrict + on update cascade + ); + comment on table storage_plugin_storage_bucket is + 'storage_plugin_storage_bucket_secret are the secrets used to access and update a storage bucket by a plugin.'; + + create view storage_plugin_storage_bucket_with_secret as + select + spsb.public_id, + spsb.scope_id, + spsb.name, + spsb.description, + spsb.create_time, + spsb.update_time, + spsb.version, + spsb.plugin_id, + spsb.bucket_name, + spsb.bucket_prefix, + spsb.worker_filter, + spsb.attributes, + spsb.secrets_hmac, + spsbs.secrets_encrypted, + spsbs.key_id + from storage_plugin_storage_bucket spsb + left join storage_plugin_storage_bucket_secret spsbs + on spsbs.storage_bucket_id = spsb.public_id; + comment on view storage_plugin_storage_bucket_with_secret is + 'storage bucket with its associated encrypted secrets'; + +commit; diff --git a/internal/db/schema/migrations/oss/postgres/68/03_session_recording.up.sql b/internal/db/schema/migrations/oss/postgres/68/04_session_recording.up.sql similarity index 100% rename from internal/db/schema/migrations/oss/postgres/68/03_session_recording.up.sql rename to internal/db/schema/migrations/oss/postgres/68/04_session_recording.up.sql diff --git a/internal/db/sqltest/Makefile b/internal/db/sqltest/Makefile index fe88b398d..29b88ae61 100644 --- a/internal/db/sqltest/Makefile +++ b/internal/db/sqltest/Makefile @@ -28,6 +28,7 @@ TESTS ?= tests/setup/*.sql \ tests/controller/*.sql \ tests/hcp/*/*.sql \ tests/kms/*.sql \ + tests/plugin/*.sql \ tests/recording/*.sql POSTGRES_DOCKER_IMAGE_BASE ?= postgres diff --git a/internal/db/sqltest/initdb.d/03_widgets_persona.sql b/internal/db/sqltest/initdb.d/03_widgets_persona.sql index 0a3de7f6d..5cc1e0102 100644 --- a/internal/db/sqltest/initdb.d/03_widgets_persona.sql +++ b/internal/db/sqltest/initdb.d/03_widgets_persona.sql @@ -270,11 +270,16 @@ begin; where h.catalog_id = s.catalog_id and h.address like '%.widget'; - insert into plugin_host + insert into plugin (scope_id, public_id, name) values ('global', 'plg___wb-hplg', 'Short Host Plugin'); + insert into plugin_host_supported + (public_id) + values + ('plg___wb-hplg'); + insert into host_plugin_catalog (project_id, public_id, plugin_id, name, attributes) values diff --git a/internal/db/sqltest/tests/plugin/valid_storage_bucket_added.sql b/internal/db/sqltest/tests/plugin/valid_storage_bucket_added.sql new file mode 100644 index 000000000..76acabb7e --- /dev/null +++ b/internal/db/sqltest/tests/plugin/valid_storage_bucket_added.sql @@ -0,0 +1,31 @@ +-- Copyright (c) HashiCorp, Inc. +-- SPDX-License-Identifier: MPL-2.0 + +begin; + select plan(4); + + -- Ensure no data has been added + select is(count(*), 0::bigint) from storage_bucket; + select is(count(*), 0::bigint) from storage_plugin_storage_bucket; + + -- Insert records into plugins storage_plugin_storage_bucket + insert into plugin + (scope_id, public_id, name) + values + ('global', 'plg____sb-plg', 'Storage Bucket Plugin'); + + insert into plugin_storage_supported + (public_id) + values + ('plg____sb-plg'); + + insert into storage_plugin_storage_bucket + (public_id, scope_id, plugin_id, bucket_name, worker_filter, secrets_hmac) + values + ('sb_________1','global', 'plg____sb-plg', 'test bucket name', 'test worker filter', '\xdeadbeef'); + + select is(count(*), 1::bigint) from storage_plugin_storage_bucket where public_id = 'sb_________1'; + select is(count(*), 1::bigint) from storage_bucket where public_id = 'sb_________1'; + + select * from finish(); +rollback; \ No newline at end of file diff --git a/internal/host/plugin/host_address_test.go b/internal/host/plugin/host_address_test.go index 21723baca..6a164cb33 100644 --- a/internal/host/plugin/host_address_test.go +++ b/internal/host/plugin/host_address_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/boundary/internal/host" "github.com/hashicorp/boundary/internal/host/store" "github.com/hashicorp/boundary/internal/iam" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -22,7 +22,7 @@ func TestHostDnsName_Create(t *testing.T) { w := db.New(conn) wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) host1 := TestHost(t, conn, cat.GetPublicId(), "external") @@ -153,7 +153,7 @@ func TestHostIpAddress_Create(t *testing.T) { w := db.New(conn) wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) host1 := TestHost(t, conn, cat.GetPublicId(), "external") @@ -292,7 +292,7 @@ func TestHostDnsName_Delete(t *testing.T) { w := db.New(conn) wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) host1 := TestHost(t, conn, cat.GetPublicId(), "external") addr1, err := host.NewDnsName(ctx, host1.GetPublicId(), "addr1.foo.com") @@ -359,7 +359,7 @@ func TestHostIpAddress_Delete(t *testing.T) { w := db.New(conn) wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) host1 := TestHost(t, conn, cat.GetPublicId(), "external") addr1, err := host.NewIpAddress(ctx, host1.GetPublicId(), "1.2.3.4") diff --git a/internal/host/plugin/host_catalog_secret_test.go b/internal/host/plugin/host_catalog_secret_test.go index e17fb019c..cc8bfd458 100644 --- a/internal/host/plugin/host_catalog_secret_test.go +++ b/internal/host/plugin/host_catalog_secret_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -27,7 +27,7 @@ func TestHostCatalogSecret_New(t *testing.T) { kkms := kms.TestKms(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) type args struct { @@ -127,7 +127,7 @@ func TestHostCatalogSecret_Create_Upsert_Update_Delete(t *testing.T) { kkms := kms.TestKms(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) ctx := context.Background() diff --git a/internal/host/plugin/host_catalog_test.go b/internal/host/plugin/host_catalog_test.go index c2ac695a9..9a05afc28 100644 --- a/internal/host/plugin/host_catalog_test.go +++ b/internal/host/plugin/host_catalog_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" wrapping "github.com/hashicorp/go-kms-wrapping/v2" "github.com/hashicorp/go-kms-wrapping/v2/aead" "github.com/mr-tron/base58" @@ -29,7 +29,7 @@ func TestHostCatalog_Create(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") type args struct { pluginId string @@ -187,8 +187,8 @@ func TestHostCatalog_Create_DuplicateNames(t *testing.T) { wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) _, prj2 := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test1") - plg2 := host.TestPlugin(t, conn, "test2") + plg := plugin.TestPlugin(t, conn, "test1") + plg2 := plugin.TestPlugin(t, conn, "test2") got, err := NewHostCatalog(ctx, prj.GetPublicId(), plg.GetPublicId(), WithName("duplicate")) require.NoError(t, err) @@ -220,7 +220,7 @@ func TestHostCatalog_Delete(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) ignoredCat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) _ = ignoredCat @@ -271,7 +271,7 @@ func TestHostCatalog_Delete_Cascading(t *testing.T) { t.Run("delete-project", func(t *testing.T) { _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "deletescope") + plg := plugin.TestPlugin(t, conn, "deletescope") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) deleted, err := w.Delete(ctx, prj) @@ -285,7 +285,7 @@ func TestHostCatalog_Delete_Cascading(t *testing.T) { t.Run("delete-plugin", func(t *testing.T) { _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "deleteplugin") + plg := plugin.TestPlugin(t, conn, "deleteplugin") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) deleted, err := w.Delete(ctx, plg) @@ -343,7 +343,7 @@ func TestHostCatalog_SecretsHmac(t *testing.T) { databaseWrapper, err := kmsCache.GetWrapper(ctx, prj.PublicId, kms.KeyPurposeDatabase) require.NoError(t, err) - plg := host.TestPlugin(t, conn, "testplugin") + plg := plugin.TestPlugin(t, conn, "testplugin") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) // stableValue checks that HMACing the same value returns the same result. diff --git a/internal/host/plugin/host_set_member_test.go b/internal/host/plugin/host_set_member_test.go index ea92770dd..ba893b6f8 100644 --- a/internal/host/plugin/host_set_member_test.go +++ b/internal/host/plugin/host_set_member_test.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/oplog" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -34,7 +34,7 @@ func TestHostSetMember_InsertDelete(t *testing.T) { sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplg.TestPlugin(t, conn, "create") + plg := plugin.TestPlugin(t, conn, "create") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&plgpb.UnimplementedHostPluginServiceServer{}), } diff --git a/internal/host/plugin/host_set_test.go b/internal/host/plugin/host_set_test.go index e483ecac6..d783cfff6 100644 --- a/internal/host/plugin/host_set_test.go +++ b/internal/host/plugin/host_set_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/iam" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" @@ -21,7 +21,7 @@ func TestHostSet_Create(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) cat2 := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) diff --git a/internal/host/plugin/host_test.go b/internal/host/plugin/host_test.go index 488a66c48..fc893ddce 100644 --- a/internal/host/plugin/host_test.go +++ b/internal/host/plugin/host_test.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/iam" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -19,7 +19,7 @@ func TestHost_Create(t *testing.T) { conn, _ := db.TestSetup(t, "postgres") wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) cat2 := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) diff --git a/internal/host/plugin/immutable_fields_test.go b/internal/host/plugin/immutable_fields_test.go index a0451429c..9998bdf7f 100644 --- a/internal/host/plugin/immutable_fields_test.go +++ b/internal/host/plugin/immutable_fields_test.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -29,8 +29,8 @@ func TestPluginCatalog_ImmutableFields(t *testing.T) { wrapper := db.TestWrapper(t) ts := timestamp.Timestamp{Timestamp: ×tamppb.Timestamp{Seconds: 0, Nanos: 0}} o, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") - plg2 := host.TestPlugin(t, conn, "test2") + plg := plugin.TestPlugin(t, conn, "test") + plg2 := plugin.TestPlugin(t, conn, "test2") new := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) tests := []struct { @@ -106,7 +106,7 @@ func TestPluginSet_ImmutableFields(t *testing.T) { ts := timestamp.Timestamp{Timestamp: ×tamppb.Timestamp{Seconds: 0, Nanos: 0}} _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) new := TestSet(t, conn, kmsCache, sched, cat, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), diff --git a/internal/host/plugin/job_orphaned_host_cleanup_test.go b/internal/host/plugin/job_orphaned_host_cleanup_test.go index e3dcc6637..2121c51cc 100644 --- a/internal/host/plugin/job_orphaned_host_cleanup_test.go +++ b/internal/host/plugin/job_orphaned_host_cleanup_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -107,7 +107,7 @@ func TestOrphanedHostCleanupJob_Run(t *testing.T) { sched := scheduler.TestScheduler(t, conn, wrapper) plgServer := &loopback.TestPluginServer{} - plg := hostplg.TestPlugin(t, conn, "run") + plg := plugin.TestPlugin(t, conn, "run") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(plgServer), } diff --git a/internal/host/plugin/job_set_sync_test.go b/internal/host/plugin/job_set_sync_test.go index 3128cb5d0..6e51b2f83 100644 --- a/internal/host/plugin/job_set_sync_test.go +++ b/internal/host/plugin/job_set_sync_test.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -30,7 +30,7 @@ func TestNewSetSyncJob(t *testing.T) { wrapper := db.TestWrapper(t) kmsCache := kms.TestKms(t, conn, wrapper) - plg := hostplg.TestPlugin(t, conn, "lookup") + plg := plugin.TestPlugin(t, conn, "lookup") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } @@ -144,7 +144,7 @@ func TestSetSyncJob_Run(t *testing.T) { sched := scheduler.TestScheduler(t, conn, wrapper) plgServer := &loopback.TestPluginServer{} - plg := hostplg.TestPlugin(t, conn, "run") + plg := plugin.TestPlugin(t, conn, "run") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(plgServer), } @@ -412,7 +412,7 @@ func TestSetSyncJob_NextRunIn(t *testing.T) { kmsCache := kms.TestKms(t, conn, wrapper) iamRepo := iam.TestRepo(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "lookup") + plg := plugin.TestPlugin(t, conn, "lookup") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } diff --git a/internal/host/plugin/repository_host.go b/internal/host/plugin/repository_host.go index 51b36a123..8ba6ed0eb 100644 --- a/internal/host/plugin/repository_host.go +++ b/internal/host/plugin/repository_host.go @@ -9,12 +9,12 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/errors" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" ) // LookupHost will look up a host in the repository. If the host is not // found, it will return nil, nil. All options are ignored. -func (r *Repository) LookupHost(ctx context.Context, publicId string, opt ...Option) (*Host, *hostplugin.Plugin, error) { +func (r *Repository) LookupHost(ctx context.Context, publicId string, opt ...Option) (*Host, *plugin.Plugin, error) { const op = "plugin.(Repository).LookupHost" if publicId == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no public id") @@ -37,7 +37,7 @@ func (r *Repository) LookupHost(ctx context.Context, publicId string, opt ...Opt // ListHostsByCatalogId returns a slice of Hosts for the catalogId. // WithLimit is the only option supported. -func (r *Repository) ListHostsByCatalogId(ctx context.Context, catalogId string, opt ...Option) ([]*Host, *hostplugin.Plugin, error) { +func (r *Repository) ListHostsByCatalogId(ctx context.Context, catalogId string, opt ...Option) ([]*Host, *plugin.Plugin, error) { const op = "plugin.(Repository).ListHostsByCatalogId" if catalogId == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no catalog id") diff --git a/internal/host/plugin/repository_host_catalog.go b/internal/host/plugin/repository_host_catalog.go index 2150202f1..fabe55157 100644 --- a/internal/host/plugin/repository_host_catalog.go +++ b/internal/host/plugin/repository_host_catalog.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/boundary/internal/libs/patchstruct" "github.com/hashicorp/boundary/internal/observability/event" "github.com/hashicorp/boundary/internal/oplog" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + plg "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/util" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs" @@ -71,7 +71,7 @@ func normalizeCatalogAttributes(ctx context.Context, plgClient plgpb.HostPluginS // not included in the returned *HostCatalog. // // Both c.CreateTime and c.UpdateTime are ignored. -func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, _ ...Option) (*HostCatalog, *hostplugin.Plugin, error) { +func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, _ ...Option) (*HostCatalog, *plg.Plugin, error) { const op = "plugin.(Repository).CreateCatalog" if c == nil { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "nil HostCatalog") @@ -236,7 +236,7 @@ func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, _ ...Opt // updated, along with any secrets included in the new request. This // request may alter the returned persisted state. Update of the // record in the database is aborted if this call fails. -func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version uint32, fieldMask []string, _ ...Option) (*HostCatalog, *hostplugin.Plugin, int, error) { +func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version uint32, fieldMask []string, _ ...Option) (*HostCatalog, *plg.Plugin, int, error) { const op = "plugin.(Repository).UpdateCatalog" if c == nil { return nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "nil HostCatalog") @@ -570,7 +570,7 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version // LookupCatalog returns the HostCatalog for id. Returns nil, nil if no // HostCatalog is found for id. -func (r *Repository) LookupCatalog(ctx context.Context, id string, _ ...Option) (*HostCatalog, *hostplugin.Plugin, error) { +func (r *Repository) LookupCatalog(ctx context.Context, id string, _ ...Option) (*HostCatalog, *plg.Plugin, error) { const op = "plugin.(Repository).LookupCatalog" if id == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no public id") @@ -590,7 +590,7 @@ func (r *Repository) LookupCatalog(ctx context.Context, id string, _ ...Option) } // ListCatalogs returns a slice of HostCatalogs for the project IDs. WithLimit is the only option supported. -func (r *Repository) ListCatalogs(ctx context.Context, projectIds []string, opt ...host.Option) ([]*HostCatalog, []*hostplugin.Plugin, error) { +func (r *Repository) ListCatalogs(ctx context.Context, projectIds []string, opt ...host.Option) ([]*HostCatalog, []*plg.Plugin, error) { const op = "plugin.(Repository).ListCatalogs" if len(projectIds) == 0 { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no project id") @@ -612,7 +612,7 @@ func (r *Repository) ListCatalogs(ctx context.Context, projectIds []string, opt for _, c := range hostCatalogs { plgIds = append(plgIds, c.PluginId) } - var plgs []*hostplugin.Plugin + var plgs []*plg.Plugin if err := r.reader.SearchWhere(ctx, &plgs, "public_id in (?)", []any{plgIds}); err != nil { return nil, nil, errors.Wrap(ctx, err, op) } @@ -725,12 +725,12 @@ func (r *Repository) getCatalog(ctx context.Context, id string) (*HostCatalog, * return c, p, nil } -func (r *Repository) getPlugin(ctx context.Context, plgId string) (*hostplugin.Plugin, error) { +func (r *Repository) getPlugin(ctx context.Context, plgId string) (*plg.Plugin, error) { const op = "plugin.(Repository).getPlugin" if plgId == "" { return nil, errors.New(ctx, errors.InvalidParameter, op, "no plugin id") } - plg := hostplugin.NewPlugin() + plg := plg.NewPlugin() plg.PublicId = plgId if err := r.reader.LookupByPublicId(ctx, plg); err != nil { return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to get host plugin with id %q", plgId))) @@ -777,7 +777,7 @@ func toPluginCatalog(ctx context.Context, in *HostCatalog) (*pb.HostCatalog, err return hc, nil } -// toPluginCatalog converts a *HostCatalogSecret from storage to a +// toPluginPersistedData converts a *HostCatalogSecret from storage to a // *plgpb.HostCatalogPersisted expected by a plugin. Project Id must be set. func toPluginPersistedData(ctx context.Context, kmsCache *kms.Kms, projectId string, cSecret *HostCatalogSecret) (*plgpb.HostCatalogPersisted, error) { const op = "plugin.(Repository).getPersistedDataForCatalog" diff --git a/internal/host/plugin/repository_host_catalog_test.go b/internal/host/plugin/repository_host_catalog_test.go index 26e051d64..7a42eb029 100644 --- a/internal/host/plugin/repository_host_catalog_test.go +++ b/internal/host/plugin/repository_host_catalog_test.go @@ -20,7 +20,7 @@ import ( "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/libs/patchstruct" "github.com/hashicorp/boundary/internal/oplog" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/scheduler/job" @@ -41,8 +41,8 @@ func TestRepository_CreateCatalog(t *testing.T) { wrapper := db.TestWrapper(t) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") - unimplementedPlugin := hostplugin.TestPlugin(t, conn, "unimplemented") + plg := plugin.TestPlugin(t, conn, "test") + unimplementedPlugin := plugin.TestPlugin(t, conn, "unimplemented") const normalizeToSliceKey = "normalize_to_slice" @@ -495,7 +495,7 @@ func TestRepository_UpdateCatalog(t *testing.T) { var setRespSecretsNil bool var gotOnUpdateCatalogRequest *plgpb.OnUpdateCatalogRequest var pluginError error - testPlugin := hostplugin.TestPlugin(t, dbConn, "test") + testPlugin := plugin.TestPlugin(t, dbConn, "test") testPluginMap := map[string]plgpb.HostPluginServiceClient{ testPlugin.GetPublicId(): &loopback.WrappingPluginHostClient{ Server: &loopback.TestPluginHostServer{ @@ -1232,7 +1232,7 @@ func TestRepository_UpdateCatalog(t *testing.T) { } setRespSecretsNil = tt.withRespSecretsNil - var gotPlugin *hostplugin.Plugin + var gotPlugin *plugin.Plugin gotCatalog, gotPlugin, gotNumUpdated, err = repo.UpdateCatalog(ctx, workingCat, tt.version, tt.fieldMask) if tt.wantIsErr != 0 { require.Equal(db.NoRowsAffected, gotNumUpdated) @@ -1263,7 +1263,7 @@ func TestRepository_LookupCatalog(t *testing.T) { wrapper := db.TestWrapper(t) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): &loopback.WrappingPluginHostClient{Server: &loopback.TestPluginServer{}}, } @@ -1330,7 +1330,7 @@ func TestRepository_ListCatalogs_Multiple_Scopes(t *testing.T) { rw := db.New(conn) kms := kms.TestKms(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): &loopback.WrappingPluginHostClient{Server: &loopback.TestPluginServer{}}, } @@ -1363,7 +1363,7 @@ func TestRepository_DeleteCatalog(t *testing.T) { wrapper := db.TestWrapper(t) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") pluginInstance := &loopback.TestPluginServer{} plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): &loopback.WrappingPluginHostClient{Server: pluginInstance}, @@ -1449,7 +1449,7 @@ func TestRepository_DeleteCatalogX(t *testing.T) { wrapper := db.TestWrapper(t) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplugin.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): &loopback.WrappingPluginHostClient{Server: &loopback.TestPluginServer{}}, } @@ -1537,7 +1537,7 @@ func TestRepository_UpdateCatalog_SyncSets(t *testing.T) { dbKmsCache := kms.TestKms(t, dbConn, dbWrapper) _, projectScope := iam.TestScopes(t, iam.TestRepo(t, dbConn, dbWrapper)) - testPlugin := hostplugin.TestPlugin(t, dbConn, "test") + testPlugin := plugin.TestPlugin(t, dbConn, "test") dummyPluginMap := map[string]plgpb.HostPluginServiceClient{ testPlugin.GetPublicId(): &loopback.WrappingPluginHostClient{Server: &plgpb.UnimplementedHostPluginServiceServer{}}, } diff --git a/internal/host/plugin/repository_host_set.go b/internal/host/plugin/repository_host_set.go index ef93818c9..deec2cd9d 100644 --- a/internal/host/plugin/repository_host_set.go +++ b/internal/host/plugin/repository_host_set.go @@ -17,7 +17,7 @@ import ( "github.com/hashicorp/boundary/internal/libs/endpoint" "github.com/hashicorp/boundary/internal/libs/patchstruct" "github.com/hashicorp/boundary/internal/oplog" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/scheduler" "github.com/hashicorp/boundary/internal/util" pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets" @@ -68,7 +68,7 @@ func normalizeSetAttributes(ctx context.Context, plgClient plgpb.HostPluginServi // // Both s.Name and s.Description are optional. If s.Name is set, it must be // unique within s.CatalogId. -func (r *Repository) CreateSet(ctx context.Context, projectId string, s *HostSet, _ ...Option) (*HostSet, *hostplugin.Plugin, error) { +func (r *Repository) CreateSet(ctx context.Context, projectId string, s *HostSet, _ ...Option) (*HostSet, *plugin.Plugin, error) { const op = "plugin.(Repository).CreateSet" if s == nil { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "nil HostSet") @@ -239,7 +239,7 @@ func (r *Repository) CreateSet(ctx context.Context, projectId string, s *HostSet // record written, but some plugins may perform some actions on this // call. Update of the record in the database is aborted if this call // fails. -func (r *Repository) UpdateSet(ctx context.Context, projectId string, s *HostSet, version uint32, fieldMask []string, opt ...Option) (*HostSet, []*Host, *hostplugin.Plugin, int, error) { +func (r *Repository) UpdateSet(ctx context.Context, projectId string, s *HostSet, version uint32, fieldMask []string, opt ...Option) (*HostSet, []*Host, *plugin.Plugin, int, error) { const op = "plugin.(Repository).UpdateSet" if s == nil { return nil, nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "nil HostSet") @@ -572,7 +572,7 @@ func (r *Repository) UpdateSet(ctx context.Context, projectId string, s *HostSet // LookupSet will look up a host set in the repository and return the host set, // as well as host IDs that match. If the host set is not found, it will return // nil, nil, nil. No options are currently supported. -func (r *Repository) LookupSet(ctx context.Context, publicId string, _ ...host.Option) (*HostSet, *hostplugin.Plugin, error) { +func (r *Repository) LookupSet(ctx context.Context, publicId string, _ ...host.Option) (*HostSet, *plugin.Plugin, error) { const op = "plugin.(Repository).LookupSet" if publicId == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no public id") @@ -595,7 +595,7 @@ func (r *Repository) LookupSet(ctx context.Context, publicId string, _ ...host.O // ListSets returns a slice of HostSets for the catalogId. WithLimit is the // only option supported. -func (r *Repository) ListSets(ctx context.Context, catalogId string, opt ...host.Option) ([]*HostSet, *hostplugin.Plugin, error) { +func (r *Repository) ListSets(ctx context.Context, catalogId string, opt ...host.Option) ([]*HostSet, *plugin.Plugin, error) { const op = "plugin.(Repository).ListSets" if catalogId == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing catalog id") @@ -683,7 +683,7 @@ func (r *Repository) DeleteSet(ctx context.Context, projectId string, publicId s return rowsDeleted, nil } -func (r *Repository) getSets(ctx context.Context, publicId string, catalogId string, opt ...host.Option) ([]*HostSet, *hostplugin.Plugin, error) { +func (r *Repository) getSets(ctx context.Context, publicId string, catalogId string, opt ...host.Option) ([]*HostSet, *plugin.Plugin, error) { const op = "plugin.(Repository).getSets" if publicId == "" && catalogId == "" { return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing search criteria: both host set id and catalog id are empty") @@ -741,7 +741,7 @@ func (r *Repository) getSets(ctx context.Context, publicId string, catalogId str } sets = append(sets, hs) } - var plg *hostplugin.Plugin + var plg *plugin.Plugin if plgId != "" { plg, err = r.getPlugin(ctx, plgId) if err != nil { diff --git a/internal/host/plugin/repository_host_set_test.go b/internal/host/plugin/repository_host_set_test.go index 97a4eb80e..dddd04f36 100644 --- a/internal/host/plugin/repository_host_set_test.go +++ b/internal/host/plugin/repository_host_set_test.go @@ -23,7 +23,7 @@ import ( "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/libs/patchstruct" "github.com/hashicorp/boundary/internal/oplog" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -44,8 +44,8 @@ func TestRepository_CreateSet(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "create") - unimplementedPlugin := hostplg.TestPlugin(t, conn, "unimplemented") + plg := plugin.TestPlugin(t, conn, "create") + unimplementedPlugin := plugin.TestPlugin(t, conn, "unimplemented") catalog := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) unimplementedPluginCatalog := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) @@ -460,7 +460,7 @@ func TestRepository_UpdateSet(t *testing.T) { dbKmsCache := kms.TestKms(t, dbConn, dbWrapper) _, projectScope := iam.TestScopes(t, iam.TestRepo(t, dbConn, dbWrapper)) - testPlugin := hostplg.TestPlugin(t, dbConn, "test") + testPlugin := plugin.TestPlugin(t, dbConn, "test") dummyPluginMap := map[string]plgpb.HostPluginServiceClient{ testPlugin.GetPublicId(): &loopback.WrappingPluginHostClient{Server: &plgpb.UnimplementedHostPluginServiceServer{}}, } @@ -1350,7 +1350,7 @@ func TestRepository_LookupSet(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "lookup") + plg := plugin.TestPlugin(t, conn, "lookup") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } @@ -1419,7 +1419,7 @@ func TestRepository_Endpoints(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "endpoints") + plg := plugin.TestPlugin(t, conn, "endpoints") hostlessCatalog := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) plgm := map[string]plgpb.HostPluginServiceClient{ @@ -1555,7 +1555,7 @@ func TestRepository_ListSets(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "list") + plg := plugin.TestPlugin(t, conn, "list") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } @@ -1627,7 +1627,7 @@ func TestRepository_ListSets_Limits(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "listlimit") + plg := plugin.TestPlugin(t, conn, "listlimit") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), } @@ -1706,7 +1706,7 @@ func TestRepository_DeleteSet(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) sched := scheduler.TestScheduler(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "create") + plg := plugin.TestPlugin(t, conn, "create") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(loopback.TestPluginHostServer{OnCreateSetFn: func(ctx context.Context, req *plgpb.OnCreateSetRequest) (*plgpb.OnCreateSetResponse, error) { diff --git a/internal/host/plugin/repository_host_test.go b/internal/host/plugin/repository_host_test.go index 8209a0baa..b1e0ecaa1 100644 --- a/internal/host/plugin/repository_host_test.go +++ b/internal/host/plugin/repository_host_test.go @@ -19,9 +19,9 @@ import ( "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/oplog" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" - hostplgstore "github.com/hashicorp/boundary/internal/plugin/host/store" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" + plgstore "github.com/hashicorp/boundary/internal/plugin/store" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" "github.com/stretchr/testify/assert" @@ -38,7 +38,7 @@ func TestJob_UpsertHosts(t *testing.T) { iamRepo := iam.TestRepo(t, conn, wrapper) _, prj := iam.TestScopes(t, iamRepo) - plg := hostplg.TestPlugin(t, conn, "create") + plg := plugin.TestPlugin(t, conn, "create") plgm := map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&plgpb.UnimplementedHostPluginServiceServer{}), } @@ -229,7 +229,7 @@ func TestJob_UpsertHosts(t *testing.T) { require.NotNil(repo) // Check again, but via performing an explicit list - var gotPlg *hostplg.Plugin + var gotPlg *plugin.Plugin got, gotPlg, err = repo.ListHostsByCatalogId(ctx, in.catalog.GetPublicId()) require.NoError(err) assert.Len(got, len(in.phs)) @@ -252,7 +252,7 @@ func TestJob_UpsertHosts(t *testing.T) { cmp.Diff( plg, gotPlg, - cmpopts.IgnoreUnexported(hostplg.Plugin{}, hostplgstore.Plugin{}), + cmpopts.IgnoreUnexported(plugin.Plugin{}, plgstore.Plugin{}), cmpopts.IgnoreTypes(×tamp.Timestamp{}), ), ) @@ -280,7 +280,7 @@ func TestJob_UpsertHosts(t *testing.T) { cmp.Diff( plg, gotPlg, - cmpopts.IgnoreUnexported(hostplg.Plugin{}, hostplgstore.Plugin{}), + cmpopts.IgnoreUnexported(plugin.Plugin{}, plgstore.Plugin{}), cmpopts.IgnoreTypes(×tamp.Timestamp{}), ), ) diff --git a/internal/host/plugin/rewrapping_test.go b/internal/host/plugin/rewrapping_test.go index 095f9f74d..137351f3b 100644 --- a/internal/host/plugin/rewrapping_test.go +++ b/internal/host/plugin/rewrapping_test.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/go-kms-wrapping/extras/kms/v2/migrations" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -42,7 +42,7 @@ func TestRewrap_hostCatalogSecretRewrapFn(t *testing.T) { rw := db.New(conn) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId()) secret, err := newHostCatalogSecret(ctx, cat.GetPublicId(), mustStruct(map[string]any{ "foo": "bar", diff --git a/internal/host/plugin/testing.go b/internal/host/plugin/testing.go index 29fe2166b..436d8ea70 100644 --- a/internal/host/plugin/testing.go +++ b/internal/host/plugin/testing.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/boundary/internal/host" "github.com/hashicorp/boundary/internal/host/plugin/store" "github.com/hashicorp/boundary/internal/kms" - hostplugin "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" "github.com/hashicorp/go-secure-stdlib/base62" @@ -48,7 +48,7 @@ func TestCatalog(t testing.TB, conn *db.DB, projectId, pluginId string, opt ...O require.NoError(t, err) assert.NotNil(t, cat) - plg := hostplugin.NewPlugin() + plg := plugin.NewPlugin() plg.PublicId = pluginId require.NoError(t, w.LookupByPublicId(ctx, plg)) @@ -77,7 +77,7 @@ func TestSet(t testing.TB, conn *db.DB, kmsCache *kms.Kms, sched *scheduler.Sche require.NoError(err) require.NotNil(set) - plg := hostplugin.NewPlugin() + plg := plugin.NewPlugin() plg.PublicId = hc.GetPluginId() require.NoError(rw.LookupByPublicId(ctx, plg)) diff --git a/internal/host/plugin/testing_test.go b/internal/host/plugin/testing_test.go index 361d75a69..4a679e295 100644 --- a/internal/host/plugin/testing_test.go +++ b/internal/host/plugin/testing_test.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -27,7 +27,7 @@ func Test_TestCatalogs(t *testing.T) { require.NotNil(proj) assert.NotEmpty(proj.GetPublicId()) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) @@ -48,7 +48,7 @@ func Test_TestSet(t *testing.T) { require.NotNil(prj) assert.NotEmpty(prj.GetPublicId()) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) @@ -66,7 +66,7 @@ func Test_TestHosts(t *testing.T) { wrapper := db.TestWrapper(t) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) @@ -89,7 +89,7 @@ func Test_TestSetMembers(t *testing.T) { require.NotNil(prj) assert.NotEmpty(prj.GetPublicId()) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) @@ -113,7 +113,7 @@ func Test_TestRunSetSync(t *testing.T) { require.NotNil(prj) assert.NotEmpty(prj.GetPublicId()) - plg := host.TestPlugin(t, conn, "test") + plg := plugin.TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) pluginServer := &loopback.TestPluginServer{} diff --git a/internal/host/preferred_endpoint_test.go b/internal/host/preferred_endpoint_test.go index 8e7139d11..9af773ae0 100644 --- a/internal/host/preferred_endpoint_test.go +++ b/internal/host/preferred_endpoint_test.go @@ -10,10 +10,10 @@ import ( "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/host" - "github.com/hashicorp/boundary/internal/host/plugin" + hostplugin "github.com/hashicorp/boundary/internal/host/plugin" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - hostplg "github.com/hashicorp/boundary/internal/plugin/host" + "github.com/hashicorp/boundary/internal/plugin" "github.com/hashicorp/boundary/internal/plugin/loopback" "github.com/hashicorp/boundary/internal/scheduler" plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin" @@ -31,9 +31,9 @@ func TestPreferredEndpoint_Create(t *testing.T) { kmsCache := kms.TestKms(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplg.TestPlugin(t, conn, "create") - catalog := plugin.TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) - set := plugin.TestSet(t, conn, kmsCache, sched, catalog, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, "create") + catalog := hostplugin.TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) + set := hostplugin.TestSet(t, conn, kmsCache, sched, catalog, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&loopback.TestPluginServer{}), }) @@ -162,9 +162,9 @@ func TestPreferredEndpoint_Delete(t *testing.T) { kmsCache := kms.TestKms(t, conn, wrapper) _, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) - plg := hostplg.TestPlugin(t, conn, "create") - catalog := plugin.TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) - set := plugin.TestSet(t, conn, kmsCache, sched, catalog, map[string]plgpb.HostPluginServiceClient{ + plg := plugin.TestPlugin(t, conn, "create") + catalog := hostplugin.TestCatalog(t, conn, prj.PublicId, plg.GetPublicId()) + set := hostplugin.TestSet(t, conn, kmsCache, sched, catalog, map[string]plgpb.HostPluginServiceClient{ plg.GetPublicId(): loopback.NewWrappingPluginHostClient(&plgpb.UnimplementedHostPluginServiceServer{}), }) diff --git a/internal/plugin/host/doc.go b/internal/plugin/host/doc.go deleted file mode 100644 index 653404f11..000000000 --- a/internal/plugin/host/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Package host provides a plugin type used to interface with boundary's host -// related resources. Additionally it provides a repository for performing -// CRUDL and custom operations on this plugin type. -package host diff --git a/internal/plugin/host/immutable_fields_test.go b/internal/plugin/host/immutable_fields_test.go deleted file mode 100644 index f857a10a7..000000000 --- a/internal/plugin/host/immutable_fields_test.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package host - -import ( - "context" - "testing" - - "github.com/hashicorp/boundary/internal/db" - "github.com/hashicorp/boundary/internal/db/timestamp" - "github.com/hashicorp/boundary/internal/plugin/host/store" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/types/known/timestamppb" -) - -func TestHostPlugin_ImmutableFields(t *testing.T) { - t.Parallel() - conn, _ := db.TestSetup(t, "postgres") - w := db.New(conn) - - ts := timestamp.Timestamp{Timestamp: ×tamppb.Timestamp{Seconds: 0, Nanos: 0}} - plg := TestPlugin(t, conn, "test") - - newPlugin := plg - - tests := []struct { - name string - update *Plugin - fieldMask []string - }{ - { - name: "public_id", - update: func() *Plugin { - c := newPlugin.testClonePlugin() - c.PublicId = "hc_thisIsNotAValidId" - return c - }(), - fieldMask: []string{"PublicId"}, - }, - { - name: "create time", - update: func() *Plugin { - c := newPlugin.testClonePlugin() - c.CreateTime = &ts - return c - }(), - fieldMask: []string{"CreateTime"}, - }, - } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - assert, require := assert.New(t), require.New(t) - orig := newPlugin.testClonePlugin() - err := w.LookupById(context.Background(), orig) - require.NoError(err) - - rowsUpdated, err := w.Update(context.Background(), tt.update, tt.fieldMask, nil, db.WithSkipVetForWrite(true)) - require.Error(err) - assert.Equal(0, rowsUpdated) - - after := newPlugin.testClonePlugin() - err = w.LookupById(context.Background(), after) - require.NoError(err) - - assert.True(proto.Equal(orig, after)) - }) - } -} - -func (c *Plugin) testClonePlugin() *Plugin { - cp := proto.Clone(c.Plugin) - return &Plugin{ - Plugin: cp.(*store.Plugin), - } -} diff --git a/internal/plugin/host/store/plugin.pb.go b/internal/plugin/host/store/plugin.pb.go deleted file mode 100644 index 2d6f46890..000000000 --- a/internal/plugin/host/store/plugin.pb.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: controller/storage/plugin/host/store/v1/plugin.proto - -// Package store provides protobufs for storing types in the host package. - -package store - -import ( - timestamp "github.com/hashicorp/boundary/internal/db/timestamp" - _ "github.com/hashicorp/boundary/sdk/pbs/controller/protooptions" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Plugin struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // public_id is a surrogate key suitable for use in a public API. - // @inject_tag: `gorm:"primary_key"` - PublicId string `protobuf:"bytes,10,opt,name=public_id,json=publicId,proto3" json:"public_id,omitempty" gorm:"primary_key"` - // The create_time is set by the database. - // @inject_tag: `gorm:"default:current_timestamp"` - CreateTime *timestamp.Timestamp `protobuf:"bytes,20,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" gorm:"default:current_timestamp"` - // The update_time is set by the database. - // @inject_tag: `gorm:"default:current_timestamp"` - UpdateTime *timestamp.Timestamp `protobuf:"bytes,30,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty" gorm:"default:current_timestamp"` - // name is optional. If set, it must be unique within scope_id. - // @inject_tag: `gorm:"default:null"` - Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty" gorm:"default:null"` - // description is optional. - // @inject_tag: `gorm:"default:null"` - Description string `protobuf:"bytes,50,opt,name=description,proto3" json:"description,omitempty" gorm:"default:null"` - // The scope_id of the owning scope and must be set. - // @inject_tag: `gorm:"not_null"` - ScopeId string `protobuf:"bytes,60,opt,name=scope_id,json=scopeId,proto3" json:"scope_id,omitempty" gorm:"not_null"` - // @inject_tag: `gorm:"default:null"` - Version uint32 `protobuf:"varint,70,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"` -} - -func (x *Plugin) Reset() { - *x = Plugin{} - if protoimpl.UnsafeEnabled { - mi := &file_controller_storage_plugin_host_store_v1_plugin_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Plugin) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Plugin) ProtoMessage() {} - -func (x *Plugin) ProtoReflect() protoreflect.Message { - mi := &file_controller_storage_plugin_host_store_v1_plugin_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 Plugin.ProtoReflect.Descriptor instead. -func (*Plugin) Descriptor() ([]byte, []int) { - return file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescGZIP(), []int{0} -} - -func (x *Plugin) GetPublicId() string { - if x != nil { - return x.PublicId - } - return "" -} - -func (x *Plugin) GetCreateTime() *timestamp.Timestamp { - if x != nil { - return x.CreateTime - } - return nil -} - -func (x *Plugin) GetUpdateTime() *timestamp.Timestamp { - if x != nil { - return x.UpdateTime - } - return nil -} - -func (x *Plugin) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Plugin) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *Plugin) GetScopeId() string { - if x != nil { - return x.ScopeId - } - return "" -} - -func (x *Plugin) GetVersion() uint32 { - if x != nil { - return x.Version - } - return 0 -} - -var File_controller_storage_plugin_host_store_v1_plugin_proto protoreflect.FileDescriptor - -var file_controller_storage_plugin_host_store_v1_plugin_proto_rawDesc = []byte{ - 0x0a, 0x34, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x68, 0x6f, 0x73, 0x74, - 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, - 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, - 0x6e, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, - 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, - 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 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, 0xdc, 0x02, 0x0a, - 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 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, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x18, 0x14, 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, 0x1e, 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, 0x24, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd, - 0x29, 0x0c, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x32, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, - 0x0b, 0x44, 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, 0x19, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x3c, 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, 0x46, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x40, 0x5a, 0x3e, 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, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x68, 0x6f, 0x73, - 0x74, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescOnce sync.Once - file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescData = file_controller_storage_plugin_host_store_v1_plugin_proto_rawDesc -) - -func file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescGZIP() []byte { - file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescOnce.Do(func() { - file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescData) - }) - return file_controller_storage_plugin_host_store_v1_plugin_proto_rawDescData -} - -var file_controller_storage_plugin_host_store_v1_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_controller_storage_plugin_host_store_v1_plugin_proto_goTypes = []interface{}{ - (*Plugin)(nil), // 0: controller.storage.plugin.host.store.v1.Plugin - (*timestamp.Timestamp)(nil), // 1: controller.storage.timestamp.v1.Timestamp -} -var file_controller_storage_plugin_host_store_v1_plugin_proto_depIdxs = []int32{ - 1, // 0: controller.storage.plugin.host.store.v1.Plugin.create_time:type_name -> controller.storage.timestamp.v1.Timestamp - 1, // 1: controller.storage.plugin.host.store.v1.Plugin.update_time:type_name -> controller.storage.timestamp.v1.Timestamp - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_controller_storage_plugin_host_store_v1_plugin_proto_init() } -func file_controller_storage_plugin_host_store_v1_plugin_proto_init() { - if File_controller_storage_plugin_host_store_v1_plugin_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_controller_storage_plugin_host_store_v1_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Plugin); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_controller_storage_plugin_host_store_v1_plugin_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_controller_storage_plugin_host_store_v1_plugin_proto_goTypes, - DependencyIndexes: file_controller_storage_plugin_host_store_v1_plugin_proto_depIdxs, - MessageInfos: file_controller_storage_plugin_host_store_v1_plugin_proto_msgTypes, - }.Build() - File_controller_storage_plugin_host_store_v1_plugin_proto = out.File - file_controller_storage_plugin_host_store_v1_plugin_proto_rawDesc = nil - file_controller_storage_plugin_host_store_v1_plugin_proto_goTypes = nil - file_controller_storage_plugin_host_store_v1_plugin_proto_depIdxs = nil -} diff --git a/internal/plugin/host/testing.go b/internal/plugin/host/testing.go deleted file mode 100644 index d77b370dd..000000000 --- a/internal/plugin/host/testing.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package host - -import ( - "context" - "testing" - - "github.com/hashicorp/boundary/internal/db" - "github.com/stretchr/testify/require" -) - -func TestPlugin(t testing.TB, conn *db.DB, name string) *Plugin { - t.Helper() - p := NewPlugin(WithName(name)) - id, err := newPluginId() - require.NoError(t, err) - p.PublicId = id - - w := db.New(conn) - require.NoError(t, w.Create(context.Background(), p)) - return p -} diff --git a/internal/plugin/host/testing_test.go b/internal/plugin/host/testing_test.go deleted file mode 100644 index 5d79c24cc..000000000 --- a/internal/plugin/host/testing_test.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package host - -import ( - "testing" - - "github.com/hashicorp/boundary/internal/db" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func Test_TestPlugins(t *testing.T) { - assert, require := assert.New(t), require.New(t) - conn, _ := db.TestSetup(t, "postgres") - - plg := TestPlugin(t, conn, "test") - require.NotNil(plg) - assert.NotEmpty(plg.GetPublicId()) -} diff --git a/internal/plugin/host/ids.go b/internal/plugin/ids.go similarity index 96% rename from internal/plugin/host/ids.go rename to internal/plugin/ids.go index 513529aaa..dce9587fd 100644 --- a/internal/plugin/host/ids.go +++ b/internal/plugin/ids.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "github.com/hashicorp/boundary/internal/db" diff --git a/internal/plugin/immutable_fields_test.go b/internal/plugin/immutable_fields_test.go index e2dcc89a1..930f04abc 100644 --- a/internal/plugin/immutable_fields_test.go +++ b/internal/plugin/immutable_fields_test.go @@ -8,42 +8,46 @@ import ( "testing" "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/db/timestamp" "github.com/hashicorp/boundary/internal/plugin/store" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" ) -func TestPlugin_ImmutableFields(t *testing.T) { +func TestHostPlugin_ImmutableFields(t *testing.T) { t.Parallel() conn, _ := db.TestSetup(t, "postgres") w := db.New(conn) - plg := testPlugin(t, conn, "test") + + ts := timestamp.Timestamp{Timestamp: ×tamppb.Timestamp{Seconds: 0, Nanos: 0}} + plg := TestPlugin(t, conn, "test") newPlugin := plg tests := []struct { name string - update *plugin + update *Plugin fieldMask []string }{ { name: "public_id", - update: func() *plugin { + update: func() *Plugin { c := newPlugin.testClonePlugin() - c.PublicId = "pi_thisIsNotAValidId" + c.PublicId = "hc_thisIsNotAValidId" return c }(), fieldMask: []string{"PublicId"}, }, { - name: "scope", - update: func() *plugin { + name: "create time", + update: func() *Plugin { c := newPlugin.testClonePlugin() - c.ScopeId = "o_1234567890" + c.CreateTime = &ts return c }(), - fieldMask: []string{"ScopeId"}, + fieldMask: []string{"CreateTime"}, }, } for _, tt := range tests { @@ -67,9 +71,9 @@ func TestPlugin_ImmutableFields(t *testing.T) { } } -func (c *plugin) testClonePlugin() *plugin { +func (c *Plugin) testClonePlugin() *Plugin { cp := proto.Clone(c.Plugin) - return &plugin{ + return &Plugin{ Plugin: cp.(*store.Plugin), } } diff --git a/internal/plugin/host/options.go b/internal/plugin/options.go similarity index 98% rename from internal/plugin/host/options.go rename to internal/plugin/options.go index ce6ed24f9..57aadd06f 100644 --- a/internal/plugin/host/options.go +++ b/internal/plugin/options.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin // GetOpts - iterate the inbound Options and return a struct func GetOpts(opt ...Option) options { diff --git a/internal/plugin/host/options_test.go b/internal/plugin/options_test.go similarity index 98% rename from internal/plugin/host/options_test.go rename to internal/plugin/options_test.go index e7e29c1ee..7f5de942e 100644 --- a/internal/plugin/host/options_test.go +++ b/internal/plugin/options_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "testing" diff --git a/internal/plugin/host/plugin.go b/internal/plugin/plugin.go similarity index 64% rename from internal/plugin/host/plugin.go rename to internal/plugin/plugin.go index c53933f40..cbc5b9b48 100644 --- a/internal/plugin/host/plugin.go +++ b/internal/plugin/plugin.go @@ -1,15 +1,48 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "github.com/hashicorp/boundary/internal/oplog" - "github.com/hashicorp/boundary/internal/plugin/host/store" + "github.com/hashicorp/boundary/internal/plugin/store" "github.com/hashicorp/boundary/internal/types/scope" "google.golang.org/protobuf/proto" ) +type PluginType int + +const ( + PluginTypeUnknown PluginType = 0 + PluginTypeHost PluginType = 1 + PluginTypeStorage PluginType = 2 +) + +type pluginHostSupported struct { + PublicId string `gorm:"primary_key"` +} + +func (*pluginHostSupported) isPluginSupported() {} +func (*pluginHostSupported) TableName() string { + return "plugin_host_supported" +} + +type pluginStorageSupported struct { + PublicId string `gorm:"primary_key"` +} + +func (*pluginStorageSupported) isPluginSupported() {} +func (*pluginStorageSupported) TableName() string { + return "plugin_storage_supported" +} + +// pluginSupportedTable is a special type created just to insert +// plugin flags in a safe way. the only structs that implement +// this should be above. new plugins should be added above. +type pluginSupportedTable interface { + isPluginSupported() +} + // A Plugin enables additional logic to be used by boundary. // It is owned by a scope. type Plugin struct { @@ -36,7 +69,7 @@ func (c *Plugin) TableName() string { if c.tableName != "" { return c.tableName } - return "plugin_host" + return "plugin" } // SetTableName sets the table name. If the caller attempts to diff --git a/internal/plugin/host/plugin_test.go b/internal/plugin/plugin_test.go similarity index 96% rename from internal/plugin/host/plugin_test.go rename to internal/plugin/plugin_test.go index c970a11d6..00b65ff68 100644 --- a/internal/plugin/host/plugin_test.go +++ b/internal/plugin/plugin_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "context" @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/require" "github.com/hashicorp/boundary/internal/db" - "github.com/hashicorp/boundary/internal/plugin/host/store" + "github.com/hashicorp/boundary/internal/plugin/store" ) func TestPlugin_Create(t *testing.T) { @@ -121,7 +121,7 @@ func TestPlugin_Delete(t *testing.T) { } func TestPlugin_SetTableName(t *testing.T) { - defaultTableName := "plugin_host" + defaultTableName := "plugin" tests := []struct { name string initialName string diff --git a/internal/plugin/host/repository.go b/internal/plugin/repository.go similarity index 70% rename from internal/plugin/host/repository.go rename to internal/plugin/repository.go index 3660a2525..6a4894ae8 100644 --- a/internal/plugin/host/repository.go +++ b/internal/plugin/repository.go @@ -1,12 +1,15 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( + "context" + "github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/util" ) // A Repository stores and retrieves the persistent types in the host @@ -24,15 +27,15 @@ type Repository struct { // only be used for one transaction and it is not safe for concurrent go // routines to access it. WithLimit option is used as a repo wide default // limit applied to all ListX methods. -func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repository, error) { +func NewRepository(ctx context.Context, r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repository, error) { const op = "static.NewRepository" switch { - case r == nil: - return nil, errors.NewDeprecated(errors.InvalidParameter, op, "db.Reader") - case w == nil: - return nil, errors.NewDeprecated(errors.InvalidParameter, op, "db.Writer") - case kms == nil: - return nil, errors.NewDeprecated(errors.InvalidParameter, op, "kms") + case util.IsNil(r): + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil db.Reader") + case util.IsNil(w): + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil db.Writer") + case util.IsNil(kms): + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil kms") } opts := GetOpts(opt...) diff --git a/internal/plugin/host/repository_plugin.go b/internal/plugin/repository_plugin.go similarity index 74% rename from internal/plugin/host/repository_plugin.go rename to internal/plugin/repository_plugin.go index 42fc36be0..1072b215e 100644 --- a/internal/plugin/host/repository_plugin.go +++ b/internal/plugin/repository_plugin.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "context" @@ -17,27 +17,26 @@ import ( // CreatePlugin inserts p into the repository and returns a new // Plugin containing the plugin's PublicId. p is not changed. p must // contain a valid ScopeID. p must not contain a PublicId. The PublicId is -// generated and assigned by this method. opt is ignored. +// generated and assigned by this method, unless supplied by WithPublicId // // Both p.Name and p.Description are optional. If p.Name is set, it must be // unique within p.ScopeID. // -// Both p.CreateTime and c.UpdateTime are ignored. +// p.CreateTime, p.UpdateTime, and p.Version are ignored and populated on creation. +// +// Supported options: WithPublicId func (r *Repository) CreatePlugin(ctx context.Context, p *Plugin, opt ...Option) (*Plugin, error) { - const op = "host.(Repository).CreatePlugin" - if p == nil { + const op = "plugin.(Repository).CreatePlugin" + switch { + case p == nil: return nil, errors.New(ctx, errors.InvalidParameter, op, "nil Plugin") - } - if p.Plugin == nil { + case p.Plugin == nil: return nil, errors.New(ctx, errors.InvalidParameter, op, "nil embedded Plugin") - } - if p.ScopeId == "" { + case p.ScopeId == "": return nil, errors.New(ctx, errors.InvalidParameter, op, "no scope id") - } - if p.ScopeId != scope.Global.String() { + case p.ScopeId != scope.Global.String(): return nil, errors.New(ctx, errors.InvalidParameter, op, "scope id is not 'global'") - } - if p.PublicId != "" { + case p.PublicId != "": return nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty") } p = p.clone() @@ -73,7 +72,7 @@ func (r *Repository) CreatePlugin(ctx context.Context, p *Plugin, opt ...Option) db.WithOplog(oplogWrapper, metadata), ) if err != nil { - return errors.Wrap(ctx, err, op) + return err } return nil }, @@ -91,7 +90,7 @@ func (r *Repository) CreatePlugin(ctx context.Context, p *Plugin, opt ...Option) // LookupPlugin returns the Plugin for id. Returns nil, nil if no // Plugin is found for id. func (r *Repository) LookupPlugin(ctx context.Context, id string, _ ...Option) (*Plugin, error) { - const op = "host.(Repository).LookupPlugin" + const op = "plugin.(Repository).LookupPlugin" if id == "" { return nil, errors.New(ctx, errors.InvalidParameter, op, "no public id") } @@ -109,7 +108,7 @@ func (r *Repository) LookupPlugin(ctx context.Context, id string, _ ...Option) ( // LookupPluginByName returns the Plugin for a given name. Returns nil, nil if no // Plugin is found with that plugin name. func (r *Repository) LookupPluginByName(ctx context.Context, name string, _ ...Option) (*Plugin, error) { - const op = "host.(Repository).LookupPluginByName" + const op = "plugin.(Repository).LookupPluginByName" if name == "" { return nil, errors.New(ctx, errors.InvalidParameter, op, "no plugin name") } @@ -126,7 +125,7 @@ func (r *Repository) LookupPluginByName(ctx context.Context, name string, _ ...O // ListPlugins returns a slice of Plugins for the scope IDs. WithLimit is the only option supported. func (r *Repository) ListPlugins(ctx context.Context, scopeIds []string, opt ...Option) ([]*Plugin, error) { - const op = "host.(Repository).ListPlugins" + const op = "plugin.(Repository).ListPlugins" if len(scopeIds) == 0 { return nil, errors.New(ctx, errors.InvalidParameter, op, "no scope id") } @@ -143,3 +142,34 @@ func (r *Repository) ListPlugins(ctx context.Context, scopeIds []string, opt ... } return plugins, nil } + +// AddSupportFlag adds a flag in the database for the current plugin to specify that it is capable +// of that type's functions +func (r *Repository) AddSupportFlag(ctx context.Context, plugin *Plugin, flag PluginType) error { + const op = "plugin.(Repository).AddSupportFlag" + + var p pluginSupportedTable + + switch flag { + case PluginTypeHost: + p = &pluginHostSupported{ + PublicId: plugin.GetPublicId(), + } + case PluginTypeStorage: + p = &pluginStorageSupported{ + PublicId: plugin.GetPublicId(), + } + default: + return errors.New(ctx, errors.InvalidParameter, op, "plugin type does not exist") + } + + if err := r.writer.Create(ctx, p, db.WithOnConflict( + &db.OnConflict{ + Target: db.Columns{"public_id"}, + Action: db.DoNothing(true), + }, + )); err != nil { + return errors.Wrap(ctx, err, op) + } + return nil +} diff --git a/internal/plugin/host/repository_plugin_test.go b/internal/plugin/repository_plugin_test.go similarity index 55% rename from internal/plugin/host/repository_plugin_test.go rename to internal/plugin/repository_plugin_test.go index a3ecbb65a..2dcd51bae 100644 --- a/internal/plugin/host/repository_plugin_test.go +++ b/internal/plugin/repository_plugin_test.go @@ -1,10 +1,11 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( "context" + "fmt" "strings" "testing" @@ -12,7 +13,7 @@ import ( "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/kms" - "github.com/hashicorp/boundary/internal/plugin/host/store" + "github.com/hashicorp/boundary/internal/plugin/store" "github.com/hashicorp/boundary/internal/types/scope" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -24,25 +25,54 @@ func TestRepository_CreatePlugin(t *testing.T) { wrapper := db.TestWrapper(t) iam.TestRepo(t, conn, wrapper) kmsCache := kms.TestKms(t, conn, wrapper) - repo, err := NewRepository(rw, rw, kmsCache) + ctx := context.Background() + repo, err := NewRepository(ctx, rw, rw, kmsCache) assert.NoError(t, err) assert.NotNil(t, repo) tests := []struct { - name string - in *Plugin - opts []Option - want *Plugin - wantIsErr errors.Code + name string + in *Plugin + opts []Option + want *Plugin + wantErr string }{ { - name: "nil-plugin", - wantIsErr: errors.InvalidParameter, + name: "nil-plugin", + wantErr: "nil Plugin", }, { - name: "nil-embedded-plugin", - in: &Plugin{}, - wantIsErr: errors.InvalidParameter, + name: "nil-embedded-plugin", + in: &Plugin{}, + wantErr: "nil embedded Plugin", + }, + { + name: "no-scope-id", + in: &Plugin{ + Plugin: &store.Plugin{ + ScopeId: "", + }, + }, + wantErr: "no scope id", + }, + { + name: "non-global-scope", + in: &Plugin{ + Plugin: &store.Plugin{ + ScopeId: "o_1234567890", + }, + }, + wantErr: "scope id is not 'global'", + }, + { + name: "public-id-not-empty", + in: &Plugin{ + Plugin: &store.Plugin{ + PublicId: "biscuit", + ScopeId: "global", + }, + }, + wantErr: "public id not empty", }, { name: "valid-with-name", @@ -74,15 +104,6 @@ func TestRepository_CreatePlugin(t *testing.T) { }, }, }, - { - name: "non-global-scope", - in: &Plugin{ - Plugin: &store.Plugin{ - ScopeId: "o_1234567890", - }, - }, - wantIsErr: errors.InvalidParameter, - }, } for _, tt := range tests { @@ -90,8 +111,8 @@ func TestRepository_CreatePlugin(t *testing.T) { t.Run(tt.name, func(t *testing.T) { assert := assert.New(t) got, err := repo.CreatePlugin(context.Background(), tt.in, tt.opts...) - if tt.wantIsErr != 0 { - assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err) + if tt.wantErr != "" { + assert.ErrorContains(err, tt.wantErr) assert.Nil(got) return } @@ -110,7 +131,8 @@ func TestRepository_CreatePlugin(t *testing.T) { t.Run("invalid-duplicate-names", func(t *testing.T) { assert := assert.New(t) kms := kms.TestKms(t, conn, wrapper) - repo, err := NewRepository(rw, rw, kms) + ctx := context.Background() + repo, err := NewRepository(ctx, rw, rw, kms) assert.NoError(err) assert.NotNil(repo) in := &Plugin{ @@ -181,7 +203,8 @@ func TestRepository_LookupPlugin(t *testing.T) { t.Run(tt.name, func(t *testing.T) { assert := assert.New(t) kms := kms.TestKms(t, conn, wrapper) - repo, err := NewRepository(rw, rw, kms) + ctx := context.Background() + repo, err := NewRepository(ctx, rw, rw, kms) assert.NoError(err) assert.NotNil(repo) @@ -213,7 +236,7 @@ func TestRepository_LookupPluginByName(t *testing.T) { name string pluginName string want *Plugin - wantErr errors.Code + wantErr string }{ { name: "found", @@ -229,7 +252,7 @@ func TestRepository_LookupPluginByName(t *testing.T) { name: "emptyname", pluginName: "", want: nil, - wantErr: errors.InvalidParameter, + wantErr: "no plugin name", }, } @@ -238,13 +261,15 @@ func TestRepository_LookupPluginByName(t *testing.T) { t.Run(tt.name, func(t *testing.T) { assert := assert.New(t) kms := kms.TestKms(t, conn, wrapper) - repo, err := NewRepository(rw, rw, kms) + ctx := context.Background() + repo, err := NewRepository(ctx, rw, rw, kms) assert.NoError(err) assert.NotNil(repo) got, err := repo.LookupPluginByName(context.Background(), tt.pluginName) - if tt.wantErr != 0 { - assert.Truef(errors.Match(errors.T(tt.wantErr), err), "want err: %q got: %q", tt.wantErr, err) + if tt.wantErr != "" { + assert.ErrorContains(err, tt.wantErr) + assert.Nil(got) return } assert.NoError(err) @@ -259,3 +284,126 @@ func TestRepository_LookupPluginByName(t *testing.T) { }) } } + +func TestRepository_AddSupportFlag(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrapper := db.TestWrapper(t) + + tests := []struct { + name string + pluginName string + table string + flag PluginType + flagExists bool + forceErr bool + err string + }{ + { + name: "flag doesn't exist and is added", + pluginName: "test1", + table: "plugin_host_supported", + flag: PluginTypeHost, + flagExists: false, + forceErr: false, + err: "", + }, + { + name: "flag exists and is unchanged", + pluginName: "test2", + table: "plugin_host_supported", + flag: PluginTypeHost, + flagExists: true, + forceErr: false, + err: "", + }, + { + name: "err thrown and is handled", + pluginName: "test3", + table: "plugin_host_supported", + flag: PluginTypeHost, + flagExists: false, + forceErr: true, + err: "wt_plugin_id_check constraint failed", + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + ctx := context.Background() + + // require.Contains(pluginTypeDbMap, tt.flag) + plg := TestPlugin(t, conn, tt.pluginName, WithHostFlag(tt.flagExists)) + + // check to make sure the start state is as expected + rows, err := rw.Query(ctx, fmt.Sprintf("select public_id from %s where public_id = ?;", tt.table), []any{plg.PublicId}) + require.NoError(err) + + rowCount := 0 + var plgid string + + for rows.Next() { + rowCount++ + require.NoError(rows.Scan(&plgid)) + } + + if tt.flagExists { + assert.Equal(1, rowCount) + assert.Equal(plg.PublicId, plgid) + } else { + assert.Equal(0, rowCount) + assert.Equal("", plgid) + } + + // create the plugin repo + kms := kms.TestKms(t, conn, wrapper) + repo, err := NewRepository(ctx, rw, rw, kms) + assert.NoError(err) + assert.NotNil(repo) + + if tt.forceErr { + plg.PublicId = "biscuit" + } + + // do the thing + err = repo.AddSupportFlag(ctx, plg, tt.flag) + + if tt.err != "" { + require.ErrorContains(err, tt.err) + return + } + require.NoError(err) + + // check to make sure the end state is as expected + rows, err = rw.Query(ctx, fmt.Sprintf("select public_id from %s where public_id = ?;", tt.table), []any{plg.PublicId}) + require.NoError(err) + rowCount = 0 + for rows.Next() { + rowCount++ + } + assert.Equal(1, rowCount) + }) + } + + // this needs it's own test becaues of the setup required for above tests + t.Run("plugin type unknown", func(t *testing.T) { + assert := assert.New(t) + require := require.New(t) + ctx := context.Background() + plg := TestPlugin(t, conn, "test12345") + + // create the plugin repo + kms := kms.TestKms(t, conn, wrapper) + repo, err := NewRepository(ctx, rw, rw, kms) + assert.NoError(err) + assert.NotNil(repo) + + // do the thing + err = repo.AddSupportFlag(ctx, plg, PluginTypeUnknown) + + require.ErrorContains(err, "plugin type does not exist: parameter violation") + }) +} diff --git a/internal/plugin/host/repository_test.go b/internal/plugin/repository_test.go similarity index 74% rename from internal/plugin/host/repository_test.go rename to internal/plugin/repository_test.go index 6e1ed3117..ed5b5cd06 100644 --- a/internal/plugin/host/repository_test.go +++ b/internal/plugin/repository_test.go @@ -1,16 +1,16 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package host +package plugin import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/hashicorp/boundary/internal/db" - "github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/kms" ) @@ -28,10 +28,10 @@ func TestRepository_New(t *testing.T) { } tests := []struct { - name string - args args - want *Repository - wantIsErr errors.Code + name string + args args + want *Repository + wantErr string }{ { name: "valid", @@ -69,8 +69,8 @@ func TestRepository_New(t *testing.T) { w: rw, kms: kmsCache, }, - want: nil, - wantIsErr: errors.InvalidParameter, + want: nil, + wantErr: "nil db.Reader", }, { name: "nil-writer", @@ -79,8 +79,8 @@ func TestRepository_New(t *testing.T) { w: nil, kms: kmsCache, }, - want: nil, - wantIsErr: errors.InvalidParameter, + want: nil, + wantErr: "nil db.Writer", }, { name: "nil-kms", @@ -89,8 +89,8 @@ func TestRepository_New(t *testing.T) { w: rw, kms: nil, }, - want: nil, - wantIsErr: errors.InvalidParameter, + want: nil, + wantErr: "nil kms", }, { name: "all-nils", @@ -99,17 +99,18 @@ func TestRepository_New(t *testing.T) { w: nil, kms: nil, }, - want: nil, - wantIsErr: errors.InvalidParameter, + want: nil, + wantErr: "nil db.Reader", // the first param in the switch }, } for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { assert, require := assert.New(t), require.New(t) - got, err := NewRepository(tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...) - if tt.wantIsErr != 0 { - assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err) + ctx := context.Background() + got, err := NewRepository(ctx, tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...) + if tt.wantErr != "" { + assert.ErrorContains(err, tt.wantErr) assert.Nil(got) return } diff --git a/internal/plugin/store/plugin.pb.go b/internal/plugin/store/plugin.pb.go index 7112aafab..707815212 100644 --- a/internal/plugin/store/plugin.pb.go +++ b/internal/plugin/store/plugin.pb.go @@ -12,6 +12,8 @@ package store import ( + timestamp "github.com/hashicorp/boundary/internal/db/timestamp" + _ "github.com/hashicorp/boundary/sdk/pbs/controller/protooptions" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" @@ -25,8 +27,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// This is a typeless plugin. In practice this should never be used directly. -// This is included for testing purposes only. type Plugin struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -41,6 +41,17 @@ type Plugin struct { // name is optional. If set, it must be unique within scope_id. // @inject_tag: `gorm:"default:null"` Name string `protobuf:"bytes,30,opt,name=name,proto3" json:"name,omitempty" gorm:"default:null"` + // description is optional. + // @inject_tag: `gorm:"default:null"` + Description string `protobuf:"bytes,40,opt,name=description,proto3" json:"description,omitempty" gorm:"default:null"` + // The create_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + CreateTime *timestamp.Timestamp `protobuf:"bytes,50,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" gorm:"default:current_timestamp"` + // The update_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + UpdateTime *timestamp.Timestamp `protobuf:"bytes,60,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty" gorm:"default:current_timestamp"` + // @inject_tag: `gorm:"default:null"` + Version uint32 `protobuf:"varint,70,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"` } func (x *Plugin) Reset() { @@ -96,6 +107,34 @@ func (x *Plugin) GetName() string { return "" } +func (x *Plugin) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *Plugin) GetCreateTime() *timestamp.Timestamp { + if x != nil { + return x.CreateTime + } + return nil +} + +func (x *Plugin) GetUpdateTime() *timestamp.Timestamp { + if x != nil { + return x.UpdateTime + } + return nil +} + +func (x *Plugin) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + var File_controller_storage_plugin_store_v1_plugin_proto protoreflect.FileDescriptor var file_controller_storage_plugin_store_v1_plugin_proto_rawDesc = []byte{ @@ -104,16 +143,39 @@ var file_controller_storage_plugin_store_v1_plugin_proto_rawDesc = []byte{ 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x2e, 0x76, 0x31, 0x22, 0x54, 0x0a, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 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, 0x19, 0x0a, 0x08, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x73, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x1e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x3b, 0x5a, 0x39, 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, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 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, 0xdc, 0x02, 0x0a, 0x06, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 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, 0x19, 0x0a, 0x08, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x63, + 0x6f, 0x70, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x1e, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd, 0x29, 0x0c, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x28, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x44, 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, 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, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x46, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x42, 0x3b, 0x5a, 0x39, 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, 0x70, 0x6c, 0x75, 0x67, + 0x69, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -130,14 +192,17 @@ func file_controller_storage_plugin_store_v1_plugin_proto_rawDescGZIP() []byte { var file_controller_storage_plugin_store_v1_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_controller_storage_plugin_store_v1_plugin_proto_goTypes = []interface{}{ - (*Plugin)(nil), // 0: controller.storage.plugin.store.v1.Plugin + (*Plugin)(nil), // 0: controller.storage.plugin.store.v1.Plugin + (*timestamp.Timestamp)(nil), // 1: controller.storage.timestamp.v1.Timestamp } var file_controller_storage_plugin_store_v1_plugin_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 1, // 0: controller.storage.plugin.store.v1.Plugin.create_time:type_name -> controller.storage.timestamp.v1.Timestamp + 1, // 1: controller.storage.plugin.store.v1.Plugin.update_time:type_name -> controller.storage.timestamp.v1.Timestamp + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name } func init() { file_controller_storage_plugin_store_v1_plugin_proto_init() } diff --git a/internal/plugin/testing.go b/internal/plugin/testing.go index 90802b115..c00b21bda 100644 --- a/internal/plugin/testing.go +++ b/internal/plugin/testing.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/plugin/store" "github.com/hashicorp/boundary/internal/types/scope" "github.com/stretchr/testify/require" @@ -44,14 +45,73 @@ func (c *plugin) SetTableName(n string) { c.tableName = n } -func testPlugin(t testing.TB, conn *db.DB, name string) *plugin { +// getTestOpts - iterate the inbound TestOptions and return a struct +func getTestOpts(opt ...TestOption) testOptions { + opts := getDefaultTestOptions() + for _, o := range opt { + o(&opts) + } + return opts +} + +// TestOption - how Options are passed as arguments +type TestOption func(*testOptions) + +// options = how options are represented +type testOptions struct { + withHostFlag bool + withStorageFlag bool +} + +func getDefaultTestOptions() testOptions { + return testOptions{ + withHostFlag: true, + withStorageFlag: false, + } +} + +// WithHostFlag determines whether or not to enable the host flag for a test plugin +func WithHostFlag(flag bool) TestOption { + return func(o *testOptions) { + o.withHostFlag = flag + } +} + +// WithStorageFlag determines whether or not to enable the storage flag for a test plugin +func WithStorageFlag(flag bool) TestOption { + return func(o *testOptions) { + o.withStorageFlag = flag + } +} + +// TestPlugin creates a plugin and inserts it into the database. enables the "host" flag by default +// +// Supported options: WithHostFlag, WithStorageFlag +func TestPlugin(t testing.TB, conn *db.DB, name string, opt ...TestOption) *Plugin { + opts := getTestOpts(opt...) t.Helper() - p := newPlugin(name) - id, err := db.NewPublicId("plg") + p := NewPlugin(WithName(name)) + id, err := newPluginId() require.NoError(t, err) p.PublicId = id w := db.New(conn) require.NoError(t, w.Create(context.Background(), p)) + wrapper := db.TestWrapper(t) + kmsCache := kms.TestKms(t, conn, wrapper) + ctx := context.Background() + repo, err := NewRepository(ctx, w, w, kmsCache) + require.NoError(t, err) + + if opts.withHostFlag { + // add the host supported flag + repo.AddSupportFlag(context.Background(), p, PluginTypeHost) + } + + if opts.withStorageFlag { + // add the storage supported flag + repo.AddSupportFlag(context.Background(), p, PluginTypeStorage) + } + return p } diff --git a/internal/plugin/testing_test.go b/internal/plugin/testing_test.go index c069f566a..85b7e1ff0 100644 --- a/internal/plugin/testing_test.go +++ b/internal/plugin/testing_test.go @@ -11,11 +11,11 @@ import ( "github.com/stretchr/testify/require" ) -func Test_testPlugin(t *testing.T) { +func Test_TestPlugins(t *testing.T) { assert, require := assert.New(t), require.New(t) conn, _ := db.TestSetup(t, "postgres") - plg := testPlugin(t, conn, "test") + plg := TestPlugin(t, conn, "test") require.NotNil(plg) assert.NotEmpty(plg.GetPublicId()) } diff --git a/internal/proto/controller/storage/plugin/host/store/v1/plugin.proto b/internal/proto/controller/storage/plugin/host/store/v1/plugin.proto deleted file mode 100644 index e08c7e808..000000000 --- a/internal/proto/controller/storage/plugin/host/store/v1/plugin.proto +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -// Package store provides protobufs for storing types in the host package. -package controller.storage.plugin.host.store.v1; - -import "controller/custom_options/v1/options.proto"; -import "controller/storage/timestamp/v1/timestamp.proto"; - -option go_package = "github.com/hashicorp/boundary/internal/plugin/host/store;store"; - -message Plugin { - // public_id is a surrogate key suitable for use in a public API. - // @inject_tag: `gorm:"primary_key"` - string public_id = 10; - - // The create_time is set by the database. - // @inject_tag: `gorm:"default:current_timestamp"` - timestamp.v1.Timestamp create_time = 20; - - // The update_time is set by the database. - // @inject_tag: `gorm:"default:current_timestamp"` - timestamp.v1.Timestamp update_time = 30; - - // name is optional. If set, it must be unique within scope_id. - // @inject_tag: `gorm:"default:null"` - string name = 4 [(custom_options.v1.mask_mapping) = { - this: "Name" - that: "name" - }]; - - // description is optional. - // @inject_tag: `gorm:"default:null"` - string description = 50 [(custom_options.v1.mask_mapping) = { - this: "Description" - that: "description" - }]; - - // The scope_id of the owning scope and must be set. - // @inject_tag: `gorm:"not_null"` - string scope_id = 60; - - // @inject_tag: `gorm:"default:null"` - uint32 version = 70; -} diff --git a/internal/proto/controller/storage/plugin/store/v1/plugin.proto b/internal/proto/controller/storage/plugin/store/v1/plugin.proto index f80d3c461..8ed05a6c8 100644 --- a/internal/proto/controller/storage/plugin/store/v1/plugin.proto +++ b/internal/proto/controller/storage/plugin/store/v1/plugin.proto @@ -6,10 +6,11 @@ syntax = "proto3"; // Package store provides protobufs for storing types in the host package. package controller.storage.plugin.store.v1; +import "controller/custom_options/v1/options.proto"; +import "controller/storage/timestamp/v1/timestamp.proto"; + option go_package = "github.com/hashicorp/boundary/internal/plugin/store;store"; -// This is a typeless plugin. In practice this should never be used directly. -// This is included for testing purposes only. message Plugin { // public_id is a surrogate key suitable for use in a public API. // @inject_tag: `gorm:"primary_key"` @@ -21,5 +22,26 @@ message Plugin { // name is optional. If set, it must be unique within scope_id. // @inject_tag: `gorm:"default:null"` - string name = 30; + string name = 30 [(custom_options.v1.mask_mapping) = { + this: "Name" + that: "name" + }]; + + // description is optional. + // @inject_tag: `gorm:"default:null"` + string description = 40 [(custom_options.v1.mask_mapping) = { + this: "Description" + that: "description" + }]; + + // The create_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + timestamp.v1.Timestamp create_time = 50; + + // The update_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + timestamp.v1.Timestamp update_time = 60; + + // @inject_tag: `gorm:"default:null"` + uint32 version = 70; } diff --git a/internal/proto/controller/storage/storage/plugin/store/v1/storage.proto b/internal/proto/controller/storage/storage/plugin/store/v1/storage.proto new file mode 100644 index 000000000..22303f33b --- /dev/null +++ b/internal/proto/controller/storage/storage/plugin/store/v1/storage.proto @@ -0,0 +1,91 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +// Package store provides protobufs for storing types in the storage plugin +// package. +package controller.storage.storage.plugin.store.v1; + +import "controller/custom_options/v1/options.proto"; +import "controller/storage/timestamp/v1/timestamp.proto"; + +option go_package = "github.com/hashicorp/boundary/internal/storage/plugin/store;store"; + +message StorageBucket { + // public_id is a surrogate key suitable for use in a public API. + // @inject_tag: `gorm:"primary_key"` + string public_id = 1; + + // The scope_id of the owning scope and must be set. + // @inject_tag: `gorm:"not_null"` + string scope_id = 2; + + // name is optional. If set, it must be globally unique. + // @inject_tag: `gorm:"default:null"` + string name = 3 [(custom_options.v1.mask_mapping) = { + this: "Name" + that: "name" + }]; + + // description is optional. + // @inject_tag: `gorm:"default:null"` + string description = 4 [(custom_options.v1.mask_mapping) = { + this: "Description" + that: "description" + }]; + + // The create_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + timestamp.v1.Timestamp create_time = 5; + + // The update_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + timestamp.v1.Timestamp update_time = 6; + + // @inject_tag: `gorm:"default:null"` + uint32 version = 7; + + // The plugin_id is the public id of the plugin managing this storage bucket. + // @inject_tag: `gorm:"not_null"` + string plugin_id = 8; + + // The name of the external storage bucket (as opposed to the name within boundary) + // @inject_tag: `gorm:"not_null"` + string bucket_name = 9; + + // @inject_tag: `gorm:"default:null"` + string bucket_prefix = 10; + + // A boolean expression that allows filtering the workers that can handle a storage buckets + // @inject_tag: `gorm:"not_null"` + string worker_filter = 11; + + // attributes is a json formatted field. + // @inject_tag: `gorm:"not_null"` + bytes attributes = 12; + + // secrets_hmac is a sha256-hmac of the unencrypted secrets stored in the db. + // @inject_tag: `gorm:"not_null"` + bytes secrets_hmac = 13; +} + +message StorageBucketSecret { + // storage_bucket_id is the public id of the storage bucket using this secret. + // @inject_tag: `gorm:"primary_key"` + string storage_bucket_id = 1; + + // secrets is the plain-text of the secret data. We are not storing this plain-text + // value in the database. + // @inject_tag: `gorm:"-" wrapping:"pt,secrets_data"` + bytes secrets = 2; + + // ct_secrets is the ciphertext of the secret data stored in the db. + // @inject_tag: `gorm:"column:secrets_encrypted;not_null" wrapping:"ct,secrets_data"` + bytes ct_secrets = 3; + + // The key_id of the kms database key used for encrypting this entry. + // It must be set. + // @inject_tag: `gorm:"not_null"` + string key_id = 4; +} diff --git a/internal/storage/plugin/ids.go b/internal/storage/plugin/ids.go new file mode 100644 index 000000000..feba9e3d5 --- /dev/null +++ b/internal/storage/plugin/ids.go @@ -0,0 +1,35 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + + "github.com/hashicorp/boundary/globals" + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/types/subtypes" +) + +const StorageDomain = "storage" + +func init() { + if err := subtypes.Register(StorageDomain, Subtype, globals.PluginStorageBucketPrefix); err != nil { + panic(err) + } +} + +// PublicId prefixes for the resources in the plugin package. +const ( + Subtype = subtypes.Subtype("plugin") +) + +func newStorageBucketId(ctx context.Context) (string, error) { + const op = "plugin.newStorageBucketId" + id, err := db.NewPublicId(globals.PluginStorageBucketPrefix) + if err != nil { + return "", errors.Wrap(ctx, err, op) + } + return id, nil +} diff --git a/internal/storage/plugin/repository.go b/internal/storage/plugin/repository.go new file mode 100644 index 000000000..2afb4a836 --- /dev/null +++ b/internal/storage/plugin/repository.go @@ -0,0 +1,38 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/kms" +) + +type Repository struct { + reader db.Reader + writer db.Writer + kms *kms.Kms +} + +// NewRepository creates a new Repository. The returned repository is not +// safe for concurrent go routines to access it +func NewRepository(ctx context.Context, r db.Reader, w db.Writer, kms *kms.Kms) (*Repository, error) { + const op = "plugin.NewRepository" + switch { + case r == nil: + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil db.Reader") + case w == nil: + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil db.Writer") + case kms == nil: + return nil, errors.New(ctx, errors.InvalidParameter, op, "nil kms") + } + + return &Repository{ + reader: r, + writer: w, + kms: kms, + }, nil +} diff --git a/internal/storage/plugin/repository_test.go b/internal/storage/plugin/repository_test.go new file mode 100644 index 000000000..85b288f48 --- /dev/null +++ b/internal/storage/plugin/repository_test.go @@ -0,0 +1,89 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + "testing" + + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/kms" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestRepository_NewRepository(t *testing.T) { + conn, _ := db.TestSetup(t, "postgres") + rw := db.New(conn) + wrapper := db.TestWrapper(t) + kmsCache := kms.TestKms(t, conn, wrapper) + + tests := []struct { + name string + in *Repository + want *Repository + wantErrContains string + wantErrCode errors.Code + }{ + { + name: "no-reader", + in: &Repository{ + writer: rw, + kms: kmsCache, + }, + wantErrContains: "nil db.Reader", + wantErrCode: errors.InvalidParameter, + }, + { + name: "no-writer", + in: &Repository{ + reader: rw, + kms: kmsCache, + }, + wantErrContains: "nil db.Writer", + wantErrCode: errors.InvalidParameter, + }, + { + name: "no-kms", + in: &Repository{ + reader: rw, + writer: rw, + }, + wantErrContains: "nil kms", + wantErrCode: errors.InvalidParameter, + }, + { + name: "valid-repository", + in: &Repository{ + reader: rw, + writer: rw, + kms: kmsCache, + }, + want: &Repository{ + reader: rw, + writer: rw, + kms: kmsCache, + }, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + require, assert := require.New(t), assert.New(t) + ctx := context.Background() + + repo, err := NewRepository(ctx, tt.in.reader, tt.in.writer, tt.in.kms) + if tt.wantErrContains != "" { + require.ErrorContains(err, tt.wantErrContains) + return + } + require.NoError(err) + + assert.Equal(tt.want.reader, repo.reader) + assert.Equal(tt.want.writer, repo.writer) + assert.Equal(tt.want.kms, repo.kms) + }) + } +} diff --git a/internal/storage/plugin/rewrapping.go b/internal/storage/plugin/rewrapping.go new file mode 100644 index 000000000..70d43352d --- /dev/null +++ b/internal/storage/plugin/rewrapping.go @@ -0,0 +1,60 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/util" +) + +const ( + storageBucketSecretTablename = "storage_plugin_storage_bucket_secret" +) + +func init() { + kms.RegisterTableRewrapFn(storageBucketSecretTablename, storageBucketSecretRewrapFn) +} + +// storageBucketRewrapFn provides a kms.Rewrapfn for the StorageBucketSecret type +func storageBucketSecretRewrapFn(ctx context.Context, dataKeyVersionId, scopeId string, reader db.Reader, writer db.Writer, kmsRepo kms.GetWrapperer) error { + const op = "storage.storageBucketRewrapFn" + switch { + case dataKeyVersionId == "": + return errors.New(ctx, errors.InvalidParameter, op, "missing data key version id") + case scopeId == "": + return errors.New(ctx, errors.InvalidParameter, op, "missing scope id") + case util.IsNil(reader): + return errors.New(ctx, errors.InvalidParameter, op, "missing database reader") + case util.IsNil(writer): + return errors.New(ctx, errors.InvalidParameter, op, "missing database writer") + case kmsRepo == nil: + return errors.New(ctx, errors.InvalidParameter, op, "missing kms repository") + } + var secrets []*StorageBucketSecret + // The only index on this table is on the primary key (storage bucket id) and we can't find it that way. + // This is the fastest query we can use without creating a new index on key_id. + if err := reader.SearchWhere(ctx, &secrets, "key_id=?", []any{dataKeyVersionId}, db.WithLimit(-1)); err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("failed to query sql for rows that need rewrapping")) + } + wrapper, err := kmsRepo.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase) + if err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("failed to fetch kms wrapper for rewrapping")) + } + for _, secret := range secrets { + if err := secret.decrypt(ctx, wrapper); err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("failed to decrypt storage bucket secret")) + } + if err := secret.encrypt(ctx, wrapper); err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("failed to re-encrypt storage bucket secret")) + } + if _, err := writer.Update(ctx, secret, []string{"CtSecrets", "KeyId"}, nil); err != nil { + return errors.Wrap(ctx, err, op, errors.WithMsg("failed to update storage bucket secret row with rewrapped fields")) + } + } + return nil +} diff --git a/internal/storage/plugin/rewrapping_test.go b/internal/storage/plugin/rewrapping_test.go new file mode 100644 index 000000000..e9e240891 --- /dev/null +++ b/internal/storage/plugin/rewrapping_test.go @@ -0,0 +1,111 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + "errors" + "testing" + "time" + + "github.com/DATA-DOG/go-sqlmock" + "github.com/hashicorp/boundary/internal/db" + "github.com/hashicorp/boundary/internal/iam" + "github.com/hashicorp/boundary/internal/kms" + "github.com/hashicorp/boundary/internal/libs/patchstruct" + "github.com/hashicorp/boundary/internal/plugin" + "github.com/hashicorp/boundary/internal/storage/plugin/store" + "github.com/hashicorp/go-kms-wrapping/extras/kms/v2/migrations" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" +) + +func TestRewrap_storageBucketSecretRewrapFn(t *testing.T) { + ctx := context.Background() + t.Run("errors-on-query-error", func(t *testing.T) { + conn, mock := db.TestSetupWithMock(t) + wrapper := db.TestWrapper(t) + mock.ExpectQuery( + `SELECT \* FROM "kms_schema_version" WHERE 1=1 ORDER BY "kms_schema_version"\."version" LIMIT 1`, + ).WillReturnRows(sqlmock.NewRows([]string{"version", "create_time"}).AddRow(migrations.Version, time.Now())) + kmsCache := kms.TestKms(t, conn, wrapper) + rw := db.New(conn) + mock.ExpectQuery( + `SELECT \* FROM "storage_plugin_storage_bucket_secret" WHERE key_id=\$1`, + ).WillReturnError(errors.New("Query error")) + err := storageBucketSecretRewrapFn(ctx, "some_id", "some_scope", rw, rw, kmsCache) + require.Error(t, err) + }) + t.Run("success", func(t *testing.T) { + require, assert := require.New(t), assert.New(t) + conn, _ := db.TestSetup(t, "postgres") + + rw := db.New(conn) + wrapper := db.TestWrapper(t) + + org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper)) + plg := plugin.TestPlugin(t, conn, "test", plugin.WithStorageFlag(true)) + + kmsCache := kms.TestKms(t, conn, wrapper) + sb := &StorageBucket{ + StorageBucket: &store.StorageBucket{ + ScopeId: org.PublicId, + PluginId: plg.PublicId, + BucketName: "test-bucket-name", + Attributes: []byte{}, + SecretsHmac: []byte("test"), + WorkerFilter: "test worker filter", + }, + Secrets: &structpb.Struct{ + Fields: map[string]*structpb.Value{ + "AWS_ACCESS_KEY_ID": structpb.NewStringValue("access_key_id"), + "AWS_SECRET_ACCESS_KEY": structpb.NewStringValue("secret_access_key"), + }, + }, + } + + // first store bucket + var err error + sb.PublicId, err = newStorageBucketId(ctx) + require.NoError(err) + sb.Attributes, err = patchstruct.PatchBytes([]byte{}, sb.Attributes) + require.NoError(err) + require.NoError(rw.Create(ctx, sb)) + + // now store secret + cred, err := newStorageBucketSecret(ctx, sb.PublicId, sb.Secrets) + require.NoError(err) + kmsWrapper1, err := kmsCache.GetWrapper(context.Background(), org.GetPublicId(), 1) + require.NoError(err) + require.NoError(cred.encrypt(ctx, kmsWrapper1)) + require.NoError(rw.Create(ctx, cred)) + assert.NoError(cred.decrypt(ctx, kmsWrapper1)) + + // now things are stored in the db, we can rotate and rewrap + require.NoError(kmsCache.RotateKeys(ctx, org.Scope.GetPublicId())) + require.NoError(storageBucketSecretRewrapFn(ctx, cred.KeyId, org.Scope.GetPublicId(), rw, rw, kmsCache)) + + // now we pull the config back from the db, decrypt it with the new key, and ensure things match + got := &StorageBucketSecret{ + StorageBucketSecret: &store.StorageBucketSecret{ + StorageBucketId: sb.PublicId, + }, + } + assert.NoError(rw.LookupById(ctx, got)) + + // fetch the new key version + kmsWrapper2, err := kmsCache.GetWrapper(ctx, org.Scope.GetPublicId(), kms.KeyPurposeDatabase, kms.WithKeyId(got.GetKeyId())) + assert.NoError(err) + newKeyVersion, err := kmsWrapper2.KeyId(ctx) + assert.NoError(err) + + // decrypt with the new key version and check to make sure things match + assert.NoError(got.decrypt(ctx, kmsWrapper2)) + assert.NotEmpty(got.GetKeyId()) + assert.NotEqual(cred.GetKeyId(), got.GetKeyId()) + assert.Equal(newKeyVersion, got.GetKeyId()) + assert.Equal(cred.Secrets, got.GetSecrets()) + }) +} diff --git a/internal/storage/plugin/storage_bucket.go b/internal/storage/plugin/storage_bucket.go new file mode 100644 index 000000000..602ea2f24 --- /dev/null +++ b/internal/storage/plugin/storage_bucket.go @@ -0,0 +1,239 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package plugin + +import ( + "context" + + "github.com/hashicorp/boundary/internal/db/timestamp" + "github.com/hashicorp/boundary/internal/errors" + "github.com/hashicorp/boundary/internal/libs/crypto" + "github.com/hashicorp/boundary/internal/oplog" + "github.com/hashicorp/boundary/internal/storage/plugin/store" + "github.com/hashicorp/boundary/internal/util" + wrapping "github.com/hashicorp/go-kms-wrapping/v2" + "github.com/hashicorp/go-kms-wrapping/v2/extras/structwrapping" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/structpb" +) + +// StorageBucket represents a bucket within an external object store. It contains secret +// data needed to create and read objects within the external object store. +type StorageBucket struct { + *store.StorageBucket + tableName string `gorm:"-"` + + Secrets *structpb.Struct `gorm:"-"` +} + +func allocStorageBucket() *StorageBucket { + return &StorageBucket{ + StorageBucket: &store.StorageBucket{}, + } +} + +// clone provides a deep copy of the storage bucket with the exception of the +// secret. The secret shallow copied. +func (s *StorageBucket) clone() *StorageBucket { + cp := proto.Clone(s.StorageBucket) + newSecret := proto.Clone(s.Secrets) + + sb := &StorageBucket{ + StorageBucket: cp.(*store.StorageBucket), + Secrets: newSecret.(*structpb.Struct), + } + // proto.Clone will convert slices with length and capacity of 0 to nil. + // Fix this since gorm treats empty slices differently than nil. + if s.Attributes != nil && len(s.Attributes) == 0 && sb.Attributes == nil { + sb.Attributes = []byte{} + } + return sb +} + +// TableName returns the table name for the storage bucket. +func (s *StorageBucket) TableName() string { + if s.tableName != "" { + return s.tableName + } + return "storage_plugin_storage_bucket" +} + +// SetTableName sets the table name. +func (s *StorageBucket) SetTableName(n string) { + s.tableName = n +} + +func (s *StorageBucket) oplog(op oplog.OpType) oplog.Metadata { + metadata := oplog.Metadata{ + "resource-public-id": []string{s.PublicId}, + "resource-type": []string{"plugin-storage-bucket"}, + "op-type": []string{op.String()}, + } + if s.ScopeId != "" { + metadata["scope-id"] = []string{s.ScopeId} + } + return metadata +} + +type StorageBucketSecret struct { + *store.StorageBucketSecret + tableName string `gorm:"-"` +} + +func allocStorageBucketSecret() *StorageBucketSecret { + return &StorageBucketSecret{ + StorageBucketSecret: &store.StorageBucketSecret{}, + } +} + +// newStorageBucketSecret creates an in memory storage bucket secret from a json +// formatted generic struct. +func newStorageBucketSecret(ctx context.Context, storageBucketId string, secret *structpb.Struct) (*StorageBucketSecret, error) { + const op = "plugin.newStorageBucketSecret" + s := &StorageBucketSecret{ + StorageBucketSecret: &store.StorageBucketSecret{ + StorageBucketId: storageBucketId, + }, + } + + if secret != nil { + sec, err := proto.Marshal(secret) + if err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.InvalidParameter)) + } + s.Secrets = sec + } + return s, nil +} + +func (sbs *StorageBucketSecret) clone() *StorageBucketSecret { + cp := proto.Clone(sbs.StorageBucketSecret) + return &StorageBucketSecret{ + StorageBucketSecret: cp.(*store.StorageBucketSecret), + } +} + +// TableName returns the table name for the storage bucket secrets. +func (sbs *StorageBucketSecret) TableName() string { + if sbs.tableName != "" { + return sbs.tableName + } + return "storage_plugin_storage_bucket_secret" +} + +// SetTableName sets the table name. +func (sbs *StorageBucketSecret) SetTableName(n string) { + sbs.tableName = n +} + +// hmacField simply hmac's a field in a consistent manner for this pkg +func hmacField(ctx context.Context, cipher wrapping.Wrapper, field []byte, publicId string) ([]byte, error) { + const op = "plugin.hmacField" + hm, err := crypto.HmacSha256(ctx, field, cipher, []byte(publicId), nil) + if err != nil { + return nil, errors.Wrap(ctx, err, op) + } + return []byte(hm), nil +} + +// only hmac's the secret's value. does not modify the underlying secret +// returns nil on failure +func (sbs *StorageBucketSecret) hmacSecrets(ctx context.Context, cipher wrapping.Wrapper) ([]byte, error) { + const op = "plugin.(StorageBucketSecret).hmacSecrets" + if cipher == nil { + return nil, errors.New(ctx, errors.InvalidParameter, op, "missing cipher") + } + var err error + if _, err = cipher.KeyId(ctx); err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("failed to read cipher key id")) + } + var hmac []byte + if hmac, err = hmacField(ctx, cipher, sbs.Secrets, sbs.StorageBucketId); err != nil { + return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("failed to hmac secrets")) + } + + return hmac, nil +} + +// encrypt the bind credential before writing it to the database +func (sbs *StorageBucketSecret) encrypt(ctx context.Context, cipher wrapping.Wrapper) error { + const op = "plugin.(StorageBucketSecret).encrypt" + if util.IsNil(cipher) { + return errors.New(ctx, errors.InvalidParameter, op, "missing cipher") + } + if err := structwrapping.WrapStruct(ctx, cipher, sbs.StorageBucketSecret); err != nil { + return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt)) + } + var err error + if sbs.KeyId, err = cipher.KeyId(ctx); err != nil { + return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("failed to read cipher key id")) + } + + return nil +} + +func (sbs *StorageBucketSecret) decrypt(ctx context.Context, cipher wrapping.Wrapper) error { + const op = "plugin.(StorageBucketSecret).decrypt" + if util.IsNil(cipher) { + return errors.New(ctx, errors.InvalidParameter, op, "missing cipher") + } + if err := structwrapping.UnwrapStruct(ctx, cipher, sbs.StorageBucketSecret, nil); err != nil { + return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt)) + } + sbs.CtSecrets = nil + return nil +} + +type storageBucketAgg struct { + PublicId string `gorm:"primary_key"` + ScopeId string + Name string + Description string + CreateTime *timestamp.Timestamp + UpdateTime *timestamp.Timestamp + Version uint32 + PluginId string + BucketName string + BucketPrefix string + WorkerFilter string + Attributes []byte + SecretsEncrypted []byte + SecretsHmac []byte + KeyId string +} + +// TableName returns the table name for gorm +func (sba *storageBucketAgg) TableName() string { + return "storage_plugin_storage_bucket_with_secret" +} + +func (sba *storageBucketAgg) GetPublicId() string { + return sba.PublicId +} + +func (sba *storageBucketAgg) toStorageBucketAndSecret() (*StorageBucket, *StorageBucketSecret) { + sb := allocStorageBucket() + sb.PublicId = sba.PublicId + sb.ScopeId = sba.ScopeId + sb.Name = sba.Name + sb.Description = sba.Description + sb.CreateTime = sba.CreateTime + sb.UpdateTime = sba.UpdateTime + sb.Version = sba.Version + sb.PluginId = sba.PluginId + sb.BucketName = sba.BucketName + sb.BucketPrefix = sba.BucketPrefix + sb.WorkerFilter = sba.WorkerFilter + sb.Attributes = sba.Attributes + sb.SecretsHmac = sba.SecretsHmac + + var sbs *StorageBucketSecret + if len(sba.SecretsEncrypted) > 0 { + sbs = allocStorageBucketSecret() + sbs.StorageBucketId = sba.PublicId + sbs.CtSecrets = sba.SecretsEncrypted + sbs.KeyId = sba.KeyId + } + return sb, sbs +} diff --git a/internal/storage/plugin/store/storage.pb.go b/internal/storage/plugin/store/storage.pb.go new file mode 100644 index 000000000..0f0bf6b4d --- /dev/null +++ b/internal/storage/plugin/store/storage.pb.go @@ -0,0 +1,423 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: controller/storage/storage/plugin/store/v1/storage.proto + +// Package store provides protobufs for storing types in the storage plugin +// package. + +package store + +import ( + timestamp "github.com/hashicorp/boundary/internal/db/timestamp" + _ "github.com/hashicorp/boundary/sdk/pbs/controller/protooptions" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type StorageBucket struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // public_id is a surrogate key suitable for use in a public API. + // @inject_tag: `gorm:"primary_key"` + PublicId string `protobuf:"bytes,1,opt,name=public_id,json=publicId,proto3" json:"public_id,omitempty" gorm:"primary_key"` + // The scope_id of the owning scope and must be set. + // @inject_tag: `gorm:"not_null"` + ScopeId string `protobuf:"bytes,2,opt,name=scope_id,json=scopeId,proto3" json:"scope_id,omitempty" gorm:"not_null"` + // name is optional. If set, it must be globally unique. + // @inject_tag: `gorm:"default:null"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty" gorm:"default:null"` + // description is optional. + // @inject_tag: `gorm:"default:null"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" gorm:"default:null"` + // The create_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + CreateTime *timestamp.Timestamp `protobuf:"bytes,5,opt,name=create_time,json=createTime,proto3" json:"create_time,omitempty" gorm:"default:current_timestamp"` + // The update_time is set by the database. + // @inject_tag: `gorm:"default:current_timestamp"` + UpdateTime *timestamp.Timestamp `protobuf:"bytes,6,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty" gorm:"default:current_timestamp"` + // @inject_tag: `gorm:"default:null"` + Version uint32 `protobuf:"varint,7,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"` + // The plugin_id is the public id of the plugin managing this storage bucket. + // @inject_tag: `gorm:"not_null"` + PluginId string `protobuf:"bytes,8,opt,name=plugin_id,json=pluginId,proto3" json:"plugin_id,omitempty" gorm:"not_null"` + // The name of the external storage bucket (as opposed to the name within boundary) + // @inject_tag: `gorm:"not_null"` + BucketName string `protobuf:"bytes,9,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty" gorm:"not_null"` + // @inject_tag: `gorm:"default:null"` + BucketPrefix string `protobuf:"bytes,10,opt,name=bucket_prefix,json=bucketPrefix,proto3" json:"bucket_prefix,omitempty" gorm:"default:null"` + // A boolean expression that allows filtering the workers that can handle a storage buckets + // @inject_tag: `gorm:"not_null"` + WorkerFilter string `protobuf:"bytes,11,opt,name=worker_filter,json=workerFilter,proto3" json:"worker_filter,omitempty" gorm:"not_null"` + // attributes is a json formatted field. + // @inject_tag: `gorm:"not_null"` + Attributes []byte `protobuf:"bytes,12,opt,name=attributes,proto3" json:"attributes,omitempty" gorm:"not_null"` + // secrets_hmac is a sha256-hmac of the unencrypted secrets stored in the db. + // @inject_tag: `gorm:"not_null"` + SecretsHmac []byte `protobuf:"bytes,13,opt,name=secrets_hmac,json=secretsHmac,proto3" json:"secrets_hmac,omitempty" gorm:"not_null"` +} + +func (x *StorageBucket) Reset() { + *x = StorageBucket{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StorageBucket) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StorageBucket) ProtoMessage() {} + +func (x *StorageBucket) ProtoReflect() protoreflect.Message { + mi := &file_controller_storage_storage_plugin_store_v1_storage_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 StorageBucket.ProtoReflect.Descriptor instead. +func (*StorageBucket) Descriptor() ([]byte, []int) { + return file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescGZIP(), []int{0} +} + +func (x *StorageBucket) GetPublicId() string { + if x != nil { + return x.PublicId + } + return "" +} + +func (x *StorageBucket) GetScopeId() string { + if x != nil { + return x.ScopeId + } + return "" +} + +func (x *StorageBucket) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *StorageBucket) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *StorageBucket) GetCreateTime() *timestamp.Timestamp { + if x != nil { + return x.CreateTime + } + return nil +} + +func (x *StorageBucket) GetUpdateTime() *timestamp.Timestamp { + if x != nil { + return x.UpdateTime + } + return nil +} + +func (x *StorageBucket) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *StorageBucket) GetPluginId() string { + if x != nil { + return x.PluginId + } + return "" +} + +func (x *StorageBucket) GetBucketName() string { + if x != nil { + return x.BucketName + } + return "" +} + +func (x *StorageBucket) GetBucketPrefix() string { + if x != nil { + return x.BucketPrefix + } + return "" +} + +func (x *StorageBucket) GetWorkerFilter() string { + if x != nil { + return x.WorkerFilter + } + return "" +} + +func (x *StorageBucket) GetAttributes() []byte { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *StorageBucket) GetSecretsHmac() []byte { + if x != nil { + return x.SecretsHmac + } + return nil +} + +type StorageBucketSecret struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // storage_bucket_id is the public id of the storage bucket using this secret. + // @inject_tag: `gorm:"primary_key"` + StorageBucketId string `protobuf:"bytes,1,opt,name=storage_bucket_id,json=storageBucketId,proto3" json:"storage_bucket_id,omitempty" gorm:"primary_key"` + // secrets is the plain-text of the secret data. We are not storing this plain-text + // value in the database. + // @inject_tag: `gorm:"-" wrapping:"pt,secrets_data"` + Secrets []byte `protobuf:"bytes,2,opt,name=secrets,proto3" json:"secrets,omitempty" gorm:"-" wrapping:"pt,secrets_data"` + // ct_secrets is the ciphertext of the secret data stored in the db. + // @inject_tag: `gorm:"column:secrets_encrypted;not_null" wrapping:"ct,secrets_data"` + CtSecrets []byte `protobuf:"bytes,3,opt,name=ct_secrets,json=ctSecrets,proto3" json:"ct_secrets,omitempty" gorm:"column:secrets_encrypted;not_null" wrapping:"ct,secrets_data"` + // The key_id of the kms database key used for encrypting this entry. + // It must be set. + // @inject_tag: `gorm:"not_null"` + KeyId string `protobuf:"bytes,4,opt,name=key_id,json=keyId,proto3" json:"key_id,omitempty" gorm:"not_null"` +} + +func (x *StorageBucketSecret) Reset() { + *x = StorageBucketSecret{} + if protoimpl.UnsafeEnabled { + mi := &file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StorageBucketSecret) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StorageBucketSecret) ProtoMessage() {} + +func (x *StorageBucketSecret) ProtoReflect() protoreflect.Message { + mi := &file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes[1] + 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 StorageBucketSecret.ProtoReflect.Descriptor instead. +func (*StorageBucketSecret) Descriptor() ([]byte, []int) { + return file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescGZIP(), []int{1} +} + +func (x *StorageBucketSecret) GetStorageBucketId() string { + if x != nil { + return x.StorageBucketId + } + return "" +} + +func (x *StorageBucketSecret) GetSecrets() []byte { + if x != nil { + return x.Secrets + } + return nil +} + +func (x *StorageBucketSecret) GetCtSecrets() []byte { + if x != nil { + return x.CtSecrets + } + return nil +} + +func (x *StorageBucketSecret) GetKeyId() string { + if x != nil { + return x.KeyId + } + return "" +} + +var File_controller_storage_storage_plugin_store_v1_storage_proto protoreflect.FileDescriptor + +var file_controller_storage_storage_plugin_store_v1_storage_proto_rawDesc = []byte{ + 0x0a, 0x38, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x2e, 0x76, 0x31, 0x1a, 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 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, 0xae, 0x04, 0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x42, + 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x49, 0x64, 0x12, 0x24, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd, 0x29, + 0x0c, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, + 0x44, 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, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 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, 0x06, 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, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x75, + 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, + 0x75, 0x67, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x62, 0x75, 0x63, + 0x6b, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x75, 0x63, 0x6b, 0x65, + 0x74, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x23, 0x0a, 0x0d, + 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f, 0x68, 0x6d, 0x61, + 0x63, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x48, 0x6d, 0x61, 0x63, 0x22, 0x91, 0x01, 0x0a, 0x13, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x11, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x73, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x42, 0x43, 0x5a, 0x41, 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, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescOnce sync.Once + file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescData = file_controller_storage_storage_plugin_store_v1_storage_proto_rawDesc +) + +func file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescGZIP() []byte { + file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescOnce.Do(func() { + file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescData = protoimpl.X.CompressGZIP(file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescData) + }) + return file_controller_storage_storage_plugin_store_v1_storage_proto_rawDescData +} + +var file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_controller_storage_storage_plugin_store_v1_storage_proto_goTypes = []interface{}{ + (*StorageBucket)(nil), // 0: controller.storage.storage.plugin.store.v1.StorageBucket + (*StorageBucketSecret)(nil), // 1: controller.storage.storage.plugin.store.v1.StorageBucketSecret + (*timestamp.Timestamp)(nil), // 2: controller.storage.timestamp.v1.Timestamp +} +var file_controller_storage_storage_plugin_store_v1_storage_proto_depIdxs = []int32{ + 2, // 0: controller.storage.storage.plugin.store.v1.StorageBucket.create_time:type_name -> controller.storage.timestamp.v1.Timestamp + 2, // 1: controller.storage.storage.plugin.store.v1.StorageBucket.update_time:type_name -> controller.storage.timestamp.v1.Timestamp + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_controller_storage_storage_plugin_store_v1_storage_proto_init() } +func file_controller_storage_storage_plugin_store_v1_storage_proto_init() { + if File_controller_storage_storage_plugin_store_v1_storage_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StorageBucket); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StorageBucketSecret); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_controller_storage_storage_plugin_store_v1_storage_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_controller_storage_storage_plugin_store_v1_storage_proto_goTypes, + DependencyIndexes: file_controller_storage_storage_plugin_store_v1_storage_proto_depIdxs, + MessageInfos: file_controller_storage_storage_plugin_store_v1_storage_proto_msgTypes, + }.Build() + File_controller_storage_storage_plugin_store_v1_storage_proto = out.File + file_controller_storage_storage_plugin_store_v1_storage_proto_rawDesc = nil + file_controller_storage_storage_plugin_store_v1_storage_proto_goTypes = nil + file_controller_storage_storage_plugin_store_v1_storage_proto_depIdxs = nil +}