configuration.go raw

   1  // Copyright (c) 2016, 2018, 2025, Oracle and/or its affiliates.  All rights reserved.
   2  // This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
   3  
   4  package auth
   5  
   6  import (
   7  	"crypto/rsa"
   8  	"fmt"
   9  
  10  	"github.com/nrdcg/oci-go-sdk/common/v1065"
  11  )
  12  
  13  type instancePrincipalConfigurationProvider struct {
  14  	keyProvider instancePrincipalKeyProvider
  15  	region      *common.Region
  16  }
  17  
  18  // InstancePrincipalConfigurationProvider returns a configuration for instance principals
  19  func InstancePrincipalConfigurationProvider() (common.ConfigurationProvider, error) {
  20  	return newInstancePrincipalConfigurationProvider("", nil)
  21  }
  22  
  23  // InstancePrincipalConfigurationProviderForRegion returns a configuration for instance principals with a given region
  24  func InstancePrincipalConfigurationProviderForRegion(region common.Region) (common.ConfigurationProvider, error) {
  25  	return newInstancePrincipalConfigurationProvider(region, nil)
  26  }
  27  
  28  // InstancePrincipalConfigurationProviderWithCustomClient returns a configuration for instance principals using a modifier function to modify the HTTPRequestDispatcher
  29  func InstancePrincipalConfigurationProviderWithCustomClient(modifier func(common.HTTPRequestDispatcher) (common.HTTPRequestDispatcher, error)) (common.ConfigurationProvider, error) {
  30  	return newInstancePrincipalConfigurationProvider("", modifier)
  31  }
  32  
  33  // InstancePrincipalConfigurationForRegionWithCustomClient returns a configuration for instance principals with a given region using a modifier function to modify the HTTPRequestDispatcher
  34  func InstancePrincipalConfigurationForRegionWithCustomClient(region common.Region, modifier func(common.HTTPRequestDispatcher) (common.HTTPRequestDispatcher, error)) (common.ConfigurationProvider, error) {
  35  	return newInstancePrincipalConfigurationProvider(region, modifier)
  36  }
  37  
  38  func newInstancePrincipalConfigurationProvider(region common.Region, modifier func(common.HTTPRequestDispatcher) (common.HTTPRequestDispatcher, error)) (common.ConfigurationProvider, error) {
  39  	var err error
  40  	var keyProvider *instancePrincipalKeyProvider
  41  	if keyProvider, err = newInstancePrincipalKeyProvider(modifier); err != nil {
  42  		return nil, fmt.Errorf("failed to create a new key provider for instance principal: %s", err.Error())
  43  	}
  44  	if len(region) > 0 {
  45  		return instancePrincipalConfigurationProvider{keyProvider: *keyProvider, region: &region}, nil
  46  	}
  47  	return instancePrincipalConfigurationProvider{keyProvider: *keyProvider, region: nil}, nil
  48  }
  49  
  50  // InstancePrincipalConfigurationWithCerts returns a configuration for instance principals with a given region and hardcoded certificates in lieu of metadata service certs
  51  func InstancePrincipalConfigurationWithCerts(region common.Region, leafCertificate, leafPassphrase, leafPrivateKey []byte, intermediateCertificates [][]byte) (common.ConfigurationProvider, error) {
  52  	leafCertificateRetriever := staticCertificateRetriever{Passphrase: leafPassphrase, CertificatePem: leafCertificate, PrivateKeyPem: leafPrivateKey}
  53  
  54  	//The .Refresh() call actually reads the certificates from the inputs
  55  	err := leafCertificateRetriever.Refresh()
  56  	if err != nil {
  57  		return nil, err
  58  	}
  59  
  60  	certificate := leafCertificateRetriever.Certificate()
  61  
  62  	tenancyID := extractTenancyIDFromCertificate(certificate)
  63  	fedClient, err := newX509FederationClientWithCerts(region, tenancyID, leafCertificate, leafPassphrase, leafPrivateKey, intermediateCertificates, *newDispatcherModifier(nil))
  64  	if err != nil {
  65  		return nil, err
  66  	}
  67  
  68  	provider := instancePrincipalConfigurationProvider{
  69  		keyProvider: instancePrincipalKeyProvider{
  70  			Region:           region,
  71  			FederationClient: fedClient,
  72  			TenancyID:        tenancyID,
  73  		},
  74  		region: &region,
  75  	}
  76  	return provider, nil
  77  
  78  }
  79  
  80  func (p instancePrincipalConfigurationProvider) PrivateRSAKey() (*rsa.PrivateKey, error) {
  81  	return p.keyProvider.PrivateRSAKey()
  82  }
  83  
  84  func (p instancePrincipalConfigurationProvider) KeyID() (string, error) {
  85  	return p.keyProvider.KeyID()
  86  }
  87  
  88  func (p instancePrincipalConfigurationProvider) TenancyOCID() (string, error) {
  89  	return p.keyProvider.TenancyOCID()
  90  }
  91  
  92  func (p instancePrincipalConfigurationProvider) UserOCID() (string, error) {
  93  	return "", nil
  94  }
  95  
  96  func (p instancePrincipalConfigurationProvider) KeyFingerprint() (string, error) {
  97  	return "", nil
  98  }
  99  
 100  func (p instancePrincipalConfigurationProvider) Region() (string, error) {
 101  	if p.region == nil {
 102  		region := p.keyProvider.RegionForFederationClient()
 103  		common.Debugf("Region in instance principal configuration provider is nil. Returning federation clients region: %s", region)
 104  		return string(region), nil
 105  	}
 106  	return string(*p.region), nil
 107  }
 108  
 109  func (p instancePrincipalConfigurationProvider) AuthType() (common.AuthConfig, error) {
 110  	return common.AuthConfig{common.InstancePrincipal, false, nil}, fmt.Errorf("unsupported, keep the interface")
 111  }
 112  
 113  func (p instancePrincipalConfigurationProvider) Refreshable() bool {
 114  	return true
 115  }
 116