go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/_motor/providers/resolver/resolver.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package resolver
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/rs/zerolog/log"
    11  	"go.mondoo.com/cnquery/motor"
    12  	v1 "go.mondoo.com/cnquery/motor/inventory/v1"
    13  	"go.mondoo.com/cnquery/motor/vault"
    14  	"google.golang.org/protobuf/proto"
    15  )
    16  
    17  var providerDevelopmentStatus = map[string]string{
    18  	"aws-ec2-ebs": "experimental",
    19  }
    20  
    21  func warnIncompleteFeature(backend string) {
    22  	if providerDevelopmentStatus[backend] != "" {
    23  		log.Warn().Str("feature", backend).Str("status", providerDevelopmentStatus[backend]).Msg("WARNING: you are using an early access feature")
    24  	}
    25  }
    26  
    27  // NewMotorConnection establishes a motor connection by using the provided provider configuration
    28  // By default, it uses the id detector mechanisms provided by the provider. User can overwrite that
    29  // behaviour by optionally passing id detector identifier
    30  func NewMotorConnection(ctx context.Context, tc *v1.Config, credsResolver vault.Resolver) (*motor.Motor, error) {
    31  	log.Debug().Msg("establish motor connection")
    32  	var m *motor.Motor
    33  
    34  	warnIncompleteFeature(tc.Type)
    35  
    36  	// we clone the config here, and replace all credential references with the real references
    37  	// the clone is important so that credentials are not leaked outside of the function
    38  	resolvedConfig := proto.Clone(tc).(*v1.Config)
    39  	// cloning a proto object with an empty map will result in the copied map being nil. make sure to initialize it
    40  	// to not break providers that check for nil.
    41  	if resolvedConfig.Options == nil {
    42  		resolvedConfig.Options = map[string]string{}
    43  	}
    44  	resolvedCredentials := []*vault.Credential{}
    45  	for i := range resolvedConfig.Credentials {
    46  		credential := resolvedConfig.Credentials[i]
    47  		if credential.SecretId != "" && credsResolver != nil {
    48  			resolvedCredential, err := credsResolver.GetCredential(credential)
    49  			if err != nil {
    50  				log.Debug().Str("secret-id", credential.SecretId).Err(err).Msg("could not fetch secret for motor connection")
    51  				return nil, err
    52  			}
    53  			credential = resolvedCredential
    54  		}
    55  		resolvedCredentials = append(resolvedCredentials, credential)
    56  	}
    57  	resolvedConfig.Credentials = resolvedCredentials
    58  
    59  	// establish connection
    60  	switch resolvedConfig.Type {
    61  	default:
    62  		return nil, fmt.Errorf("connection> unsupported backend '%s'", resolvedConfig.Type)
    63  	}
    64  
    65  	return m, nil
    66  }