Skip to content

Commit

Permalink
Merge pull request #20570 from hashicorp/tests/provider-auth
Browse files Browse the repository at this point in the history
Tests: Provider authentication
  • Loading branch information
manicminer authored Feb 21, 2023
2 parents 61893bf + 57bcf13 commit 8ba7a3f
Show file tree
Hide file tree
Showing 112 changed files with 544 additions and 28,841 deletions.
63 changes: 63 additions & 0 deletions .github/workflows/provider-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: Provider Tests
on:
pull_request:
types: ["opened", "synchronize"]
paths:
- ".github/workflows/provider-test.yml"
- 'internal/**.go'
- 'vendor/github.com/hashicorp/go-azure-sdk/sdk/auth/**'
- 'vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/**'

permissions:
contents: read
id-token: write
pull-requests: read

jobs:
secrets-check:
runs-on: ubuntu-latest
outputs:
available: "${{ steps.check-secrets.outputs.available }}"
steps:
# we check for the ACTIONS_ID_TOKEN_REQUEST_URL variable as a proxy for other secrets
# it will be unset when running for a PR from a fork, in which case we don't run these tests
- id: check-secrets
run: |
if [[ "${ACTIONS_ID_TOKEN_REQUEST_URL}" == "" ]]; then
echo "available=false" | tee ${GITHUB_OUTPUT}
else
echo "available=true" | tee ${GITHUB_OUTPUT}
fi
provider-tests:
runs-on: [custom, linux, large]
needs: [secrets-check]
if: needs.secrets-check.outputs.available == 'true'
steps:
- name: Azure CLI login
run: az login --output none --username="${{ secrets.AZCLI_USERNAME }}" --password="${{ secrets.AZCLI_PASSWORD }}"

- name: Set OIDC Token
run: |
echo "ARM_OIDC_TOKEN=$(curl -H "Accept: application/json; api-version=2.0" -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" -H "Content-Type: application/json" -G --data-urlencode "audience=api://AzureADTokenExchange" "${ACTIONS_ID_TOKEN_REQUEST_URL}" | jq -r '.value')" >>${GITHUB_ENV}
- name: Checkout
uses: actions/checkout@v3

- name: Install Go
uses: actions/setup-go@v3
with:
go-version-file: ./.go-version

- name: Run provider tests
run: make testacc TEST=./internal/provider TESTARGS="-run '^TestAcc'"
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_CERTIFICATE: ${{ secrets.ARM_CLIENT_CERTIFICATE }}
ARM_CLIENT_CERTIFICATE_PASSWORD: ${{ secrets.ARM_CLIENT_CERTIFICATE_PASSWORD }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}

# vim: set ts=2 sts=2 sw=2 et:
9 changes: 2 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ require (
github.com/gofrs/uuid v4.0.0+incompatible
github.com/google/go-cmp v0.5.9
github.com/google/uuid v1.1.2
github.com/hashicorp/go-azure-helpers v0.51.0
github.com/hashicorp/go-azure-sdk v0.20230217.1150808
github.com/hashicorp/go-azure-helpers v0.52.0
github.com/hashicorp/go-azure-sdk v0.20230221.1105556
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-uuid v1.0.3
github.com/hashicorp/go-version v1.6.0
Expand All @@ -34,12 +34,10 @@ require (
require (
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg v1.0.0 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/golang-jwt/jwt/v4 v4.4.3 // indirect
github.com/golang/protobuf v1.5.2 // indirect
Expand All @@ -61,12 +59,9 @@ require (
github.com/hashicorp/terraform-registry-address v0.1.0 // indirect
github.com/hashicorp/terraform-svchost v0.0.0-20200729002733-f050f53b9734 // indirect
github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864 // indirect
github.com/manicminer/hamilton v0.55.0 // indirect
github.com/manicminer/hamilton-autorest v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
Expand Down
275 changes: 4 additions & 271 deletions go.sum

Large diffs are not rendered by default.

94 changes: 49 additions & 45 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc {
enableOidc = d.Get("use_oidc").(bool)
)

authConfig := auth.Credentials{
authConfig := &auth.Credentials{
Environment: *env,
ClientID: d.Get("client_id").(string),
TenantID: d.Get("tenant_id").(string),
Expand All @@ -413,58 +413,62 @@ func providerConfigure(p *schema.Provider) schema.ConfigureContextFunc {
EnableAuthenticationUsingGitHubOIDC: enableOidc,
}

skipProviderRegistration := d.Get("skip_provider_registration").(bool)

clientBuilder := clients.ClientBuilder{
AuthConfig: &authConfig,
DisableCorrelationRequestID: d.Get("disable_correlation_request_id").(bool),
DisableTerraformPartnerID: d.Get("disable_terraform_partner_id").(bool),
Features: expandFeatures(d.Get("features").([]interface{})),
MetadataHost: metadataHost,
PartnerID: d.Get("partner_id").(string),
SkipProviderRegistration: skipProviderRegistration,
StorageUseAzureAD: d.Get("storage_use_azuread").(bool),
SubscriptionID: d.Get("subscription_id").(string),
TerraformVersion: p.TerraformVersion,

// this field is intentionally not exposed in the provider block, since it's only used for
// platform level tracing
CustomCorrelationRequestID: os.Getenv("ARM_CORRELATION_REQUEST_ID"),
}

//lint:ignore SA1019 SDKv2 migration - staticcheck's own linter directives are currently being ignored under golanci-lint
stopCtx, ok := schema.StopContext(ctx) //nolint:staticcheck
if !ok {
stopCtx = ctx
}
return buildClient(ctx, p, d, authConfig)
}
}

client, err := clients.Build(stopCtx, clientBuilder)
if err != nil {
return nil, diag.FromErr(err)
}
func buildClient(ctx context.Context, p *schema.Provider, d *schema.ResourceData, authConfig *auth.Credentials) (*clients.Client, diag.Diagnostics) {
skipProviderRegistration := d.Get("skip_provider_registration").(bool)

clientBuilder := clients.ClientBuilder{
AuthConfig: authConfig,
DisableCorrelationRequestID: d.Get("disable_correlation_request_id").(bool),
DisableTerraformPartnerID: d.Get("disable_terraform_partner_id").(bool),
Features: expandFeatures(d.Get("features").([]interface{})),
MetadataHost: d.Get("metadata_host").(string),
PartnerID: d.Get("partner_id").(string),
SkipProviderRegistration: skipProviderRegistration,
StorageUseAzureAD: d.Get("storage_use_azuread").(bool),
SubscriptionID: d.Get("subscription_id").(string),
TerraformVersion: p.TerraformVersion,

// this field is intentionally not exposed in the provider block, since it's only used for
// platform level tracing
CustomCorrelationRequestID: os.Getenv("ARM_CORRELATION_REQUEST_ID"),
}

client.StopContext = stopCtx
//lint:ignore SA1019 SDKv2 migration - staticcheck's own linter directives are currently being ignored under golanci-lint
stopCtx, ok := schema.StopContext(ctx) //nolint:staticcheck
if !ok {
stopCtx = ctx
}

if !skipProviderRegistration {
// List all the available providers and their registration state to avoid unnecessary
// requests. This also lets us check if the provider credentials are correct.
providerList, err := client.Resource.ProvidersClient.List(ctx, nil, "")
if err != nil {
return nil, diag.Errorf("Unable to list provider registration status, it is possible that this is due to invalid "+
"credentials or the service principal does not have permission to use the Resource Manager API, Azure "+
"error: %s", err)
}
client, err := clients.Build(stopCtx, clientBuilder)
if err != nil {
return nil, diag.FromErr(err)
}

availableResourceProviders := providerList.Values()
requiredResourceProviders := resourceproviders.Required()
client.StopContext = stopCtx

if err := resourceproviders.EnsureRegistered(ctx, *client.Resource.ProvidersClient, availableResourceProviders, requiredResourceProviders); err != nil {
return nil, diag.Errorf(resourceProviderRegistrationErrorFmt, err)
}
if !skipProviderRegistration {
// List all the available providers and their registration state to avoid unnecessary
// requests. This also lets us check if the provider credentials are correct.
providerList, err := client.Resource.ProvidersClient.List(ctx, nil, "")
if err != nil {
return nil, diag.Errorf("Unable to list provider registration status, it is possible that this is due to invalid "+
"credentials or the service principal does not have permission to use the Resource Manager API, Azure "+
"error: %s", err)
}

return client, nil
availableResourceProviders := providerList.Values()
requiredResourceProviders := resourceproviders.Required()

if err := resourceproviders.EnsureRegistered(ctx, *client.Resource.ProvidersClient, availableResourceProviders, requiredResourceProviders); err != nil {
return nil, diag.Errorf(resourceProviderRegistrationErrorFmt, err)
}
}

return client, nil
}

func decodeCertificate(clientCertificate string) ([]byte, error) {
Expand Down
Loading

0 comments on commit 8ba7a3f

Please sign in to comment.