diff --git a/.github/workflows/provider-test.yaml b/.github/workflows/provider-test.yaml index 48758d0690..649e68138d 100644 --- a/.github/workflows/provider-test.yaml +++ b/.github/workflows/provider-test.yaml @@ -59,6 +59,9 @@ jobs: - name: Set Client Secret Path run: echo "${{ secrets.ARM_CLIENT_SECRET }}" >"${RUNNER_TEMP}/client-secret" && echo "ARM_CLIENT_SECRET_PATH=${RUNNER_TEMP}/client-secret" >>${GITHUB_ENV} + - name: Set Client Certificate Path + run: echo "${{ secrets.ARM_CLIENT_CERTIFICATE }}" | base64 -d >"${RUNNER_TEMP}/client-certificate.pfx" && echo "ARM_CLIENT_CERTIFICATE_PATH=${RUNNER_TEMP}/client-certificate.pfx" >>${GITHUB_ENV} + - name: Run provider tests run: make testacc TEST=./internal/provider TESTARGS="-run '^TestAcc'" env: diff --git a/internal/clients/builder.go b/internal/clients/builder.go index 44fa8192ce..41c277746f 100644 --- a/internal/clients/builder.go +++ b/internal/clients/builder.go @@ -34,7 +34,7 @@ func (b *ClientBuilder) Build(ctx context.Context) (*Client, error) { authorizer, err := auth.NewAuthorizerFromCredentials(ctx, *b.AuthConfig, b.AuthConfig.Environment.MicrosoftGraph) if err != nil { - return nil, fmt.Errorf("unable to build authorizer for Resource Manager API: %+v", err) + return nil, fmt.Errorf("unable to build authorizer: %+v", err) } client.Environment = b.AuthConfig.Environment diff --git a/internal/provider/provider.go b/internal/provider/provider.go index c755ba1854..5b5e07ad89 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -287,7 +287,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc { ClientCertificatePassword: d.Get("client_certificate_password").(string), ClientCertificatePath: d.Get("client_certificate_path").(string), ClientSecret: *clientSecret, - OIDCAssertionToken: idToken, + OIDCAssertionToken: *idToken, GitHubOIDCTokenRequestURL: d.Get("oidc_request_url").(string), GitHubOIDCTokenRequestToken: d.Get("oidc_request_token").(string), EnableAuthenticatingUsingClientCertificate: true, @@ -344,24 +344,26 @@ func decodeCertificate(clientCertificate string) ([]byte, error) { return pfx, nil } -func oidcToken(d *schema.ResourceData) (string, error) { +func oidcToken(d *schema.ResourceData) (*string, error) { idToken := d.Get("oidc_token").(string) if path := d.Get("oidc_token_file_path").(string); path != "" { - fileToken, err := os.ReadFile(path) + fileTokenRaw, err := os.ReadFile(path) if err != nil { - return "", fmt.Errorf("reading OIDC Token from file %q: %v", path, err) + return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err) } - if idToken != "" && idToken != string(fileToken) { - return "", fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") + fileToken := strings.TrimSpace(string(fileTokenRaw)) + + if idToken != "" && idToken != fileToken { + return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") } - idToken = string(fileToken) + idToken = fileToken } - return idToken, nil + return &idToken, nil } func getClientId(d *schema.ResourceData) (*string, error) { diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 326b1378ef..00de46dafc 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -284,6 +284,63 @@ func testAccProvider_clientSecretAuthFromFiles(t *testing.T) { } func TestAccProvider_genericOidcAuth(t *testing.T) { + t.Run("fromEnvironment", testAccProvider_genericOidcAuthFromEnvironment) + t.Run("fromFiles", testAccProvider_genericOidcAuthFromFiles) +} + +func testAccProvider_genericOidcAuthFromEnvironment(t *testing.T) { + if os.Getenv("TF_ACC") == "" { + t.Skip("TF_ACC not set") + } + if os.Getenv("ARM_OIDC_TOKEN_FILE_PATH") == "" { + t.Skip("ARM_OIDC_TOKEN_FILE_PATH not set") + } + + // Ensure we are running using the expected env-vars + // t.SetEnv does automatic cleanup / resets the values after the test + t.Setenv("ARM_OIDC_TOKEN", "") + + provider := AzureADProvider() + ctx := context.Background() + + // Support only oidc authentication + provider.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { + envName := d.Get("environment").(string) + env, err := environments.FromName(envName) + if err != nil { + t.Fatalf("configuring environment %q: %v", envName, err) + } + + idToken, err := oidcToken(d) + if err != nil { + return nil, diag.FromErr(err) + } + + authConfig := &auth.Credentials{ + Environment: *env, + TenantID: d.Get("tenant_id").(string), + ClientID: d.Get("client_id").(string), + + EnableAuthenticationUsingOIDC: true, + OIDCAssertionToken: *idToken, + } + + return buildClient(ctx, provider, authConfig, "") + } + + d := provider.Configure(ctx, terraform.NewResourceConfigRaw(nil)) + if d != nil && d.HasError() { + t.Fatalf("err: %+v", d) + } + + if errs := testCheckProvider(provider); len(errs) > 0 { + for _, err := range errs { + t.Error(err) + } + } +} + +func testAccProvider_genericOidcAuthFromFiles(t *testing.T) { if os.Getenv("TF_ACC") == "" { t.Skip("TF_ACC not set") } @@ -291,6 +348,10 @@ func TestAccProvider_genericOidcAuth(t *testing.T) { t.Skip("ARM_OIDC_TOKEN not set") } + // Ensure we are running using the expected env-vars + // t.SetEnv does automatic cleanup / resets the values after the test + t.Setenv("ARM_OIDC_TOKEN_FILE_PATH", "") + provider := AzureADProvider() ctx := context.Background() @@ -313,7 +374,7 @@ func TestAccProvider_genericOidcAuth(t *testing.T) { ClientID: d.Get("client_id").(string), EnableAuthenticationUsingOIDC: true, - OIDCAssertionToken: idToken, + OIDCAssertionToken: *idToken, } return buildClient(ctx, provider, authConfig, "")