github.com/thiagoyeds/go-cloud@v0.26.0/secrets/azurekeyvault/akv_test.go (about) 1 // Copyright 2019 The Go Cloud Development Kit Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package azurekeyvault 16 17 import ( 18 "context" 19 "errors" 20 "log" 21 "os" 22 "strings" 23 "testing" 24 25 "github.com/Azure/azure-sdk-for-go/services/keyvault/v7.0/keyvault" 26 "github.com/Azure/go-autorest/autorest" 27 "github.com/Azure/go-autorest/autorest/azure" 28 "gocloud.dev/internal/testing/setup" 29 "gocloud.dev/secrets" 30 "gocloud.dev/secrets/driver" 31 "gocloud.dev/secrets/drivertest" 32 ) 33 34 // Prerequisites for --record mode 35 // 36 // 1. Sign-in to your Azure Subscription at http://portal.azure.com. 37 // 38 // 2. Create a KeyVault, see 39 // https://docs.microsoft.com/en-us/azure/key-vault/quick-create-portal. 40 // 41 // 3. Choose an authentication model. This test uses Service Principal, see 42 // https://docs.microsoft.com/en-us/rest/api/azure/index#register-your-client-application-with-azure-ad. 43 // For documentation on acceptable auth models, see 44 // https://docs.microsoft.com/en-us/azure/key-vault/key-vault-whatis. 45 // 46 // 4. Set your environment variables depending on the auth model selection. 47 // Modify helper initEnv() as needed. 48 // For Service Principal, please set the following, see 49 // https://docs.microsoft.com/en-us/go/azure/azure-sdk-go-authorization. 50 // 51 // - AZURE_TENANT_ID: Go to "Azure Active Directory", then "Properties". The 52 // "Directory ID" property is your AZURE_TENANT_ID. 53 // - AZURE_CLIENT_ID: Go to "Azure Active Directory", then "App Registrations", 54 // then "View all applications". The "Application ID" column shows your 55 // AZURE_CLIENT_ID. 56 // - AZURE_CLIENT_SECRET: Click on the application from the previous step, 57 // then "Settings" and then "Keys". Create a key and use it as your 58 // AZURE_CLIENT_SECRET. Make sure to save the value as it's hidden after 59 // the initial creation. 60 // - AZURE_ENVIRONMENT: (optional). 61 // - AZURE_AD_RESOURCE: (optional). 62 // 63 // 5. Create/Import a Key. This can be done in the Azure Portal under "Key vaults". 64 // 65 // 6. Update constants below to match your Azure KeyVault settings. 66 67 const ( 68 keyID1 = "https://go-cdk.vault.azure.net/keys/test1" 69 keyID2 = "https://go-cdk.vault.azure.net/keys/test2" 70 ) 71 72 type harness struct { 73 client *keyvault.BaseClient 74 close func() 75 } 76 77 func (h *harness) MakeDriver(ctx context.Context) (driver.Keeper, driver.Keeper, error) { 78 keeper1, err := openKeeper(h.client, keyID1, nil) 79 if err != nil { 80 return nil, nil, err 81 } 82 keeper2, err := openKeeper(h.client, keyID2, nil) 83 if err != nil { 84 return nil, nil, err 85 } 86 return keeper1, keeper2, nil 87 } 88 89 func (h *harness) Close() { 90 h.close() 91 } 92 93 func newHarness(ctx context.Context, t *testing.T) (drivertest.Harness, error) { 94 // Use initEnv to setup your environment variables. 95 var client *keyvault.BaseClient 96 if *setup.Record { 97 initEnv() 98 var err error 99 client, err = Dial() 100 if err != nil { 101 return nil, err 102 } 103 } else { 104 // Use a null authorizer for replay mode. 105 c := keyvault.NewWithoutDefaults() 106 client = &c 107 client.Authorizer = &autorest.NullAuthorizer{} 108 } 109 sender, done := setup.NewAzureKeyVaultTestClient(ctx, t) 110 client.Sender = sender 111 return &harness{ 112 client: client, 113 close: done, 114 }, nil 115 } 116 117 func initEnv() { 118 env, err := azure.EnvironmentFromName("AZUREPUBLICCLOUD") 119 if err != nil { 120 log.Fatalln(err) 121 } 122 123 // For Client Credentials authorization, set AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET 124 // For Client Certificate and Azure Managed Service Identity, see doc below for help 125 // https://github.com/Azure/azure-sdk-for-go 126 127 if os.Getenv("AZURE_TENANT_ID") == "" || 128 os.Getenv("AZURE_CLIENT_ID") == "" || 129 os.Getenv("AZURE_CLIENT_SECRET") == "" { 130 log.Fatal("Missing environment for recording tests, set AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET") 131 } 132 133 os.Setenv("AZURE_ENVIRONMENT", env.Name) 134 135 vaultEndpoint := strings.TrimSuffix(env.KeyVaultEndpoint, "/") 136 os.Setenv("AZURE_AD_RESOURCE", vaultEndpoint) 137 } 138 139 func TestConformance(t *testing.T) { 140 drivertest.RunConformanceTests(t, newHarness, []drivertest.AsTest{verifyAs{}}) 141 } 142 143 type verifyAs struct{} 144 145 func (v verifyAs) Name() string { 146 return "verify As function" 147 } 148 149 func (v verifyAs) ErrorCheck(k *secrets.Keeper, err error) error { 150 var e autorest.DetailedError 151 if !k.ErrorAs(err, &e) { 152 return errors.New("Keeper.ErrorAs failed") 153 } 154 return nil 155 } 156 157 // Key Vault-specific tests. 158 159 func TestNoConnectionError(t *testing.T) { 160 client := keyvault.NewWithoutDefaults() 161 k, err := OpenKeeper(&client, keyID1, nil) 162 if err != nil { 163 t.Fatal(err) 164 } 165 defer k.Close() 166 if _, err := k.Encrypt(context.Background(), []byte("secrets")); err == nil { 167 t.Error("Encrypt: got nil, want no connection error") 168 } 169 } 170 171 // This test no longer works on MacOS, as OpenKeeper always fails with "MSI not available". 172 /* 173 func TestOpenKeeper(t *testing.T) { 174 tests := []struct { 175 URL string 176 WantErr bool 177 }{ 178 // OK. 179 {"azurekeyvault://mykeyvault.vault.azure.net/keys/mykey/myversion", false}, 180 // No version -> OK. 181 {"azurekeyvault://mykeyvault.vault.azure.net/keys/mykey", false}, 182 // Setting algorithm query param -> OK. 183 {"azurekeyvault://mykeyvault.vault.azure.net/keys/mykey/myversion?algorithm=RSA-OAEP", false}, 184 // Invalid query parameter. 185 {"azurekeyvault://mykeyvault.vault.azure.net/keys/mykey/myversion?param=value", true}, 186 // Missing key vault name. 187 {"azurekeyvault:///vault.azure.net/keys/mykey/myversion", true}, 188 // Missing "keys". 189 {"azurekeyvault://mykeyvault.vault.azure.net/mykey/myversion", true}, 190 } 191 192 ctx := context.Background() 193 for _, test := range tests { 194 keeper, err := secrets.OpenKeeper(ctx, test.URL) 195 if (err != nil) != test.WantErr { 196 t.Errorf("%s: got error %v, want error %v", test.URL, err, test.WantErr) 197 } 198 if err == nil { 199 if err = keeper.Close(); err != nil { 200 t.Errorf("%s: got error during close: %v", test.URL, err) 201 } 202 } 203 } 204 } 205 */ 206 207 func TestKeyIDRE(t *testing.T) { 208 client := keyvault.NewWithoutDefaults() 209 210 testCases := []struct { 211 // input 212 keyID string 213 214 // output 215 keyVaultURI string 216 keyName string 217 keyVersion string 218 }{ 219 { 220 keyID: keyID1, 221 keyVaultURI: "https://go-cdk.vault.azure.net/", 222 keyName: "test1", 223 }, 224 { 225 keyID: keyID2, 226 keyVaultURI: "https://go-cdk.vault.azure.net/", 227 keyName: "test2", 228 }, 229 { 230 keyID: "https://mykeyvault.vault.azure.net/keys/mykey/myversion", 231 keyVaultURI: "https://mykeyvault.vault.azure.net/", 232 keyName: "mykey", 233 keyVersion: "myversion", 234 }, 235 { 236 keyID: "https://mykeyvault.vault.usgovcloudapi.net/keys/mykey/myversion", 237 keyVaultURI: "https://mykeyvault.vault.usgovcloudapi.net/", 238 keyName: "mykey", 239 keyVersion: "myversion", 240 }, 241 { 242 keyID: "https://mykeyvault.vault.region01.external.com/keys/mykey/myversion", 243 keyVaultURI: "https://mykeyvault.vault.region01.external.com/", 244 keyName: "mykey", 245 keyVersion: "myversion", 246 }, 247 } 248 249 for _, testCase := range testCases { 250 t.Run(testCase.keyID, func(t *testing.T) { 251 k, err := openKeeper(&client, testCase.keyID, nil) 252 if err != nil { 253 t.Fatal(err) 254 } 255 defer k.Close() 256 257 if k.keyVaultURI != testCase.keyVaultURI { 258 t.Errorf("got key vault URI %s, want key vault URI %s", k.keyVaultURI, testCase.keyVaultURI) 259 } 260 261 if k.keyName != testCase.keyName { 262 t.Errorf("got key name %s, want key name %s", k.keyName, testCase.keyName) 263 } 264 265 if k.keyVersion != testCase.keyVersion { 266 t.Errorf("got key version %s, want key version %s", k.keyVersion, testCase.keyVersion) 267 } 268 }) 269 } 270 }