Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/auth0_terraform_generate.md
Original file line number Diff line number Diff line change
Expand Up @@ -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])
-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])
-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")
```

Expand Down
1 change: 1 addition & 0 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ var RequiredScopes = []string{
"create:users", "delete:users", "read:users", "update:users",
"read:branding", "update:branding",
"create:phone_providers", "read:phone_providers", "update:phone_providers", "delete:phone_providers",
"read:phone_templates",
"create:email_templates", "read:email_templates", "update:email_templates",
"create:email_provider", "read:email_provider", "update:email_provider", "delete:email_provider",
"read:flows", "read:forms", "read:flows_vault_connections",
Expand Down
2 changes: 2 additions & 0 deletions internal/auth0/auth0.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ func NewAPI(m *management.Management) *API {

type APIV2 struct {
AttackProtectionBotDetection AttackProtectionBotDetectionAPIV2
PhoneNotificationTemplate PhoneNotificationTemplateAPI
}

func NewAPIV2(m *managementv2.Management) *APIV2 {
return &APIV2{
AttackProtectionBotDetection: m.AttackProtection.BotDetection,
PhoneNotificationTemplate: m.Branding.Phone.Templates,
}
}

Expand Down
57 changes: 57 additions & 0 deletions internal/auth0/mock/phone_notification_template_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions internal/auth0/phone_notification_template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:generate mockgen -source=phone_notification_template.go -destination=mock/phone_notification_template_mock.go -package=mock

package auth0

import (
"context"

managementv2 "github.com/auth0/go-auth0/v2/management"
"github.com/auth0/go-auth0/v2/management/option"
)

type PhoneNotificationTemplateAPI interface {
List(ctx context.Context, request *managementv2.ListPhoneTemplatesRequestParameters, opts ...option.RequestOption) (*managementv2.ListPhoneTemplatesResponseContent, error)
}
6 changes: 4 additions & 2 deletions internal/cli/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type (
}
)

func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataFetcher, error) {
func (i *terraformInputs) parseResourceFetchers(api *auth0.API, apiv2 *auth0.APIV2) ([]resourceDataFetcher, error) {
fetchers := make([]resourceDataFetcher, 0)
var err error

Expand All @@ -77,6 +77,8 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataF
fetchers = append(fetchers, &brandingThemeResourceFetcher{api})
case "auth0_phone_provider":
fetchers = append(fetchers, &phoneProviderResourceFetcher{api})
case "auth0_phone_notification_template":
fetchers = append(fetchers, &phoneNotificationTemplateResourceFetcher{apiv2})
case "auth0_client", "auth0_client_credentials":
fetchers = append(fetchers, &clientResourceFetcher{api})
case "auth0_client_grant":
Expand Down Expand Up @@ -177,7 +179,7 @@ func generateTerraformCmd(cli *cli) *cobra.Command {

func generateTerraformCmdRun(cli *cli, inputs *terraformInputs) func(cmd *cobra.Command, args []string) error {
return func(cmd *cobra.Command, args []string) error {
resources, err := inputs.parseResourceFetchers(cli.api)
resources, err := inputs.parseResourceFetchers(cli.api, cli.apiv2)
if err != nil {
return err
}
Expand Down
32 changes: 31 additions & 1 deletion internal/cli/terraform_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ import (
)

var (
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", "auth0_prompt_screen_partial"}
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", "auth0_prompt_screen_partial",
"auth0_phone_notification_template",
}
)

type (
Expand Down Expand Up @@ -126,6 +133,10 @@ type (
userAttributeProfilesResourceFetcher struct {
api *auth0.API
}

phoneNotificationTemplateResourceFetcher struct {
apiv2 *auth0.APIV2
}
)

func (f *attackProtectionResourceFetcher) FetchData(_ context.Context) (importDataList, error) {
Expand Down Expand Up @@ -186,6 +197,25 @@ func (f *phoneProviderResourceFetcher) FetchData(ctx context.Context) (importDat
return data, nil
}

func (f *phoneNotificationTemplateResourceFetcher) FetchData(ctx context.Context) (importDataList, error) {
phoneNotificationTemplateList, err := f.apiv2.PhoneNotificationTemplate.List(ctx, nil)
if err != nil {
return nil, err
}

var data importDataList
for _, template := range phoneNotificationTemplateList.GetTemplates() {
if id := template.GetID(); id != "" {
data = append(data, importDataItem{
ResourceName: "auth0_phone_notification_template." + sanitizeResourceName(string(template.GetType())),
ImportID: id,
})
}
}

return data, nil
}

func (f *clientResourceFetcher) FetchData(ctx context.Context) (importDataList, error) {
var data importDataList

Expand Down
92 changes: 92 additions & 0 deletions internal/cli/terraform_fetcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"testing"

"github.com/auth0/go-auth0/management"
managementv2 "github.com/auth0/go-auth0/v2/management"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -305,6 +306,97 @@ func Test_phoneProviderResourceFetcher_FetchData(t *testing.T) {
})
}

func Test_phoneNotificationTemplateResourceFetcher_FetchData(t *testing.T) {
t.Run("it successfully retrieves phone notification templates data", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

phoneNotificationTemplateAPI := mock.NewMockPhoneNotificationTemplateAPI(ctrl)
phoneNotificationTemplateAPI.EXPECT().
List(gomock.Any(), gomock.Any(), gomock.Any()).
Return(
&managementv2.ListPhoneTemplatesResponseContent{
Templates: []*managementv2.PhoneTemplate{
{
ID: "pnt_abc123",
Type: managementv2.PhoneTemplateNotificationTypeEnumOtpVerify,
},
{
ID: "pnt_def456",
Type: managementv2.PhoneTemplateNotificationTypeEnumOtpEnroll,
},
},
},
nil,
)

fetcher := phoneNotificationTemplateResourceFetcher{
apiv2: &auth0.APIV2{
PhoneNotificationTemplate: phoneNotificationTemplateAPI,
},
}

expectedData := importDataList{
{
ResourceName: "auth0_phone_notification_template.otp_verify",
ImportID: "pnt_abc123",
},
{
ResourceName: "auth0_phone_notification_template.otp_enroll",
ImportID: "pnt_def456",
},
}

data, err := fetcher.FetchData(context.Background())
assert.NoError(t, err)
assert.Equal(t, expectedData, data)
})

t.Run("it returns nil when no templates exist", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

phoneNotificationTemplateAPI := mock.NewMockPhoneNotificationTemplateAPI(ctrl)
phoneNotificationTemplateAPI.EXPECT().
List(gomock.Any(), gomock.Any(), gomock.Any()).
Return(
&managementv2.ListPhoneTemplatesResponseContent{
Templates: []*managementv2.PhoneTemplate{},
},
nil,
)

fetcher := phoneNotificationTemplateResourceFetcher{
apiv2: &auth0.APIV2{
PhoneNotificationTemplate: phoneNotificationTemplateAPI,
},
}

data, err := fetcher.FetchData(context.Background())
assert.NoError(t, err)
assert.Nil(t, data)
})

t.Run("it returns an error if api call fails", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

phoneNotificationTemplateAPI := mock.NewMockPhoneNotificationTemplateAPI(ctrl)
phoneNotificationTemplateAPI.EXPECT().
List(gomock.Any(), gomock.Any(), gomock.Any()).
Return(nil, fmt.Errorf("failed to list phone notification templates"))

fetcher := phoneNotificationTemplateResourceFetcher{
apiv2: &auth0.APIV2{
PhoneNotificationTemplate: phoneNotificationTemplateAPI,
},
}

_, err := fetcher.FetchData(context.Background())
assert.EqualError(t, err, "failed to list phone notification templates")
})
}

func TestClientResourceFetcher_FetchData(t *testing.T) {
t.Run("it successfully retrieves client data", func(t *testing.T) {
ctrl := gomock.NewController(t)
Expand Down
12 changes: 11 additions & 1 deletion internal/cli/terraform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ func TestCleanOutputDirectory(t *testing.T) {

func TestTerraformInputs_ParseResourceFetchers(t *testing.T) {
api := &auth0.API{}
apiv2 := &auth0.APIV2{}

var testCases = []struct {
name string
Expand All @@ -478,6 +479,15 @@ func TestTerraformInputs_ParseResourceFetchers(t *testing.T) {
&clientResourceFetcher{api},
},
},
{
name: "it can successfully parse resources: auth0_phone_notification_template",
input: terraformInputs{
Resources: []string{"auth0_phone_notification_template"},
},
expectedDataFetchers: []resourceDataFetcher{
&phoneNotificationTemplateResourceFetcher{apiv2},
},
},
{
name: "it can successfully parse resources: auth0_client, auth0_connection",
input: terraformInputs{
Expand Down Expand Up @@ -513,7 +523,7 @@ func TestTerraformInputs_ParseResourceFetchers(t *testing.T) {

for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
actual, err := testCase.input.parseResourceFetchers(api)
actual, err := testCase.input.parseResourceFetchers(api, apiv2)

if testCase.expectedError != "" {
assert.EqualError(t, err, testCase.expectedError)
Expand Down
Loading