From 6588e109342da02c4fbe599680ba0cde0f5b38ed Mon Sep 17 00:00:00 2001 From: Elim Tsiagbey Date: Mon, 16 Sep 2024 14:28:54 -0400 Subject: [PATCH] feat: package structure (#2) Update structure to match other Boundary plugins which groups packages by service --- plugin/plugin.go | 282 +----------------- plugin/{ => service/host}/attributes.go | 2 +- plugin/{ => service/host}/attributes_test.go | 2 +- plugin/{ => service/host}/client.go | 2 +- plugin/{ => service/host}/client_test.go | 2 +- plugin/{ => service/host}/const.go | 2 +- plugin/service/host/plugin.go | 285 +++++++++++++++++++ plugin/{ => service/host}/plugin_test.go | 12 +- 8 files changed, 309 insertions(+), 280 deletions(-) rename plugin/{ => service/host}/attributes.go (99%) rename plugin/{ => service/host}/attributes_test.go (99%) rename plugin/{ => service/host}/client.go (99%) rename plugin/{ => service/host}/client_test.go (99%) rename plugin/{ => service/host}/const.go (96%) create mode 100644 plugin/service/host/plugin.go rename plugin/{ => service/host}/plugin_test.go (99%) diff --git a/plugin/plugin.go b/plugin/plugin.go index 469b111..70b1366 100644 --- a/plugin/plugin.go +++ b/plugin/plugin.go @@ -4,282 +4,26 @@ package plugin import ( - "context" - "fmt" - - compute "cloud.google.com/go/compute/apiv1" - computepb "cloud.google.com/go/compute/apiv1/computepb" - errors "github.com/hashicorp/boundary-plugin-gcp/internal/errors" - "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets" + "github.com/hashicorp/boundary-plugin-gcp/plugin/service/host" pb "github.com/hashicorp/boundary/sdk/pbs/plugin" - "github.com/mitchellh/mapstructure" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) -// GooglePlugin implements the GooglePluginServiceServer interface for the -// Google host service plugin. -type GooglePlugin struct { - pb.UnimplementedHostPluginServiceServer -} - +// Ensure that HostPlugin implements the following services: +// +// HostPluginServiceServer var ( - _ pb.HostPluginServiceServer = (*GooglePlugin)(nil) + _ pb.HostPluginServiceServer = (*host.HostPlugin)(nil) ) -// OnCreateCatalog is called when a dynamic host catalog is created. -func (p *GooglePlugin) OnCreateCatalog(_ context.Context, req *pb.OnCreateCatalogRequest) (*pb.OnCreateCatalogResponse, error) { - catalog := req.GetCatalog() - if catalog == nil { - return nil, status.Error(codes.InvalidArgument, "catalog is nil") - } - - attrs := catalog.GetAttributes() - if attrs == nil { - return nil, status.Error(codes.InvalidArgument, "attributes are required") - } - - if _, err := getCatalogAttributes(attrs); err != nil { - return nil, err - } - - return &pb.OnCreateCatalogResponse{ - Persisted: &pb.HostCatalogPersisted{ - Secrets: nil, - }, - }, nil +// GCPPlugin contains a collection of all GCP plugin services. +type GCPPlugin struct { + // HostPlugin implements the HostPluginServiceServer interface for + // supporting dynamically sourcing hosts from GCP Compute Engine. + *host.HostPlugin } -// OnUpdateCatalog is called when a dynamic host catalog is updated. -func (p *GooglePlugin) OnUpdateCatalog(_ context.Context, req *pb.OnUpdateCatalogRequest) (*pb.OnUpdateCatalogResponse, error) { - currentCatalog := req.GetCurrentCatalog() - if currentCatalog == nil { - return nil, status.Error(codes.FailedPrecondition, "current catalog is nil") +func NewGCPPlugin() *GCPPlugin { + return &GCPPlugin{ + HostPlugin: &host.HostPlugin{}, } - - secrets := req.GetNewCatalog().GetSecrets() - if secrets == nil { - // If new secrets weren't passed in, don't rotate what we have on - // update. - return &pb.OnUpdateCatalogResponse{}, nil - } - - return &pb.OnUpdateCatalogResponse{ - Persisted: &pb.HostCatalogPersisted{ - Secrets: nil, - }, - }, nil -} - -// OnDeleteCatalog is called when a dynamic host catalog is deleted. -func (p *GooglePlugin) OnDeleteCatalog(ctx context.Context, req *pb.OnDeleteCatalogRequest) (*pb.OnDeleteCatalogResponse, error) { - catalog := req.GetCatalog() - if catalog == nil { - return nil, status.Error(codes.InvalidArgument, "new catalog is nil") - } - - attrs := catalog.GetAttributes() - if attrs == nil { - return nil, status.Error(codes.InvalidArgument, "new catalog missing attributes") - } - - if _, err := getCatalogAttributes(attrs); err != nil { - return nil, err - } - - return &pb.OnDeleteCatalogResponse{}, nil -} - -// OnCreateSet is called when a dynamic host set is created. -func (p *GooglePlugin) OnCreateSet(_ context.Context, req *pb.OnCreateSetRequest) (*pb.OnCreateSetResponse, error) { - if err := validateSet(req.GetSet()); err != nil { - return nil, err - } - return &pb.OnCreateSetResponse{}, nil -} - -// OnUpdateSet is called when a dynamic host set is updated. -func (p *GooglePlugin) OnUpdateSet(_ context.Context, req *pb.OnUpdateSetRequest) (*pb.OnUpdateSetResponse, error) { - if err := validateSet(req.GetNewSet()); err != nil { - return nil, err - } - return &pb.OnUpdateSetResponse{}, nil -} - -// OnDeleteSet is called when a dynamic host set is deleted. -func (p *GooglePlugin) OnDeleteSet(ctx context.Context, req *pb.OnDeleteSetRequest) (*pb.OnDeleteSetResponse, error) { - return &pb.OnDeleteSetResponse{}, nil -} - -// ListHosts returns the list of instances based on filter or instance group name. -func (p *GooglePlugin) ListHosts(ctx context.Context, req *pb.ListHostsRequest) (*pb.ListHostsResponse, error) { - catalog := req.GetCatalog() - if catalog == nil { - return nil, status.Error(codes.InvalidArgument, "catalog is nil") - } - - catalogAttrsRaw := catalog.GetAttributes() - if catalogAttrsRaw == nil { - return nil, status.Error(codes.InvalidArgument, "catalog missing attributes") - } - - catalogAttributes, err := getCatalogAttributes(catalogAttrsRaw) - if err != nil { - return nil, err - } - - sets := req.GetSets() - if sets == nil { - return nil, status.Error(codes.InvalidArgument, "sets is nil") - } - - type hostSetQuery struct { - Id string - InputInstances *computepb.ListInstancesRequest - InputGroups *computepb.ListInstancesInstanceGroupsRequest - Project string - Zone string - Output []*computepb.Instance - OutputHosts []*pb.ListHostsResponseHost - } - - queries := make([]hostSetQuery, len(sets)) - for i, set := range sets { - // Validate Id since we use it in output - if set.GetId() == "" { - return nil, status.Error(codes.InvalidArgument, "set missing id") - } - - if set.GetAttributes() == nil { - return nil, status.Error(codes.InvalidArgument, "set missing attributes") - } - setAttrs, err := getSetAttributes(set.GetAttributes()) - if err != nil { - return nil, err - } - - if setAttrs.InstanceGroup != "" { - queries[i] = hostSetQuery{ - Id: set.GetId(), - InputGroups: buildListInstanceGroupsRequest(setAttrs, catalogAttributes), - } - } else { - queries[i] = hostSetQuery{ - Id: set.GetId(), - InputInstances: buildListInstancesRequest(setAttrs, catalogAttributes), - } - } - } - - instancesClient, err := compute.NewInstancesRESTClient(ctx) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "error creating NewInstancesRESTClient: %s", err) - } - - instanceGroupsClient, err := compute.NewInstanceGroupsRESTClient(ctx) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "error creating NewInstanceGroupsRESTClient: %s", err) - } - - gclient := GoogleClient{ - InstancesClient: instancesClient, - InstanceGroupClient: instanceGroupsClient, - Context: ctx, - } - - // Run all queries now and assemble output. - var maxLen int - for i, query := range queries { - var output []*computepb.Instance - if query.InputGroups != nil { - output, err = gclient.getInstancesForInstanceGroup(query.InputGroups) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "error running getInstancesForInstanceGroup for host set id %q: %s", query.Id, err) - } - } else { - output, err = gclient.getInstances(query.InputInstances) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "error running getInstances for host set id %q: %s", query.Id, err) - } - } - - queries[i].Output = output - - // Process the output here, we will normalize this into a single - // set of hosts afterwards (possibly removing duplicates). - for _, instance := range output { - host, err := instanceToHost(instance) - - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "error processing host results for host set id %q: %s", query.Id, err) - } - - queries[i].OutputHosts = append(queries[i].OutputHosts, host) - maxLen++ - } - } - - // Now de-duplicate the hosts for the output. Maintain two sets: - // * A slice of hosts that will be used in the output - // * A map of hosts indexed by their external ID - // - // The map will is used in de-duplication to determine whether or - // not we've seen the host before to simply add the query's set ID - // to the list of set IDs that the host was seen in. - hostResultSlice := make([]*pb.ListHostsResponseHost, 0, maxLen) - hostResultMap := make(map[string]*pb.ListHostsResponseHost) - for _, query := range queries { - for _, host := range query.OutputHosts { - if existingHost, ok := hostResultMap[host.ExternalId]; ok { - // Existing host, just add the set ID to the list of seen IDs - // and continue - existingHost.SetIds = append(existingHost.SetIds, query.Id) - continue - } - - // This will be the first seen entry, so append the set ID to - // this host, and add it. - host.SetIds = append(host.SetIds, query.Id) - hostResultSlice = append(hostResultSlice, host) - hostResultMap[host.ExternalId] = host - } - } - - return &pb.ListHostsResponse{ - Hosts: hostResultSlice, - }, nil -} - -func validateSet(s *hostsets.HostSet) error { - if s == nil { - return status.Error(codes.InvalidArgument, "set is nil") - } - var attrs SetAttributes - attrMap := s.GetAttributes().AsMap() - if err := mapstructure.Decode(attrMap, &attrs); err != nil { - return status.Errorf(codes.InvalidArgument, "error decoding set attributes: %s", err) - } - - badFields := make(map[string]string) - _, filterSet := attrMap[ConstListInstancesFilter] - _, instanceGroupSet := attrMap[ConstInstanceGroup] - - if instanceGroupSet && filterSet { - badFields["attributes"] = "must set instance group or filter, cannot set both" - } else if instanceGroupSet && len(attrs.InstanceGroup) == 0 { - badFields[fmt.Sprintf("attributes.%s", ConstInstanceGroup)] = "must not be empty." - } else if filterSet && len(attrs.Filter) == 0 { - badFields[fmt.Sprintf("attributes.%s", ConstListInstancesFilter)] = "must not be empty." - } - - for f := range attrMap { - if _, ok := allowedSetFields[f]; !ok { - badFields[fmt.Sprintf("attributes.%s", f)] = "Unrecognized field." - } - } - - if len(badFields) > 0 { - return errors.InvalidArgumentError("Invalid arguments in the new set", badFields) - } - return nil } diff --git a/plugin/attributes.go b/plugin/service/host/attributes.go similarity index 99% rename from plugin/attributes.go rename to plugin/service/host/attributes.go index af1bb68..d330c61 100644 --- a/plugin/attributes.go +++ b/plugin/service/host/attributes.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host import ( "fmt" diff --git a/plugin/attributes_test.go b/plugin/service/host/attributes_test.go similarity index 99% rename from plugin/attributes_test.go rename to plugin/service/host/attributes_test.go index 97885e7..a8ae2b6 100644 --- a/plugin/attributes_test.go +++ b/plugin/service/host/attributes_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host import ( "testing" diff --git a/plugin/client.go b/plugin/service/host/client.go similarity index 99% rename from plugin/client.go rename to plugin/service/host/client.go index 0a7d20f..74f198f 100644 --- a/plugin/client.go +++ b/plugin/service/host/client.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host import ( "context" diff --git a/plugin/client_test.go b/plugin/service/host/client_test.go similarity index 99% rename from plugin/client_test.go rename to plugin/service/host/client_test.go index 6834cab..10de4f3 100644 --- a/plugin/client_test.go +++ b/plugin/service/host/client_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host import ( "testing" diff --git a/plugin/const.go b/plugin/service/host/const.go similarity index 96% rename from plugin/const.go rename to plugin/service/host/const.go index fc5af9d..161c92a 100644 --- a/plugin/const.go +++ b/plugin/service/host/const.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host const ( // ConstListInstancesFilter refers to a Google Cloud SDK filter to search for instances diff --git a/plugin/service/host/plugin.go b/plugin/service/host/plugin.go new file mode 100644 index 0000000..f7bf1ea --- /dev/null +++ b/plugin/service/host/plugin.go @@ -0,0 +1,285 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package host + +import ( + "context" + "fmt" + + compute "cloud.google.com/go/compute/apiv1" + computepb "cloud.google.com/go/compute/apiv1/computepb" + errors "github.com/hashicorp/boundary-plugin-gcp/internal/errors" + "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets" + pb "github.com/hashicorp/boundary/sdk/pbs/plugin" + "github.com/mitchellh/mapstructure" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// HostPlugin implements the HostPluginServiceServer interface for the +// GCP host service plugin. +type HostPlugin struct { + pb.UnimplementedHostPluginServiceServer +} + +var ( + _ pb.HostPluginServiceServer = (*HostPlugin)(nil) +) + +// OnCreateCatalog is called when a dynamic host catalog is created. +func (p *HostPlugin) OnCreateCatalog(_ context.Context, req *pb.OnCreateCatalogRequest) (*pb.OnCreateCatalogResponse, error) { + catalog := req.GetCatalog() + if catalog == nil { + return nil, status.Error(codes.InvalidArgument, "catalog is nil") + } + + attrs := catalog.GetAttributes() + if attrs == nil { + return nil, status.Error(codes.InvalidArgument, "attributes are required") + } + + if _, err := getCatalogAttributes(attrs); err != nil { + return nil, err + } + + return &pb.OnCreateCatalogResponse{ + Persisted: &pb.HostCatalogPersisted{ + Secrets: nil, + }, + }, nil +} + +// OnUpdateCatalog is called when a dynamic host catalog is updated. +func (p *HostPlugin) OnUpdateCatalog(_ context.Context, req *pb.OnUpdateCatalogRequest) (*pb.OnUpdateCatalogResponse, error) { + currentCatalog := req.GetCurrentCatalog() + if currentCatalog == nil { + return nil, status.Error(codes.FailedPrecondition, "current catalog is nil") + } + + secrets := req.GetNewCatalog().GetSecrets() + if secrets == nil { + // If new secrets weren't passed in, don't rotate what we have on + // update. + return &pb.OnUpdateCatalogResponse{}, nil + } + + return &pb.OnUpdateCatalogResponse{ + Persisted: &pb.HostCatalogPersisted{ + Secrets: nil, + }, + }, nil +} + +// OnDeleteCatalog is called when a dynamic host catalog is deleted. +func (p *HostPlugin) OnDeleteCatalog(ctx context.Context, req *pb.OnDeleteCatalogRequest) (*pb.OnDeleteCatalogResponse, error) { + catalog := req.GetCatalog() + if catalog == nil { + return nil, status.Error(codes.InvalidArgument, "new catalog is nil") + } + + attrs := catalog.GetAttributes() + if attrs == nil { + return nil, status.Error(codes.InvalidArgument, "new catalog missing attributes") + } + + if _, err := getCatalogAttributes(attrs); err != nil { + return nil, err + } + + return &pb.OnDeleteCatalogResponse{}, nil +} + +// OnCreateSet is called when a dynamic host set is created. +func (p *HostPlugin) OnCreateSet(_ context.Context, req *pb.OnCreateSetRequest) (*pb.OnCreateSetResponse, error) { + if err := validateSet(req.GetSet()); err != nil { + return nil, err + } + return &pb.OnCreateSetResponse{}, nil +} + +// OnUpdateSet is called when a dynamic host set is updated. +func (p *HostPlugin) OnUpdateSet(_ context.Context, req *pb.OnUpdateSetRequest) (*pb.OnUpdateSetResponse, error) { + if err := validateSet(req.GetNewSet()); err != nil { + return nil, err + } + return &pb.OnUpdateSetResponse{}, nil +} + +// OnDeleteSet is called when a dynamic host set is deleted. +func (p *HostPlugin) OnDeleteSet(ctx context.Context, req *pb.OnDeleteSetRequest) (*pb.OnDeleteSetResponse, error) { + return &pb.OnDeleteSetResponse{}, nil +} + +// ListHosts returns the list of instances based on filter or instance group name. +func (p *HostPlugin) ListHosts(ctx context.Context, req *pb.ListHostsRequest) (*pb.ListHostsResponse, error) { + catalog := req.GetCatalog() + if catalog == nil { + return nil, status.Error(codes.InvalidArgument, "catalog is nil") + } + + catalogAttrsRaw := catalog.GetAttributes() + if catalogAttrsRaw == nil { + return nil, status.Error(codes.InvalidArgument, "catalog missing attributes") + } + + catalogAttributes, err := getCatalogAttributes(catalogAttrsRaw) + if err != nil { + return nil, err + } + + sets := req.GetSets() + if sets == nil { + return nil, status.Error(codes.InvalidArgument, "sets is nil") + } + + type hostSetQuery struct { + Id string + InputInstances *computepb.ListInstancesRequest + InputGroups *computepb.ListInstancesInstanceGroupsRequest + Project string + Zone string + Output []*computepb.Instance + OutputHosts []*pb.ListHostsResponseHost + } + + queries := make([]hostSetQuery, len(sets)) + for i, set := range sets { + // Validate Id since we use it in output + if set.GetId() == "" { + return nil, status.Error(codes.InvalidArgument, "set missing id") + } + + if set.GetAttributes() == nil { + return nil, status.Error(codes.InvalidArgument, "set missing attributes") + } + setAttrs, err := getSetAttributes(set.GetAttributes()) + if err != nil { + return nil, err + } + + if setAttrs.InstanceGroup != "" { + queries[i] = hostSetQuery{ + Id: set.GetId(), + InputGroups: buildListInstanceGroupsRequest(setAttrs, catalogAttributes), + } + } else { + queries[i] = hostSetQuery{ + Id: set.GetId(), + InputInstances: buildListInstancesRequest(setAttrs, catalogAttributes), + } + } + } + + instancesClient, err := compute.NewInstancesRESTClient(ctx) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "error creating NewInstancesRESTClient: %s", err) + } + + instanceGroupsClient, err := compute.NewInstanceGroupsRESTClient(ctx) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "error creating NewInstanceGroupsRESTClient: %s", err) + } + + gclient := GoogleClient{ + InstancesClient: instancesClient, + InstanceGroupClient: instanceGroupsClient, + Context: ctx, + } + + // Run all queries now and assemble output. + var maxLen int + for i, query := range queries { + var output []*computepb.Instance + if query.InputGroups != nil { + output, err = gclient.getInstancesForInstanceGroup(query.InputGroups) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "error running getInstancesForInstanceGroup for host set id %q: %s", query.Id, err) + } + } else { + output, err = gclient.getInstances(query.InputInstances) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "error running getInstances for host set id %q: %s", query.Id, err) + } + } + + queries[i].Output = output + + // Process the output here, we will normalize this into a single + // set of hosts afterwards (possibly removing duplicates). + for _, instance := range output { + host, err := instanceToHost(instance) + + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "error processing host results for host set id %q: %s", query.Id, err) + } + + queries[i].OutputHosts = append(queries[i].OutputHosts, host) + maxLen++ + } + } + + // Now de-duplicate the hosts for the output. Maintain two sets: + // * A slice of hosts that will be used in the output + // * A map of hosts indexed by their external ID + // + // The map will is used in de-duplication to determine whether or + // not we've seen the host before to simply add the query's set ID + // to the list of set IDs that the host was seen in. + hostResultSlice := make([]*pb.ListHostsResponseHost, 0, maxLen) + hostResultMap := make(map[string]*pb.ListHostsResponseHost) + for _, query := range queries { + for _, host := range query.OutputHosts { + if existingHost, ok := hostResultMap[host.ExternalId]; ok { + // Existing host, just add the set ID to the list of seen IDs + // and continue + existingHost.SetIds = append(existingHost.SetIds, query.Id) + continue + } + + // This will be the first seen entry, so append the set ID to + // this host, and add it. + host.SetIds = append(host.SetIds, query.Id) + hostResultSlice = append(hostResultSlice, host) + hostResultMap[host.ExternalId] = host + } + } + + return &pb.ListHostsResponse{ + Hosts: hostResultSlice, + }, nil +} + +func validateSet(s *hostsets.HostSet) error { + if s == nil { + return status.Error(codes.InvalidArgument, "set is nil") + } + var attrs SetAttributes + attrMap := s.GetAttributes().AsMap() + if err := mapstructure.Decode(attrMap, &attrs); err != nil { + return status.Errorf(codes.InvalidArgument, "error decoding set attributes: %s", err) + } + + badFields := make(map[string]string) + _, filterSet := attrMap[ConstListInstancesFilter] + _, instanceGroupSet := attrMap[ConstInstanceGroup] + + if instanceGroupSet && filterSet { + badFields["attributes"] = "must set instance group or filter, cannot set both" + } else if instanceGroupSet && len(attrs.InstanceGroup) == 0 { + badFields[fmt.Sprintf("attributes.%s", ConstInstanceGroup)] = "must not be empty." + } else if filterSet && len(attrs.Filter) == 0 { + badFields[fmt.Sprintf("attributes.%s", ConstListInstancesFilter)] = "must not be empty." + } + + for f := range attrMap { + if _, ok := allowedSetFields[f]; !ok { + badFields[fmt.Sprintf("attributes.%s", f)] = "Unrecognized field." + } + } + + if len(badFields) > 0 { + return errors.InvalidArgumentError("Invalid arguments in the new set", badFields) + } + return nil +} diff --git a/plugin/plugin_test.go b/plugin/service/host/plugin_test.go similarity index 99% rename from plugin/plugin_test.go rename to plugin/service/host/plugin_test.go index 0fe5246..79a8ac0 100644 --- a/plugin/plugin_test.go +++ b/plugin/service/host/plugin_test.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package plugin +package host import ( "context" @@ -28,7 +28,7 @@ func wrapMap(t *testing.T, in map[string]interface{}) *structpb.Struct { func TestListHosts(t *testing.T) { t.Skip("TODO: this needs a secrets file to run - maybe only manually?") ctx := context.Background() - p := &GooglePlugin{} + p := &HostPlugin{} wd, err := os.Getwd() require.NoError(t, err) @@ -297,7 +297,7 @@ func TestListHosts(t *testing.T) { func TestCreateCatalog(t *testing.T) { t.Skip("TODO: this needs a secrets file to run - maybe only manually?") ctx := context.Background() - p := &GooglePlugin{} + p := &HostPlugin{} wd, err := os.Getwd() require.NoError(t, err) @@ -378,7 +378,7 @@ func TestCreateCatalog(t *testing.T) { func TestUpdateCatalog(t *testing.T) { t.Skip("TODO: this needs a secrets file to run - maybe only manually?") ctx := context.Background() - p := &GooglePlugin{} + p := &HostPlugin{} wd, err := os.Getwd() require.NoError(t, err) @@ -458,7 +458,7 @@ func TestUpdateCatalog(t *testing.T) { func TestCreateSet(t *testing.T) { ctx := context.Background() - p := &GooglePlugin{} + p := &HostPlugin{} cases := []struct { name string @@ -580,7 +580,7 @@ func TestCreateSet(t *testing.T) { func TestUpdateSet(t *testing.T) { ctx := context.Background() - p := &GooglePlugin{} + p := &HostPlugin{} cases := []struct { name string