github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/provider/oci/provider_integration_test.go (about)

     1  // Copyright 2018 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package oci_test
     5  
     6  import (
     7  	stdcontext "context"
     8  	"fmt"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	"github.com/juju/errors"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	"github.com/juju/utils/v3"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/cloud"
    19  	"github.com/juju/juju/environs"
    20  	environscloudspec "github.com/juju/juju/environs/cloudspec"
    21  	"github.com/juju/juju/environs/config"
    22  	envtesting "github.com/juju/juju/environs/testing"
    23  	"github.com/juju/juju/provider/oci"
    24  	ocitesting "github.com/juju/juju/provider/oci/testing"
    25  	jujutesting "github.com/juju/juju/testing"
    26  )
    27  
    28  type credentialsSuite struct {
    29  	testing.FakeHomeSuite
    30  
    31  	provider environs.EnvironProvider
    32  	spec     environscloudspec.CloudSpec
    33  }
    34  
    35  var _ = gc.Suite(&credentialsSuite{})
    36  
    37  var singleSectionTemplate = `[%s]
    38  user=fake
    39  fingerprint=%s
    40  key_file=%s
    41  tenancy=fake
    42  region=%s
    43  pass_phrase=%s
    44  `
    45  
    46  func newConfig(c *gc.C, attrs jujutesting.Attrs) *config.Config {
    47  	attrs = jujutesting.FakeConfig().Merge(attrs)
    48  	cfg, err := config.New(config.NoDefaults, attrs)
    49  	c.Assert(err, gc.IsNil)
    50  	return cfg
    51  }
    52  
    53  func fakeCloudSpec() environscloudspec.CloudSpec {
    54  	cred := fakeCredential()
    55  	return environscloudspec.CloudSpec{
    56  		Type:       "oci",
    57  		Name:       "oci",
    58  		Region:     "us-phoenix-1",
    59  		Endpoint:   "",
    60  		Credential: &cred,
    61  	}
    62  }
    63  
    64  func fakeCredential() cloud.Credential {
    65  	return cloud.NewCredential(cloud.HTTPSigAuthType, map[string]string{
    66  		"key":         ocitesting.PrivateKeyEncrypted,
    67  		"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
    68  		"pass-phrase": ocitesting.PrivateKeyPassphrase,
    69  		"tenancy":     "fake",
    70  		"user":        "fake",
    71  	})
    72  }
    73  
    74  func (s *credentialsSuite) SetUpTest(c *gc.C) {
    75  	s.FakeHomeSuite.SetUpTest(c)
    76  
    77  	s.provider = &oci.EnvironProvider{}
    78  	s.spec = fakeCloudSpec()
    79  }
    80  
    81  func (s *credentialsSuite) writeOCIConfig(c *gc.C, sections map[string]map[string]string) {
    82  	home := utils.Home()
    83  	sectionList := []string{}
    84  	for k, v := range sections {
    85  		pem_name := fmt.Sprintf(".oci/oci_api_key_%s.pem", k)
    86  		pem := filepath.Join(home, pem_name)
    87  		s.Home.AddFiles(c, testing.TestFile{
    88  			Name: pem_name,
    89  			Data: v["key"],
    90  		})
    91  		cfg := fmt.Sprintf(
    92  			singleSectionTemplate, k, v["fingerprint"],
    93  			pem, v["region"], v["pass-phrase"])
    94  		sectionList = append(sectionList, cfg)
    95  	}
    96  	s.Home.AddFiles(c, testing.TestFile{
    97  		Name: ".oci/config",
    98  		Data: strings.Join(sectionList, "\n")})
    99  }
   100  
   101  func (s *credentialsSuite) TestCredentialSchemas(c *gc.C) {
   102  	envtesting.AssertProviderAuthTypes(c, s.provider, "httpsig")
   103  }
   104  
   105  func (s *credentialsSuite) TestUserPassCredentialsValid(c *gc.C) {
   106  	envtesting.AssertProviderCredentialsValid(c, s.provider, "httpsig", map[string]string{
   107  		"user":        "fake",
   108  		"tenancy":     "fake",
   109  		"key":         ocitesting.PrivateKeyEncrypted,
   110  		"pass-phrase": ocitesting.PrivateKeyPassphrase,
   111  		"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
   112  		"region":      "us-phoenix-1",
   113  	})
   114  }
   115  
   116  func (s *credentialsSuite) TestPassphraseHiddenAttributes(c *gc.C) {
   117  	envtesting.AssertProviderCredentialsAttributesHidden(c, s.provider, "httpsig", "pass-phrase")
   118  }
   119  
   120  func (s *credentialsSuite) TestDetectCredentialsNotFound(c *gc.C) {
   121  	result := cloud.CloudCredential{
   122  		AuthCredentials: make(map[string]cloud.Credential),
   123  	}
   124  	creds, err := s.provider.DetectCredentials("")
   125  	c.Assert(err, gc.IsNil)
   126  	c.Assert(creds, gc.NotNil)
   127  	c.Assert(*creds, jc.DeepEquals, result)
   128  }
   129  
   130  func (s *credentialsSuite) TestDetectCredentials(c *gc.C) {
   131  	cfg := map[string]map[string]string{
   132  		"DEFAULT": {
   133  			"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
   134  			"pass-phrase": ocitesting.PrivateKeyPassphrase,
   135  			"key":         ocitesting.PrivateKeyEncrypted,
   136  		},
   137  	}
   138  	s.writeOCIConfig(c, cfg)
   139  	creds, err := s.provider.DetectCredentials("")
   140  	c.Assert(err, gc.IsNil)
   141  	c.Assert(len(creds.AuthCredentials), gc.Equals, 1)
   142  }
   143  
   144  func (s *credentialsSuite) TestDetectCredentialsWrongPassphrase(c *gc.C) {
   145  	cfg := map[string]map[string]string{
   146  		"DEFAULT": {
   147  			"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
   148  			"pass-phrase": "bogus",
   149  			"key":         ocitesting.PrivateKeyEncrypted,
   150  		},
   151  	}
   152  	s.writeOCIConfig(c, cfg)
   153  	_, err := s.provider.DetectCredentials("")
   154  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   155  }
   156  
   157  func (s *credentialsSuite) TestDetectCredentialsMultiSection(c *gc.C) {
   158  	cfg := map[string]map[string]string{
   159  		"DEFAULT": {
   160  			"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
   161  			"pass-phrase": ocitesting.PrivateKeyPassphrase,
   162  			"key":         ocitesting.PrivateKeyEncrypted,
   163  		},
   164  		"SECONDARY": {
   165  			"fingerprint": ocitesting.PrivateKeyUnencryptedFingerprint,
   166  			"pass-phrase": "",
   167  			"key":         ocitesting.PrivateKeyUnencrypted,
   168  		},
   169  	}
   170  	s.writeOCIConfig(c, cfg)
   171  	creds, err := s.provider.DetectCredentials("")
   172  	c.Assert(err, gc.IsNil)
   173  	c.Assert(len(creds.AuthCredentials), gc.Equals, 2)
   174  }
   175  
   176  func (s *credentialsSuite) TestDetectCredentialsMultiSectionInvalidConfig(c *gc.C) {
   177  	cfg := map[string]map[string]string{
   178  		// The default section is invalid, due to incorrect password
   179  		// This section should be skipped by DetectCredentials()
   180  		"DEFAULT": {
   181  			"fingerprint": ocitesting.PrivateKeyEncryptedFingerprint,
   182  			"pass-phrase": "bogus",
   183  			"key":         ocitesting.PrivateKeyEncrypted,
   184  		},
   185  		"SECONDARY": {
   186  			"fingerprint": ocitesting.PrivateKeyUnencryptedFingerprint,
   187  			"pass-phrase": "",
   188  			"key":         ocitesting.PrivateKeyUnencrypted,
   189  		},
   190  	}
   191  	s.writeOCIConfig(c, cfg)
   192  	creds, err := s.provider.DetectCredentials("")
   193  	c.Assert(err, gc.IsNil)
   194  	c.Assert(len(creds.AuthCredentials), gc.Equals, 1)
   195  	c.Assert(creds.DefaultRegion, gc.Equals, "")
   196  }
   197  
   198  func (s *credentialsSuite) TestOpen(c *gc.C) {
   199  	env, err := environs.Open(stdcontext.TODO(), s.provider, environs.OpenParams{
   200  		Cloud:  s.spec,
   201  		Config: newConfig(c, jujutesting.Attrs{"compartment-id": "fake"}),
   202  	})
   203  	c.Assert(err, jc.ErrorIsNil)
   204  	c.Assert(env, gc.NotNil)
   205  
   206  	env, err = environs.Open(stdcontext.TODO(), s.provider, environs.OpenParams{
   207  		Cloud:  s.spec,
   208  		Config: newConfig(c, nil),
   209  	})
   210  	c.Check(err, gc.ErrorMatches, "compartment-id may not be empty")
   211  	c.Assert(env, gc.IsNil)
   212  }