| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- package gcp
- import (
- "encoding/json"
- "fmt"
- "github.com/opencost/opencost/pkg/cloud"
- "google.golang.org/api/option"
- )
- const ServiceAccountKeyAuthorizerType = "GCPServiceAccountKey"
- const WorkloadIdentityAuthorizerType = "GCPWorkloadIdentity"
- // Authorizer provide a []option.ClientOption which is used in when creating clients in the GCP SDK
- type Authorizer interface {
- cloud.Authorizer
- CreateGCPClientOptions() ([]option.ClientOption, error)
- }
- // SelectAuthorizerByType is an implementation of AuthorizerSelectorFn and acts as a register for Authorizer types
- func SelectAuthorizerByType(typeStr string) (Authorizer, error) {
- switch typeStr {
- case ServiceAccountKeyAuthorizerType:
- return &ServiceAccountKey{}, nil
- case WorkloadIdentityAuthorizerType:
- return &WorkloadIdentity{}, nil
- default:
- return nil, fmt.Errorf("GCP: provider authorizer type '%s' is not valid", typeStr)
- }
- }
- type ServiceAccountKey struct {
- Key map[string]string `json:"key"`
- }
- // MarshalJSON custom json marshalling functions, sets properties as tagged in struct and sets the authorizer type property
- func (gkc *ServiceAccountKey) MarshalJSON() ([]byte, error) {
- fmap := make(map[string]any, 2)
- fmap[cloud.AuthorizerTypeProperty] = ServiceAccountKeyAuthorizerType
- fmap["key"] = gkc.Key
- return json.Marshal(fmap)
- }
- func (gkc *ServiceAccountKey) Validate() error {
- if gkc.Key == nil || len(gkc.Key) == 0 {
- return fmt.Errorf("ServiceAccountKey: missing Key")
- }
- return nil
- }
- func (gkc *ServiceAccountKey) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- thatConfig, ok := config.(*ServiceAccountKey)
- if !ok {
- return false
- }
- if len(gkc.Key) != len(thatConfig.Key) {
- return false
- }
- for k, v := range gkc.Key {
- if thatConfig.Key[k] != v {
- return false
- }
- }
- return true
- }
- func (gkc *ServiceAccountKey) Sanitize() cloud.Config {
- redactedMap := make(map[string]string, len(gkc.Key))
- for key := range gkc.Key {
- redactedMap[key] = cloud.Redacted
- }
- return &ServiceAccountKey{
- Key: redactedMap,
- }
- }
- func (gkc *ServiceAccountKey) CreateGCPClientOptions() ([]option.ClientOption, error) {
- err := gkc.Validate()
- if err != nil {
- return nil, err
- }
- b, err := json.Marshal(gkc.Key)
- if err != nil {
- return nil, fmt.Errorf("Key: failed to marshal Key: %s", err.Error())
- }
- clientOption := option.WithCredentialsJSON(b)
- // The creation of the BigQuery Client is where FAILED_CONNECTION CloudConnectionStatus is recorded for GCP
- return []option.ClientOption{clientOption}, nil
- }
- // WorkloadIdentity passes an empty slice of client options which causes the GCP SDK to check for the workload identity in the environment
- type WorkloadIdentity struct{}
- // MarshalJSON custom json marshalling functions, sets properties as tagged in struct and sets the authorizer type property
- func (wi *WorkloadIdentity) MarshalJSON() ([]byte, error) {
- fmap := make(map[string]any, 1)
- fmap[cloud.AuthorizerTypeProperty] = WorkloadIdentityAuthorizerType
- return json.Marshal(fmap)
- }
- func (wi *WorkloadIdentity) Validate() error {
- return nil
- }
- func (wi *WorkloadIdentity) Equals(config cloud.Config) bool {
- if config == nil {
- return false
- }
- _, ok := config.(*WorkloadIdentity)
- if !ok {
- return false
- }
- return true
- }
- func (wi *WorkloadIdentity) Sanitize() cloud.Config {
- return &WorkloadIdentity{}
- }
- func (wi *WorkloadIdentity) CreateGCPClientOptions() ([]option.ClientOption, error) {
- return []option.ClientOption{}, nil
- }
|