diff --git a/docs/auth0_terraform_generate.md b/docs/auth0_terraform_generate.md index f75e676b..02a4232a 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_client,auth0_client_grant,auth0_connection,auth0_custom_domain,auth0_email_provider,auth0_email_template,auth0_guardian,auth0_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_resource_server,auth0_role,auth0_tenant,auth0_trigger_actions]) + -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_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_organization,auth0_pages,auth0_prompt,auth0_prompt_custom_text,auth0_resource_server,auth0_role,auth0_tenant,auth0_trigger_actions]) ``` diff --git a/internal/auth0/auth0.go b/internal/auth0/auth0.go index 737e6a90..1e822761 100644 --- a/internal/auth0/auth0.go +++ b/internal/auth0/auth0.go @@ -8,55 +8,61 @@ import ( // API mimics `management.Management`s general interface, except it refers to // the interfaces instead of the concrete structs. type API struct { - Action ActionAPI - Anomaly AnomalyAPI - AttackProtection AttackProtectionAPI - Branding BrandingAPI - BrandingTheme BrandingThemeAPI - Client ClientAPI - ClientGrant ClientGrantAPI - Connection ConnectionAPI - CustomDomain CustomDomainAPI - EmailTemplate EmailTemplateAPI - EmailProvider EmailProviderAPI - Log LogAPI - LogStream LogStreamAPI - Organization OrganizationAPI - Prompt PromptAPI - ResourceServer ResourceServerAPI - Role RoleAPI - Rule RuleAPI - Tenant TenantAPI - User UserAPI - Jobs JobsAPI + Action ActionAPI + Anomaly AnomalyAPI + AttackProtection AttackProtectionAPI + Branding BrandingAPI + BrandingTheme BrandingThemeAPI + Client ClientAPI + ClientGrant ClientGrantAPI + Connection ConnectionAPI + CustomDomain CustomDomainAPI + EmailTemplate EmailTemplateAPI + EmailProvider EmailProviderAPI + Flow FlowAPI + FlowVaultConnection FlowVaultConnectionAPI + Form FormAPI + Log LogAPI + LogStream LogStreamAPI + Organization OrganizationAPI + Prompt PromptAPI + ResourceServer ResourceServerAPI + Role RoleAPI + Rule RuleAPI + Tenant TenantAPI + User UserAPI + Jobs JobsAPI HTTPClient HTTPClientAPI } func NewAPI(m *management.Management) *API { return &API{ - Action: m.Action, - Anomaly: m.Anomaly, - AttackProtection: m.AttackProtection, - Branding: m.Branding, - BrandingTheme: m.BrandingTheme, - Client: m.Client, - ClientGrant: m.ClientGrant, - Connection: m.Connection, - CustomDomain: m.CustomDomain, - EmailTemplate: m.EmailTemplate, - EmailProvider: m.EmailProvider, - Log: m.Log, - LogStream: m.LogStream, - Organization: m.Organization, - Prompt: m.Prompt, - ResourceServer: m.ResourceServer, - Role: m.Role, - Rule: m.Rule, - Tenant: m.Tenant, - User: m.User, - Jobs: m.Job, - HTTPClient: m, + Action: m.Action, + Anomaly: m.Anomaly, + AttackProtection: m.AttackProtection, + Branding: m.Branding, + BrandingTheme: m.BrandingTheme, + Client: m.Client, + ClientGrant: m.ClientGrant, + Connection: m.Connection, + CustomDomain: m.CustomDomain, + EmailTemplate: m.EmailTemplate, + EmailProvider: m.EmailProvider, + Flow: m.Flow, + FlowVaultConnection: m.Flow.Vault, + Form: m.Form, + Log: m.Log, + LogStream: m.LogStream, + Organization: m.Organization, + Prompt: m.Prompt, + ResourceServer: m.ResourceServer, + Role: m.Role, + Rule: m.Rule, + Tenant: m.Tenant, + User: m.User, + Jobs: m.Job, + HTTPClient: m, } } diff --git a/internal/auth0/flow.go b/internal/auth0/flow.go new file mode 100644 index 00000000..ead68348 --- /dev/null +++ b/internal/auth0/flow.go @@ -0,0 +1,43 @@ +//go:generate mockgen -source=flow.go -destination=mock/flow_mock.go -package=mock + +package auth0 + +import ( + "context" + + "github.com/auth0/go-auth0/management" +) + +type FlowAPI interface { + // Create a new flow. + Create(ctx context.Context, r *management.Flow, opts ...management.RequestOption) error + + // Read flow details. + Read(ctx context.Context, id string, opts ...management.RequestOption) (r *management.Flow, err error) + + // Update an existing flow. + Update(ctx context.Context, id string, r *management.Flow, opts ...management.RequestOption) error + + // Delete a flow. + Delete(ctx context.Context, id string, opts ...management.RequestOption) error + + // List flow. + List(ctx context.Context, opts ...management.RequestOption) (r *management.FlowList, err error) +} + +type FlowVaultConnectionAPI interface { + // CreateConnection Create a new flow vault connection. + CreateConnection(ctx context.Context, r *management.FlowVaultConnection, opts ...management.RequestOption) error + + // GetConnection Retrieve flow vault connection details. + GetConnection(ctx context.Context, id string, opts ...management.RequestOption) (r *management.FlowVaultConnection, err error) + + // UpdateConnection Update an existing flow vault connection. + UpdateConnection(ctx context.Context, id string, r *management.FlowVaultConnection, opts ...management.RequestOption) error + + // DeleteConnection Delete a flow vault connection. + DeleteConnection(ctx context.Context, id string, opts ...management.RequestOption) error + + // GetConnectionList List flow vault connections. + GetConnectionList(ctx context.Context, opts ...management.RequestOption) (r *management.FlowVaultConnectionList, err error) +} diff --git a/internal/auth0/form.go b/internal/auth0/form.go new file mode 100644 index 00000000..20d562b4 --- /dev/null +++ b/internal/auth0/form.go @@ -0,0 +1,26 @@ +//go:generate mockgen -source=form.go -destination=mock/form_mock.go -package=mock + +package auth0 + +import ( + "context" + + "github.com/auth0/go-auth0/management" +) + +type FormAPI interface { + // Create a new form. + Create(ctx context.Context, r *management.Form, opts ...management.RequestOption) error + + // Read form details. + Read(ctx context.Context, id string, opts ...management.RequestOption) (r *management.Form, err error) + + // Update an existing action. + Update(ctx context.Context, id string, r *management.Form, opts ...management.RequestOption) error + + // Delete an action. + Delete(ctx context.Context, id string, opts ...management.RequestOption) error + + // List form. + List(ctx context.Context, opts ...management.RequestOption) (r *management.FormList, err error) +} diff --git a/internal/auth0/mock/flow_mock.go b/internal/auth0/mock/flow_mock.go new file mode 100644 index 00000000..8a0e7c38 --- /dev/null +++ b/internal/auth0/mock/flow_mock.go @@ -0,0 +1,253 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: flow.go + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + + management "github.com/auth0/go-auth0/management" + gomock "github.com/golang/mock/gomock" +) + +// MockFlowAPI is a mock of FlowAPI interface. +type MockFlowAPI struct { + ctrl *gomock.Controller + recorder *MockFlowAPIMockRecorder +} + +// MockFlowAPIMockRecorder is the mock recorder for MockFlowAPI. +type MockFlowAPIMockRecorder struct { + mock *MockFlowAPI +} + +// NewMockFlowAPI creates a new mock instance. +func NewMockFlowAPI(ctrl *gomock.Controller) *MockFlowAPI { + mock := &MockFlowAPI{ctrl: ctrl} + mock.recorder = &MockFlowAPIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFlowAPI) EXPECT() *MockFlowAPIMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockFlowAPI) Create(ctx context.Context, r *management.Flow, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Create", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockFlowAPIMockRecorder) Create(ctx, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockFlowAPI)(nil).Create), varargs...) +} + +// Delete mocks base method. +func (m *MockFlowAPI) Delete(ctx context.Context, id string, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Delete", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockFlowAPIMockRecorder) Delete(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockFlowAPI)(nil).Delete), varargs...) +} + +// List mocks base method. +func (m *MockFlowAPI) List(ctx context.Context, opts ...management.RequestOption) (*management.FlowList, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) + ret0, _ := ret[0].(*management.FlowList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockFlowAPIMockRecorder) List(ctx interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockFlowAPI)(nil).List), varargs...) +} + +// Read mocks base method. +func (m *MockFlowAPI) Read(ctx context.Context, id string, opts ...management.RequestOption) (*management.Flow, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Read", varargs...) + ret0, _ := ret[0].(*management.Flow) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Read indicates an expected call of Read. +func (mr *MockFlowAPIMockRecorder) Read(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockFlowAPI)(nil).Read), varargs...) +} + +// Update mocks base method. +func (m *MockFlowAPI) Update(ctx context.Context, id string, r *management.Flow, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Update", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Update indicates an expected call of Update. +func (mr *MockFlowAPIMockRecorder) Update(ctx, id, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockFlowAPI)(nil).Update), varargs...) +} + +// MockFlowVaultConnectionAPI is a mock of FlowVaultConnectionAPI interface. +type MockFlowVaultConnectionAPI struct { + ctrl *gomock.Controller + recorder *MockFlowVaultConnectionAPIMockRecorder +} + +// MockFlowVaultConnectionAPIMockRecorder is the mock recorder for MockFlowVaultConnectionAPI. +type MockFlowVaultConnectionAPIMockRecorder struct { + mock *MockFlowVaultConnectionAPI +} + +// NewMockFlowVaultConnectionAPI creates a new mock instance. +func NewMockFlowVaultConnectionAPI(ctrl *gomock.Controller) *MockFlowVaultConnectionAPI { + mock := &MockFlowVaultConnectionAPI{ctrl: ctrl} + mock.recorder = &MockFlowVaultConnectionAPIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFlowVaultConnectionAPI) EXPECT() *MockFlowVaultConnectionAPIMockRecorder { + return m.recorder +} + +// CreateConnection mocks base method. +func (m *MockFlowVaultConnectionAPI) CreateConnection(ctx context.Context, r *management.FlowVaultConnection, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "CreateConnection", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateConnection indicates an expected call of CreateConnection. +func (mr *MockFlowVaultConnectionAPIMockRecorder) CreateConnection(ctx, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateConnection", reflect.TypeOf((*MockFlowVaultConnectionAPI)(nil).CreateConnection), varargs...) +} + +// DeleteConnection mocks base method. +func (m *MockFlowVaultConnectionAPI) DeleteConnection(ctx context.Context, id string, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "DeleteConnection", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteConnection indicates an expected call of DeleteConnection. +func (mr *MockFlowVaultConnectionAPIMockRecorder) DeleteConnection(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteConnection", reflect.TypeOf((*MockFlowVaultConnectionAPI)(nil).DeleteConnection), varargs...) +} + +// GetConnection mocks base method. +func (m *MockFlowVaultConnectionAPI) GetConnection(ctx context.Context, id string, opts ...management.RequestOption) (*management.FlowVaultConnection, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetConnection", varargs...) + ret0, _ := ret[0].(*management.FlowVaultConnection) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetConnection indicates an expected call of GetConnection. +func (mr *MockFlowVaultConnectionAPIMockRecorder) GetConnection(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConnection", reflect.TypeOf((*MockFlowVaultConnectionAPI)(nil).GetConnection), varargs...) +} + +// GetConnectionList mocks base method. +func (m *MockFlowVaultConnectionAPI) GetConnectionList(ctx context.Context, opts ...management.RequestOption) (*management.FlowVaultConnectionList, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetConnectionList", varargs...) + ret0, _ := ret[0].(*management.FlowVaultConnectionList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetConnectionList indicates an expected call of GetConnectionList. +func (mr *MockFlowVaultConnectionAPIMockRecorder) GetConnectionList(ctx interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConnectionList", reflect.TypeOf((*MockFlowVaultConnectionAPI)(nil).GetConnectionList), varargs...) +} + +// UpdateConnection mocks base method. +func (m *MockFlowVaultConnectionAPI) UpdateConnection(ctx context.Context, id string, r *management.FlowVaultConnection, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "UpdateConnection", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateConnection indicates an expected call of UpdateConnection. +func (mr *MockFlowVaultConnectionAPIMockRecorder) UpdateConnection(ctx, id, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateConnection", reflect.TypeOf((*MockFlowVaultConnectionAPI)(nil).UpdateConnection), varargs...) +} diff --git a/internal/auth0/mock/form_mock.go b/internal/auth0/mock/form_mock.go new file mode 100644 index 00000000..73161402 --- /dev/null +++ b/internal/auth0/mock/form_mock.go @@ -0,0 +1,133 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: form.go + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + + management "github.com/auth0/go-auth0/management" + gomock "github.com/golang/mock/gomock" +) + +// MockFormAPI is a mock of FormAPI interface. +type MockFormAPI struct { + ctrl *gomock.Controller + recorder *MockFormAPIMockRecorder +} + +// MockFormAPIMockRecorder is the mock recorder for MockFormAPI. +type MockFormAPIMockRecorder struct { + mock *MockFormAPI +} + +// NewMockFormAPI creates a new mock instance. +func NewMockFormAPI(ctrl *gomock.Controller) *MockFormAPI { + mock := &MockFormAPI{ctrl: ctrl} + mock.recorder = &MockFormAPIMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFormAPI) EXPECT() *MockFormAPIMockRecorder { + return m.recorder +} + +// Create mocks base method. +func (m *MockFormAPI) Create(ctx context.Context, r *management.Form, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Create", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Create indicates an expected call of Create. +func (mr *MockFormAPIMockRecorder) Create(ctx, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Create", reflect.TypeOf((*MockFormAPI)(nil).Create), varargs...) +} + +// Delete mocks base method. +func (m *MockFormAPI) Delete(ctx context.Context, id string, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Delete", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete. +func (mr *MockFormAPIMockRecorder) Delete(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockFormAPI)(nil).Delete), varargs...) +} + +// List mocks base method. +func (m *MockFormAPI) List(ctx context.Context, opts ...management.RequestOption) (*management.FormList, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "List", varargs...) + ret0, _ := ret[0].(*management.FormList) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// List indicates an expected call of List. +func (mr *MockFormAPIMockRecorder) List(ctx interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockFormAPI)(nil).List), varargs...) +} + +// Read mocks base method. +func (m *MockFormAPI) Read(ctx context.Context, id string, opts ...management.RequestOption) (*management.Form, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Read", varargs...) + ret0, _ := ret[0].(*management.Form) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Read indicates an expected call of Read. +func (mr *MockFormAPIMockRecorder) Read(ctx, id interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockFormAPI)(nil).Read), varargs...) +} + +// Update mocks base method. +func (m *MockFormAPI) Update(ctx context.Context, id string, r *management.Form, opts ...management.RequestOption) error { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, id, r} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Update", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Update indicates an expected call of Update. +func (mr *MockFormAPIMockRecorder) Update(ctx, id, r interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, id, r}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockFormAPI)(nil).Update), varargs...) +} diff --git a/internal/cli/terraform.go b/internal/cli/terraform.go index e00c3890..973633b2 100644 --- a/internal/cli/terraform.go +++ b/internal/cli/terraform.go @@ -76,6 +76,12 @@ func (i *terraformInputs) parseResourceFetchers(api *auth0.API) ([]resourceDataF fetchers = append(fetchers, &emailProviderResourceFetcher{api}) case "auth0_email_template": fetchers = append(fetchers, &emailTemplateResourceFetcher{api}) + case "auth0_flow": + fetchers = append(fetchers, &flowResourceFetcher{api}) + case "auth0_flow_vault_connection": + fetchers = append(fetchers, &flowVaultConnectionResourceFetcher{api}) + case "auth0_form": + fetchers = append(fetchers, &formResourceFetcher{api}) case "auth0_guardian": fetchers = append(fetchers, &guardianResourceFetcher{}) case "auth0_log_stream": @@ -273,7 +279,7 @@ func createMainFile(outputDIR string) error { }() fileContent := `terraform { - required_version = "~> 1.5.0" + required_version = ">= 1.5.0" required_providers { auth0 = { source = "auth0/auth0" diff --git a/internal/cli/terraform_fetcher.go b/internal/cli/terraform_fetcher.go index 7ceae958..c908b7b8 100644 --- a/internal/cli/terraform_fetcher.go +++ b/internal/cli/terraform_fetcher.go @@ -11,7 +11,7 @@ import ( "github.com/auth0/auth0-cli/internal/auth0" ) -var defaultResources = []string{"auth0_action", "auth0_attack_protection", "auth0_branding", "auth0_client", "auth0_client_grant", "auth0_connection", "auth0_custom_domain", "auth0_email_provider", "auth0_email_template", "auth0_guardian", "auth0_organization", "auth0_pages", "auth0_prompt", "auth0_prompt_custom_text", "auth0_resource_server", "auth0_role", "auth0_tenant", "auth0_trigger_actions"} +var defaultResources = []string{"auth0_action", "auth0_attack_protection", "auth0_branding", "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_organization", "auth0_pages", "auth0_prompt", "auth0_prompt_custom_text", "auth0_resource_server", "auth0_role", "auth0_tenant", "auth0_trigger_actions"} type ( importDataList []importDataItem @@ -58,6 +58,18 @@ type ( api *auth0.API } + flowResourceFetcher struct { + api *auth0.API + } + + flowVaultConnectionResourceFetcher struct { + api *auth0.API + } + + formResourceFetcher struct { + api *auth0.API + } + guardianResourceFetcher struct{} logStreamResourceFetcher struct { api *auth0.API @@ -272,6 +284,60 @@ func (f *emailTemplateResourceFetcher) FetchData(ctx context.Context) (importDat return data, nil } +func (f *flowResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { + var data importDataList + + flowList, err := f.api.Flow.List(ctx) + if err != nil { + return data, err + } + + for _, flow := range flowList.Flows { + data = append(data, importDataItem{ + ResourceName: "auth0_flow." + sanitizeResourceName(flow.GetName()), + ImportID: flow.GetID(), + }) + } + + return data, nil +} + +func (f *flowVaultConnectionResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { + var data importDataList + + flowVaultConnectionList, err := f.api.FlowVaultConnection.GetConnectionList(ctx) + if err != nil { + return data, err + } + + for _, flowVaultConnection := range flowVaultConnectionList.Connections { + data = append(data, importDataItem{ + ResourceName: "auth0_flow_vault_connection." + sanitizeResourceName(flowVaultConnection.GetName()), + ImportID: flowVaultConnection.GetID(), + }) + } + + return data, nil +} + +func (f *formResourceFetcher) FetchData(ctx context.Context) (importDataList, error) { + var data importDataList + + forms, err := f.api.Form.List(ctx) + if err != nil { + return data, err + } + + for _, form := range forms.Forms { + data = append(data, importDataItem{ + ResourceName: "auth0_form." + sanitizeResourceName(form.GetName()), + ImportID: form.GetID(), + }) + } + + return data, nil +} + func (f *guardianResourceFetcher) FetchData(_ context.Context) (importDataList, error) { return []importDataItem{ { diff --git a/internal/cli/terraform_fetcher_test.go b/internal/cli/terraform_fetcher_test.go index 4466266e..9b6dda9c 100644 --- a/internal/cli/terraform_fetcher_test.go +++ b/internal/cli/terraform_fetcher_test.go @@ -563,6 +563,291 @@ func TestCustomDomainResourceFetcher_FetchData(t *testing.T) { }) } +func TestFormResourceFetcher_FetchData(t *testing.T) { + t.Run("it successfully generates form import data", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + formAPI := mock.NewMockFormAPI(ctrl) + formAPI.EXPECT(). + List(gomock.Any(), gomock.Any()).Return( + &management.FormList{ + List: management.List{ + Start: 0, + Limit: 1, + Total: 2, + }, + Forms: []*management.Form{ + { + ID: auth0.String("form_id1"), + Name: auth0.String("Form 1"), + }, + { + ID: auth0.String("form_id2"), + Name: auth0.String("Form 2"), + }, + }, + }, nil) + + fetcher := formResourceFetcher{ + api: &auth0.API{ + Form: formAPI, + }, + } + + expectedData := importDataList{ + { + ResourceName: "auth0_form.form_1", + ImportID: "form_id1", + }, + { + ResourceName: "auth0_form.form_2", + ImportID: "form_id2", + }, + } + + data, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + assert.Equal(t, expectedData, data) + }) + + t.Run("it successfully returns empty import list", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + formAPI := mock.NewMockFormAPI(ctrl) + formAPI.EXPECT(). + List(gomock.Any(), gomock.Any()).Return( + &management.FormList{ + List: management.List{ + Start: 0, + Limit: 0, + Total: 0, + }, + Forms: []*management.Form{}, + }, nil) + + fetcher := formResourceFetcher{ + api: &auth0.API{ + Form: formAPI, + }, + } + + 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() + + formAPI := mock.NewMockFormAPI(ctrl) + formAPI.EXPECT(). + List(gomock.Any(), gomock.Any()). + Return(nil, fmt.Errorf("failed to read form")) + + fetcher := formResourceFetcher{ + api: &auth0.API{ + Form: formAPI, + }, + } + + _, err := fetcher.FetchData(context.Background()) + assert.EqualError(t, err, "failed to read form") + }) +} + +func TestFlowResourceFetcher_FetchData(t *testing.T) { + t.Run("it successfully generates form import data", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + flowAPI := mock.NewMockFlowAPI(ctrl) + flowAPI.EXPECT(). + List(gomock.Any(), gomock.Any()).Return( + &management.FlowList{ + List: management.List{ + Start: 0, + Limit: 1, + Total: 2, + }, + Flows: []*management.Flow{ + { + ID: auth0.String("flow_id1"), + Name: auth0.String("Flow 1"), + }, + { + ID: auth0.String("flow_id2"), + Name: auth0.String("Flow 2"), + }, + }, + }, nil) + + fetcher := flowResourceFetcher{ + api: &auth0.API{ + Flow: flowAPI, + }, + } + + expectedData := importDataList{ + { + ResourceName: "auth0_flow.flow_1", + ImportID: "flow_id1", + }, + { + ResourceName: "auth0_flow.flow_2", + ImportID: "flow_id2", + }, + } + + data, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + assert.Equal(t, expectedData, data) + }) + + t.Run("it successfully returns empty import list", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + flowAPI := mock.NewMockFlowAPI(ctrl) + flowAPI.EXPECT(). + List(gomock.Any(), gomock.Any()).Return( + &management.FlowList{ + List: management.List{ + Start: 0, + Limit: 0, + Total: 0, + }, + Flows: []*management.Flow{}, + }, nil) + + fetcher := flowResourceFetcher{ + api: &auth0.API{ + Flow: flowAPI, + }, + } + + 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() + + flowAPI := mock.NewMockFlowAPI(ctrl) + flowAPI.EXPECT(). + List(gomock.Any(), gomock.Any()). + Return(nil, fmt.Errorf("failed to read flow")) + + fetcher := flowResourceFetcher{ + api: &auth0.API{ + Flow: flowAPI, + }, + } + + _, err := fetcher.FetchData(context.Background()) + assert.EqualError(t, err, "failed to read flow") + }) +} + +func TestFlowVaultConnectionResourceFetcher_FetchData(t *testing.T) { + t.Run("it successfully generates form import data", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + flowVaultAPI := mock.NewMockFlowVaultConnectionAPI(ctrl) + flowVaultAPI.EXPECT(). + GetConnectionList(gomock.Any()).Return( + &management.FlowVaultConnectionList{ + List: management.List{ + Start: 0, + Limit: 1, + Total: 2, + }, + Connections: []*management.FlowVaultConnection{ + { + ID: auth0.String("flow_vault_connection1"), + Name: auth0.String("Flow Vault Connection 1"), + }, + { + ID: auth0.String("flow_vault_connection2"), + Name: auth0.String("Flow Vault Connection 2"), + }, + }, + }, nil) + + fetcher := flowVaultConnectionResourceFetcher{ + api: &auth0.API{ + FlowVaultConnection: flowVaultAPI, + }, + } + + expectedData := importDataList{ + { + ResourceName: "auth0_flow_vault_connection.flow_vault_connection_1", + ImportID: "flow_vault_connection1", + }, + { + ResourceName: "auth0_flow_vault_connection.flow_vault_connection_2", + ImportID: "flow_vault_connection2", + }, + } + + data, err := fetcher.FetchData(context.Background()) + assert.NoError(t, err) + assert.Equal(t, expectedData, data) + }) + + t.Run("it successfully returns empty import list", func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + flowVaultAPI := mock.NewMockFlowVaultConnectionAPI(ctrl) + flowVaultAPI.EXPECT(). + GetConnectionList(gomock.Any()).Return( + &management.FlowVaultConnectionList{ + List: management.List{ + Start: 0, + Limit: 0, + Total: 0, + }, + Connections: []*management.FlowVaultConnection{}, + }, nil) + + fetcher := flowVaultConnectionResourceFetcher{ + api: &auth0.API{ + FlowVaultConnection: flowVaultAPI, + }, + } + + 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() + + flowVaultConnectionAPI := mock.NewMockFlowVaultConnectionAPI(ctrl) + flowVaultConnectionAPI.EXPECT(). + GetConnectionList(gomock.Any(), gomock.Any()). + Return(nil, fmt.Errorf("failed to read flow connection")) + + fetcher := flowVaultConnectionResourceFetcher{ + api: &auth0.API{ + FlowVaultConnection: flowVaultConnectionAPI, + }, + } + + _, err := fetcher.FetchData(context.Background()) + assert.EqualError(t, err, "failed to read flow connection") + }) +} + func TestGuardianResourceFetcher_FetchData(t *testing.T) { t.Run("it successfully generates pages guardian data", func(t *testing.T) { fetcher := guardianResourceFetcher{} diff --git a/internal/cli/terraform_test.go b/internal/cli/terraform_test.go index c55f37b9..fe499c9f 100644 --- a/internal/cli/terraform_test.go +++ b/internal/cli/terraform_test.go @@ -193,7 +193,7 @@ func assertTerraformMainFileWasGeneratedCorrectly(t *testing.T, outputDIR string assert.NoError(t, err) expectedContent := `terraform { - required_version = "~> 1.5.0" + required_version = ">= 1.5.0" required_providers { auth0 = { source = "auth0/auth0"