From e1c013f2bcd2fc5fa07795dd7e780b0ce836f87f Mon Sep 17 00:00:00 2001 From: ramya18101 Date: Mon, 8 Sep 2025 16:33:33 +0530 Subject: [PATCH 1/2] support branding theme resource in terraform generation --- docs/auth0_terraform_generate.md | 2 +- internal/cli/terraform.go | 2 + internal/cli/terraform_fetcher.go | 21 ++++++++++- internal/cli/terraform_fetcher_test.go | 51 ++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/docs/auth0_terraform_generate.md b/docs/auth0_terraform_generate.md index 8f273d9f5..f4933e2b1 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_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]) + -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]) -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 dc0c02aab..f24fa745f 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -73,6 +73,8 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataF fetchers = append(fetchers, &attackProtectionResourceFetcher{}) case "auth0_branding": fetchers = append(fetchers, &brandingResourceFetcher{}) + case "auth0_branding_theme": + fetchers = append(fetchers, &brandingThemeResourceFetcher{}) case "auth0_phone_provider": fetchers = append(fetchers, &phoneProviderResourceFetcher{api}) case "auth0_client", "auth0_client_credentials": diff --git a/internal/cli/terraform_fetcher.go b/internal/cli/terraform_fetcher.go index 739ee4921..8b7f48456 100644 --- a/internal/cli/terraform_fetcher.go +++ b/internal/cli/terraform_fetcher.go @@ -12,7 +12,7 @@ import ( ) var ( - defaultResources = []string{"auth0_action", "auth0_attack_protection", "auth0_branding", "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"} + defaultResources = []string{"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"} ) type ( @@ -37,6 +37,10 @@ type ( brandingResourceFetcher struct{} + brandingThemeResourceFetcher struct { + api *auth0.API + } + phoneProviderResourceFetcher struct { api *auth0.API } @@ -139,6 +143,21 @@ func (f *brandingResourceFetcher) FetchData(_ context.Context) (importDataList, }, }, nil } +func (f *brandingThemeResourceFetcher) FetchData(_ context.Context) (importDataList, error) { + var data importDataList + + theme, err := f.api.BrandingTheme.Default(context.Background()) + if err != nil { + return nil, err + } + + data = append(data, importDataItem{ + ResourceName: "auth0_branding_theme." + sanitizeResourceName(theme.GetDisplayName()), + ImportID: theme.GetID(), + }) + + return data, nil +} func (f *phoneProviderResourceFetcher) 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 3a8a71f9a..0a43daaff 100644 --- a/internal/cli/terraform_fetcher_test.go +++ b/internal/cli/terraform_fetcher_test.go @@ -140,6 +140,57 @@ func TestBrandingResourceFetcher_FetchData(t *testing.T) { }) } +func TestBrandingThemeResourceFetcher_FetchData(t *testing.T) { + t.Run("it successfully retrieves branding theme data", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + brandingThemeAPI := mock.NewMockBrandingThemeAPI(ctrl) + brandingThemeAPI.EXPECT(). + Default(gomock.Any()). + Return(&management.BrandingTheme{ + ID: auth0.String("theme_123"), + DisplayName: auth0.String("My Theme"), + }, nil) + + fetcher := brandingThemeResourceFetcher{ + api: &auth0.API{ + BrandingTheme: brandingThemeAPI, + }, + } + + expectedData := importDataList{ + { + ResourceName: "auth0_branding_theme.my_theme", + ImportID: "theme_123", + }, + } + + data, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + assert.Equal(t, expectedData, data) + }) + + t.Run("it returns an error if api call fails", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + brandingThemeAPI := mock.NewMockBrandingThemeAPI(ctrl) + brandingThemeAPI.EXPECT(). + Default(gomock.Any()). + Return(nil, fmt.Errorf("failed to get default theme")) + + fetcher := brandingThemeResourceFetcher{ + api: &auth0.API{ + BrandingTheme: brandingThemeAPI, + }, + } + + _, err := fetcher.FetchData(context.Background()) + assert.EqualError(t, err, "failed to get default theme") + }) +} + func Test_phoneProviderResourceFetcher_FetchData(t *testing.T) { t.Run("it successfully retrieves twilio's phone providers data", func(t *testing.T) { ctrl := gomock.NewController(t) From 906f236b1584723bf21f710f42320fe22fab88ad Mon Sep 17 00:00:00 2001 From: ramya18101 Date: Sat, 18 Oct 2025 10:59:25 +0530 Subject: [PATCH 2/2] enhance branding theme resource fetcher in tf generation --- internal/cli/terraform.go | 2 +- internal/cli/terraform_fetcher.go | 9 ++++++--- internal/cli/terraform_fetcher_test.go | 25 ++++++++++++++++++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/internal/cli/terraform.go b/internal/cli/terraform.go index f24fa745f..c0f62e8b1 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -74,7 +74,7 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataF case "auth0_branding": fetchers = append(fetchers, &brandingResourceFetcher{}) case "auth0_branding_theme": - fetchers = append(fetchers, &brandingThemeResourceFetcher{}) + fetchers = append(fetchers, &brandingThemeResourceFetcher{api}) case "auth0_phone_provider": fetchers = append(fetchers, &phoneProviderResourceFetcher{api}) case "auth0_client", "auth0_client_credentials": diff --git a/internal/cli/terraform_fetcher.go b/internal/cli/terraform_fetcher.go index 8b7f48456..cc84f601f 100644 --- a/internal/cli/terraform_fetcher.go +++ b/internal/cli/terraform_fetcher.go @@ -143,16 +143,19 @@ func (f *brandingResourceFetcher) FetchData(_ context.Context) (importDataList, }, }, nil } -func (f *brandingThemeResourceFetcher) FetchData(_ context.Context) (importDataList, error) { +func (f *brandingThemeResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { var data importDataList - theme, err := f.api.BrandingTheme.Default(context.Background()) + theme, err := f.api.BrandingTheme.Default(ctx) if err != nil { + if mErr, ok := err.(management.Error); ok && mErr.Status() == http.StatusNotFound { + return nil, nil + } return nil, err } data = append(data, importDataItem{ - ResourceName: "auth0_branding_theme." + sanitizeResourceName(theme.GetDisplayName()), + ResourceName: "auth0_branding_theme.default", ImportID: theme.GetID(), }) diff --git a/internal/cli/terraform_fetcher_test.go b/internal/cli/terraform_fetcher_test.go index 0a43daaff..de38ca499 100644 --- a/internal/cli/terraform_fetcher_test.go +++ b/internal/cli/terraform_fetcher_test.go @@ -149,8 +149,7 @@ func TestBrandingThemeResourceFetcher_FetchData(t *testing.T) { brandingThemeAPI.EXPECT(). Default(gomock.Any()). Return(&management.BrandingTheme{ - ID: auth0.String("theme_123"), - DisplayName: auth0.String("My Theme"), + ID: auth0.String("theme_123"), }, nil) fetcher := brandingThemeResourceFetcher{ @@ -161,7 +160,7 @@ func TestBrandingThemeResourceFetcher_FetchData(t *testing.T) { expectedData := importDataList{ { - ResourceName: "auth0_branding_theme.my_theme", + ResourceName: "auth0_branding_theme.default", ImportID: "theme_123", }, } @@ -189,6 +188,26 @@ func TestBrandingThemeResourceFetcher_FetchData(t *testing.T) { _, err := fetcher.FetchData(context.Background()) assert.EqualError(t, err, "failed to get default theme") }) + + t.Run("it returns nil data if branding theme is not found", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mErr := mockManagamentError{status: http.StatusNotFound} + brandingThemeAPI := mock.NewMockBrandingThemeAPI(ctrl) + brandingThemeAPI.EXPECT(). + Default(gomock.Any()). + Return(nil, mErr) + + fetcher := brandingThemeResourceFetcher{ + api: &auth0.API{ + BrandingTheme: brandingThemeAPI, + }, + } + + _, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + }) } func Test_phoneProviderResourceFetcher_FetchData(t *testing.T) {