Files
threshold-plugin-gcp/plugin/service/host/attributes.go
T

139 lines
3.9 KiB
Go
Raw Normal View History

2024-04-02 15:47:49 -04:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2024-09-16 14:28:54 -04:00
package host
2024-04-02 15:47:49 -04:00
import (
"fmt"
computepb "cloud.google.com/go/compute/apiv1/computepb"
2024-09-16 12:20:08 -04:00
cred "github.com/hashicorp/boundary-plugin-gcp/internal/credential"
"github.com/hashicorp/boundary-plugin-gcp/internal/errors"
"github.com/hashicorp/boundary-plugin-gcp/internal/values"
2024-04-02 15:47:49 -04:00
"github.com/mitchellh/mapstructure"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/structpb"
)
2024-08-06 11:51:00 -04:00
// CatalogAttributes defines a set of attributes for the host catalog
2024-04-02 15:47:49 -04:00
type CatalogAttributes struct {
*cred.CredentialAttributes
}
func getCatalogAttributes(in *structpb.Struct) (*CatalogAttributes, error) {
unknownFields := values.StructFields(in)
badFields := make(map[string]string)
var err error
credAttributes, err := cred.GetCredentialAttributes(in)
if err != nil {
return nil, err
}
for s := range unknownFields {
switch s {
// Ignore knownFields from CredentialAttributes
2024-09-17 10:50:10 -04:00
case cred.ConstProjectId:
2024-04-02 15:47:49 -04:00
continue
case cred.ConstZone:
continue
2024-09-17 10:50:10 -04:00
case cred.ConstDisableCredentialRotation:
continue
case cred.ConstClientEmail:
continue
case cred.ConstTargetServiceAccountID:
continue
2024-04-02 15:47:49 -04:00
default:
badFields[fmt.Sprintf("attributes.%s", s)] = "unrecognized field"
}
}
if len(badFields) > 0 {
return nil, errors.InvalidArgumentError("Invalid arguments in catalog attributes", badFields)
}
return &CatalogAttributes{
CredentialAttributes: credAttributes,
}, nil
}
2024-08-06 11:51:00 -04:00
// SetAttributes defines attributes fro the host set
2024-04-02 15:47:49 -04:00
type SetAttributes struct {
Filter string `mapstructure:"filter"`
InstanceGroup string `mapstructure:"instance_group"`
}
func getSetAttributes(in *structpb.Struct) (*SetAttributes, error) {
var setAttrs SetAttributes
badFields := make(map[string]string)
unknownFields := values.StructFields(in)
2024-08-06 11:51:00 -04:00
if _, filter := unknownFields[ConstListInstancesFilter]; filter {
if _, ig := unknownFields[ConstInstanceGroup]; ig {
return nil, errors.InvalidArgumentError("Error in the attributes provided, cannot define both filter and instance group", nil)
}
}
2024-04-02 15:47:49 -04:00
delete(unknownFields, ConstListInstancesFilter)
delete(unknownFields, ConstInstanceGroup)
for a := range unknownFields {
badFields[fmt.Sprintf("attributes.%s", a)] = "unrecognized field"
}
if len(badFields) > 0 {
return nil, errors.InvalidArgumentError("Error in the attributes provided", badFields)
}
// Mapstructure complains if it expects a slice as output and sees a scalar
// value. Rather than use WeakDecode and risk unintended consequences, I'm
// manually making this change if necessary.
inMap := in.AsMap()
if filtersRaw, ok := inMap[ConstListInstancesFilter]; ok {
switch filterVal := filtersRaw.(type) {
case string:
inMap[ConstListInstancesFilter] = string(filterVal)
}
}
2024-08-06 11:51:00 -04:00
2024-04-02 15:47:49 -04:00
if instanceGroupRaw, ok := inMap[ConstInstanceGroup]; ok {
switch instanceGroupValue := instanceGroupRaw.(type) {
case string:
inMap[ConstInstanceGroup] = string(instanceGroupValue)
}
}
if err := mapstructure.Decode(inMap, &setAttrs); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "error decoding set attributes: %s", err)
}
return &setAttrs, nil
}
func buildListInstancesRequest(attributes *SetAttributes, catalog *CatalogAttributes) *computepb.ListInstancesRequest {
request := &computepb.ListInstancesRequest{
2024-09-17 10:50:10 -04:00
Project: catalog.ProjectId,
2024-04-02 15:47:49 -04:00
Zone: catalog.Zone,
}
if len(attributes.Filter) > 1 {
request.Filter = &attributes.Filter
}
return request
}
func buildListInstanceGroupsRequest(attributes *SetAttributes, catalog *CatalogAttributes) *computepb.ListInstancesInstanceGroupsRequest {
request := &computepb.ListInstancesInstanceGroupsRequest{
InstanceGroup: attributes.InstanceGroup,
2024-09-17 10:50:10 -04:00
Project: catalog.ProjectId,
2024-04-02 15:47:49 -04:00
Zone: catalog.Zone,
}
if len(attributes.Filter) > 1 {
request.Filter = &attributes.Filter
}
return request
}