From b4dd6198bf3673d4e2c06798c21edd57f105af7b Mon Sep 17 00:00:00 2001 From: Kat Lim Ruiz Date: Mon, 24 Aug 2026 09:25:41 -0500 Subject: [PATCH] feat: add terraform export support for auth0_token_exchange_profile Adds a resourceDataFetcher for auth0_token_exchange_profile, following the same checkpoint-pagination pattern used by auth0_user_attribute_profile, and registers it in the default resource list and parseResourceFetchers switch. Co-Authored-By: Claude Sonnet 5 --- docs/auth0_terraform_generate.md | 2 +- internal/cli/terraform.go | 2 ++ internal/cli/terraform_fetcher.go | 33 +++++++++++++++++++++++++- internal/cli/terraform_fetcher_test.go | 30 +++++++++++++++++++++++ internal/cli/terraform_test.go | 9 +++++++ 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/docs/auth0_terraform_generate.md b/docs/auth0_terraform_generate.md index 7b1a6796b..72026e616 100644 --- a/docs/auth0_terraform_generate.md +++ b/docs/auth0_terraform_generate.md @@ -33,7 +33,7 @@ auth0 terraform generate [flags] ``` --force Skip confirmation. -o, --output-dir string Output directory for the generated Terraform config files. If not provided, the files will be saved in the current working directory. (default "./") - -r, --resources strings Resource types to generate Terraform config for. If not provided, config files for all available resources will be generated. (default [auth0_action,auth0_attack_protection,auth0_branding,auth0_branding_theme,auth0_phone_provider,auth0_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_flow,auth0_flow_vault_connection,auth0_form,auth0_email_provider,auth0_email_template,auth0_guardian,auth0_log_stream,auth0_network_acl,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_prompt_screen_renderer,auth0_resource_server,auth0_role,auth0_self_service_profile,auth0_tenant,auth0_trigger_actions,auth0_user_attribute_profile,auth0_prompt_screen_partial,auth0_phone_notification_template]) + -r, --resources strings Resource types to generate Terraform config for. If not provided, config files for all available resources will be generated. (default [auth0_action,auth0_attack_protection,auth0_branding,auth0_branding_theme,auth0_phone_provider,auth0_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_flow,auth0_flow_vault_connection,auth0_form,auth0_email_provider,auth0_email_template,auth0_guardian,auth0_log_stream,auth0_network_acl,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_prompt_screen_renderer,auth0_resource_server,auth0_role,auth0_self_service_profile,auth0_tenant,auth0_trigger_actions,auth0_user_attribute_profile,auth0_prompt_screen_partial,auth0_phone_notification_template,auth0_token_exchange_profile]) -v, --tf-version string Terraform version that ought to be used while generating the terraform files for resources. If not provided, 1.5.0 is used by default (default "1.5.0") ``` diff --git a/internal/cli/terraform.go b/internal/cli/terraform.go index 5ddee1b59..a73e1ebcb 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -129,6 +129,8 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API, apiv3 *auth0.API fetchers = append(fetchers, &triggerActionsResourceFetcher{api}) case "auth0_user_attribute_profile": fetchers = append(fetchers, &userAttributeProfilesResourceFetcher{api}) + case "auth0_token_exchange_profile": + fetchers = append(fetchers, &tokenExchangeProfileResourceFetcher{api}) default: err = errors.Join(err, fmt.Errorf("unsupported resource type: %s", resource)) } diff --git a/internal/cli/terraform_fetcher.go b/internal/cli/terraform_fetcher.go index 05655e5f2..5eaf52815 100644 --- a/internal/cli/terraform_fetcher.go +++ b/internal/cli/terraform_fetcher.go @@ -19,7 +19,7 @@ var ( "auth0_email_provider", "auth0_email_template", "auth0_guardian", "auth0_log_stream", "auth0_network_acl", "auth0_organization", "auth0_pages", "auth0_prompt", "auth0_prompt_custom_text", "auth0_prompt_screen_renderer", "auth0_resource_server", "auth0_role", "auth0_self_service_profile", "auth0_tenant", "auth0_trigger_actions", "auth0_user_attribute_profile", "auth0_prompt_screen_partial", - "auth0_phone_notification_template", + "auth0_phone_notification_template", "auth0_token_exchange_profile", } ) @@ -138,6 +138,10 @@ type ( phoneNotificationTemplateResourceFetcher struct { apiv3 *auth0.APIV3 } + + tokenExchangeProfileResourceFetcher struct { + api *auth0.API + } ) func (f *attackProtectionResourceFetcher) FetchData(_ context.Context) (importDataList, error) { @@ -818,6 +822,33 @@ func (f *userAttributeProfilesResourceFetcher) FetchData(ctx context.Context) (i return data, nil } +func (f *tokenExchangeProfileResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { + var data importDataList + + from := "" + for { + profiles, err := f.api.TokenExchange.List(ctx, management.From(from)) + if err != nil { + return nil, err + } + + for _, profile := range profiles.TokenExchangeProfiles { + data = append(data, importDataItem{ + ResourceName: "auth0_token_exchange_profile." + sanitizeResourceName(profile.GetName()), + ImportID: profile.GetID(), + }) + } + + if !profiles.HasNext() { + break + } + + from = profiles.Next + } + + return data, nil +} + func (f *actionResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { var data importDataList diff --git a/internal/cli/terraform_fetcher_test.go b/internal/cli/terraform_fetcher_test.go index 574763c3f..a981935e9 100644 --- a/internal/cli/terraform_fetcher_test.go +++ b/internal/cli/terraform_fetcher_test.go @@ -2448,6 +2448,36 @@ func TestUserAttributeProfileResourceFetcher(t *testing.T) { }) } +func TestTokenExchangeProfileResourceFetcher(t *testing.T) { + t.Run("it successfully generates token exchange profile import data", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tokenExchangeAPI := mock.NewMockTokenExchangeAPI(ctrl) + + tokenExchangeAPI.EXPECT(). + List(gomock.Any(), gomock.Any()). + Return(&management.TokenExchangeProfileList{ + TokenExchangeProfiles: []*management.TokenExchangeProfile{ + { + ID: auth0.String("tep_123456"), + Name: auth0.String("Token Exchange Profile 1"), + }}}, nil) + + fetcher := tokenExchangeProfileResourceFetcher{ + api: &auth0.API{ + TokenExchange: tokenExchangeAPI, + }, + } + + data, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + assert.Len(t, data, 1) + assert.Equal(t, data[0].ResourceName, "auth0_token_exchange_profile.token_exchange_profile_1") + assert.Greater(t, len(data[0].ImportID), 0) + }) +} + func Test_promptScreenPartialResourceFetcher_FetchData(t *testing.T) { t.Run("it successfully retrieves screen partial prompts data", func(t *testing.T) { fetcher := promptScreenPartialResourceFetcher{} diff --git a/internal/cli/terraform_test.go b/internal/cli/terraform_test.go index 68b1120f3..9ef809ac8 100644 --- a/internal/cli/terraform_test.go +++ b/internal/cli/terraform_test.go @@ -488,6 +488,15 @@ func TestTerraformInputs_ParseResourceFetchers(t *testing.T) { &phoneNotificationTemplateResourceFetcher{apiv3}, }, }, + { + name: "it can successfully parse resources: auth0_token_exchange_profile", + input: terraformInputs{ + Resources: []string{"auth0_token_exchange_profile"}, + }, + expectedDataFetchers: []resourceDataFetcher{ + &tokenExchangeProfileResourceFetcher{api}, + }, + }, { name: "it can successfully parse resources: auth0_client, auth0_connection", input: terraformInputs{