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 }