diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml index c377ca73..0687eedf 100644 --- a/.github/workflows/golangci-lint.yaml +++ b/.github/workflows/golangci-lint.yaml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: "1.20" + go-version: "1.21.11" cache: false - name: golangci-lint uses: golangci/golangci-lint-action@v3 @@ -26,7 +26,7 @@ jobs: # Require: The version of golangci-lint to use. # When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version. # When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit. - version: v1.53 + version: v1.59.1 # Optional: working directory, useful for monorepos # working-directory: somedir diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5e0c62d3..b8720dd4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-go@v4 with: - go-version: "1.20.6" + go-version: "1.21.11" - run: go mod download - run: go test -v -cover ./provider/ env: diff --git a/.gitignore b/.gitignore index b8690d3e..a9c0d1b5 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ website/vendor # Keep windows files with windows line endings *.winfile eol=crlf + +#local +local \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index b97f5c3d..4982c930 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -25,4 +25,4 @@ linters: - unconvert - unparam - unused - - vet + - govet diff --git a/GNUmakefile b/GNUmakefile index 247f579f..c8c60528 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -3,8 +3,13 @@ PLATFORM ?= $(shell go env GOOS)_$(shell go env GOARCH) default: testacc install: - go build -o ~/.terraform.d/plugins/registry.terraform.io/frontegg/frontegg/1.0.0/$(PLATFORM)/terraform-provider-frontegg + @go build -o ~/.terraform.d/plugins/registry.terraform.io/frontegg/frontegg/1.0.0/$(PLATFORM)/terraform-provider-frontegg + @rm .terraform.lock.hcl .PHONY: testacc testacc: - TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m + @TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m + +capply: install + @terraform init + @terraform apply diff --git a/docs/data-sources/permission.md b/docs/data-sources/permission.md index 000d7688..f269677a 100644 --- a/docs/data-sources/permission.md +++ b/docs/data-sources/permission.md @@ -36,5 +36,3 @@ output "permission_id" { - `description` (String) A human-readable description of the permission. - `id` (String) The ID of this resource. - `name` (String) A human-readable name for the permission. - - diff --git a/docs/guides/v1-migration.md b/docs/guides/v1-migration.md index 2955147c..0dd358e4 100644 --- a/docs/guides/v1-migration.md +++ b/docs/guides/v1-migration.md @@ -1,3 +1,4 @@ + --- page_title: "frontegg_migration-v0 Migration - V0 to V1 migration" subcategory: "" @@ -10,12 +11,10 @@ description: |- This guide will help you migrate from Frontegg's V0 to V1. > **This migration guide applies exclusively to users who have configured a custom domain with the provider.** - ## Provider Configuration > [!IMPORTANT] > If you update your provider without proceeding with following guide, you'll get an error when running `terraform apply`. - ### Custom Domains We've made a significant update to the provider configuration, introducing the `custom_domains` field to replace the previous `custom_domain` field. The `custom_domains` field now accepts a list of strings, allowing you to configure multiple custom domains for the Frontegg application. @@ -38,4 +37,4 @@ custom_domains = [ ] ``` -[Frontegg]: https://frontegg.com +[Frontegg]: https://frontegg.com \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 7fdf0abe..f9c71aff 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,9 +31,8 @@ provided the configuration will be cross-environments. ```terraform provider "frontegg" { - client_id = "[your-personal-token-client-id]" - secret_key = "[your-personal-token-api-key]" - + client_id = "[your-personal-token-client-id]" + secret_key = "[your-personal-token-api-key]" environment_id = "[your-environment-id]" api_base_url = "https://api.frontegg.com" diff --git a/docs/resources/allowed_origin.md b/docs/resources/allowed_origin.md index 118c7175..a88f1698 100644 --- a/docs/resources/allowed_origin.md +++ b/docs/resources/allowed_origin.md @@ -22,5 +22,3 @@ Configures a Frontegg allowed origin. ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/email_provider.md b/docs/resources/email_provider.md new file mode 100644 index 00000000..26c8b2e6 --- /dev/null +++ b/docs/resources/email_provider.md @@ -0,0 +1,33 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "frontegg_email_provider Resource - terraform-provider-frontegg" +subcategory: "" +description: |- + Configures a Frontegg Email provider. +--- + +# frontegg_email_provider (Resource) + +Configures a Frontegg Email provider. + + + + +## Schema + +### Required + +- `provider_name` (String) Name of the email provider (If the provider is changed, the old provider's configuration will be deleted). +- `secret` (String) A secret to be included with the event. + +### Optional + +- `domain` (String) Required for Mailgun (required only for Mailgun). +- `provider_id` (String) Provider ID (required only for AWS SES). +- `region` (String) Required for AWS SES or Mailgun. + +### Read-Only + +- `created_at` (String) The timestamp at which the permission was created. +- `id` (String) The ID of this resource. +- `updated_at` (String) The timestamp at which the permission was updated. diff --git a/docs/resources/permission.md b/docs/resources/permission.md index 2e7ba9e2..fcaccca3 100644 --- a/docs/resources/permission.md +++ b/docs/resources/permission.md @@ -32,5 +32,3 @@ data "frontegg_permission" "read_users" { - `created_at` (String) The timestamp at which the permission was created. - `id` (String) The ID of this resource. - - diff --git a/docs/resources/permission_category.md b/docs/resources/permission_category.md index 68cda8ff..83ba5e77 100644 --- a/docs/resources/permission_category.md +++ b/docs/resources/permission_category.md @@ -31,5 +31,3 @@ resource "frontegg_permission_category" "example" { - `created_at` (String) The timestamp at which the permission category was created. - `id` (String) The ID of this resource. - - diff --git a/docs/resources/redirect_uri.md b/docs/resources/redirect_uri.md index f4e437db..796c4b44 100644 --- a/docs/resources/redirect_uri.md +++ b/docs/resources/redirect_uri.md @@ -23,5 +23,3 @@ Configures a Frontegg Redirect URI. - `id` (String) The ID of this resource. - `key` (String) The redirect URI key. - - diff --git a/docs/resources/role.md b/docs/resources/role.md index f011a7de..8be92446 100644 --- a/docs/resources/role.md +++ b/docs/resources/role.md @@ -48,5 +48,3 @@ resource "frontegg_role" "example" { - `created_at` (String) The timestamp at which the role was created. - `id` (String) The ID of this resource. - `vendor_id` (String) The ID of the vendor that owns the role. - - diff --git a/docs/resources/tenant.md b/docs/resources/tenant.md index 831d6e3d..ad493601 100644 --- a/docs/resources/tenant.md +++ b/docs/resources/tenant.md @@ -28,5 +28,3 @@ Configures a Frontegg tenant. ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/user.md b/docs/resources/user.md index f86716b3..502ac182 100644 --- a/docs/resources/user.md +++ b/docs/resources/user.md @@ -31,5 +31,3 @@ Configures a Frontegg user. ### Read-Only - `id` (String) The ID of this resource. - - diff --git a/docs/resources/webhook.md b/docs/resources/webhook.md index 8a507762..b39ab34f 100644 --- a/docs/resources/webhook.md +++ b/docs/resources/webhook.md @@ -46,5 +46,3 @@ resource "frontegg_webhook" "example" { - `id` (String) The ID of this resource. - `type` (String) The type of the webhook. - `vendor_id` (String) The ID of the vendor that owns the webhook. - - diff --git a/docs/resources/workspace.md b/docs/resources/workspace.md index 7c3fce2f..e2eee6e6 100644 --- a/docs/resources/workspace.md +++ b/docs/resources/workspace.md @@ -142,6 +142,8 @@ resource "frontegg_workspace" "example" { enable_usage = false enable_users = false enable_webhooks = false + enable_groups = false + enable_provisioning = false palette { error { @@ -190,7 +192,6 @@ resource "frontegg_workspace" "example" { ``` - ## Schema ### Required @@ -198,15 +199,13 @@ resource "frontegg_workspace" "example" { - `admin_portal` (Block List, Min: 1, Max: 1) Configures the admin portal. (see [below for nested schema](#nestedblock--admin_portal)) - `allowed_origins` (Set of String) The origins that are allowed to access the workspace. - This parameter controls the value of the "Origin" header for API responses. - + This parameter controls the value of the "Origin" header for API responses. - `auth_policy` (Block List, Min: 1, Max: 1) Configures the general authentication policy. (see [below for nested schema](#nestedblock--auth_policy)) - `backend_stack` (String) The backend stack of the application associated with the workspace. - `country` (String) The country associated with the workspace. - `frontegg_domain` (String) The domain at which the Frontegg API is served for this workspace. - The domain must end with ".frontegg.com" or ".us.frontegg.com". - + The domain must end with ".frontegg.com" or ".us.frontegg.com". - `frontend_stack` (String) The frontend stack of the application associated with the worksapce. - `mfa_policy` (Block List, Min: 1, Max: 1) Configures the multi-factor authentication (MFA) policy. (see [below for nested schema](#nestedblock--mfa_policy)) - `name` (String) The name of the workspace. diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf index e9f6b19e..c477e393 100644 --- a/examples/provider/provider.tf +++ b/examples/provider/provider.tf @@ -1,8 +1,8 @@ provider "frontegg" { - client_id = "e295e71d-40b3-4178-b0de-f7a1f3818ea4" - secret_key = "29c55559-6968-4d60-8f4e-40ebeec5a459" - environment_id = "eee00841-99fd-4914-bc76-29b38b2e36e8" + client_id = "[your-personal-token-client-id]" + secret_key = "[your-personal-token-api-key]" + environment_id = "[your-environment-id]" api_base_url = "https://api.frontegg.com" portal_base_url = "https://frontegg-portal.frontegg.com" -} +} \ No newline at end of file diff --git a/go.mod b/go.mod index 4a545d60..019cf546 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/frontegg/terraform-provider-frontegg -go 1.20 +go 1.21 require ( github.com/hashicorp/terraform-plugin-docs v0.16.0 @@ -60,8 +60,8 @@ require ( github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.14.1 // indirect golang.org/x/crypto v0.17.0 // indirect - golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.18.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/go.sum b/go.sum index e09d3454..aa0ce32a 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,5 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= @@ -7,6 +8,7 @@ github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFP github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= @@ -20,24 +22,33 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= +github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -104,14 +115,20 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= @@ -139,19 +156,23 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= @@ -170,6 +191,7 @@ github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21 github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= @@ -181,12 +203,12 @@ golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2Uz golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= -golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -200,6 +222,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -237,7 +261,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -255,6 +280,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/provider/provider.go b/provider/provider.go index 607a1de0..0f6f1907 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -63,6 +63,7 @@ func New(version string) func() *schema.Provider { "frontegg_user": resourceFronteggUser(), "frontegg_redirect_uri": resourceFronteggRedirectUri(), "frontegg_allowed_origin": resourceFronteggAllowedOrigin(), + "frontegg_email_provider": resourceFronteggEmailProvider(), }, ConfigureContextFunc: func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { environmentId := d.Get("environment_id").(string) diff --git a/provider/resource_frontegg_email_providers.go b/provider/resource_frontegg_email_providers.go new file mode 100644 index 00000000..f92a2325 --- /dev/null +++ b/provider/resource_frontegg_email_providers.go @@ -0,0 +1,185 @@ +package provider + +import ( + "context" + "fmt" + + "github.com/frontegg/terraform-provider-frontegg/internal/restclient" + "github.com/frontegg/terraform-provider-frontegg/provider/validators" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + fronteggEmailPorivderPath = "/identity/resources/mail/v2/configurations" + fronteggEmailPorivderPathV1 = "/identity/resources/mail/v1/configurations" +) + +type fronteggEmailProviderPayload struct { + Id string `json:"id,omitempty"` + Region string `json:"region,omitempty"` + Domain string `json:"domain,omitempty"` + Secret string `json:"secret,omitempty"` + Provider string `json:"provider,omitempty"` +} + +type fronteggEmailProvider struct { + Payload fronteggEmailProviderPayload `json:"payload,omitempty"` +} + +type Extension struct { + ExtensionName string `json:"extensionName,omitempty"` + ExtensionValue string `json:"extensionValue,omitempty"` +} + +type fronteggEmailProviderResponse struct { + Secret string `json:"secret,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + UpdatedAt string `json:"updatedAt,omitempty"` + Extension []Extension `json:"extension,omitempty"` +} + +func resourceFronteggEmailProvider() *schema.Resource { + return &schema.Resource{ + Description: `Configures a Frontegg Email provider.`, + + CreateContext: resourceFronteggEmailProviderCreate, + ReadContext: resourceFronteggEmailProviderRead, + UpdateContext: resourceFronteggEmailProviderUpdate, + DeleteContext: resourceFronteggEmailProviderDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + + Schema: map[string]*schema.Schema{ + "provider_id": { + Description: "Provider ID (required only for AWS SES).", + Type: schema.TypeString, + Optional: true, + }, + "region": { + Description: "Required for AWS SES or Mailgun.", + Type: schema.TypeString, + Optional: true, + }, + "domain": { + Description: "Required for Mailgun (required only for Mailgun).", + Type: schema.TypeString, + Optional: true, + }, + "secret": { + Description: "A secret to be included with the event.", + Type: schema.TypeString, + Required: true, + }, + "provider_name": { + Description: "Name of the email provider (If the provider is changed, the old provider's configuration will be deleted).", + Type: schema.TypeString, + Required: true, + ValidateFunc: validators.ValidateProvider, + }, + "created_at": { + Description: "The timestamp at which the permission was created.", + Type: schema.TypeString, + Computed: true, + }, + "updated_at": { + Description: "The timestamp at which the permission was updated.", + Type: schema.TypeString, + Computed: true, + }, + }, + CustomizeDiff: validators.ValidateRequiredFields, + } + +} + +func resourceFronteggEmailProviderSerialize(d *schema.ResourceData) fronteggEmailProvider { + return fronteggEmailProvider{ + Payload: fronteggEmailProviderPayload{ + Secret: d.Get("secret").(string), + Provider: d.Get("provider_name").(string), + Id: d.Get("provider_id").(string), + Region: d.Get("region").(string), + Domain: d.Get("domain").(string), + }, + } +} + +func resourceFronteggEmailProviderDeserialize(d *schema.ResourceData, f *fronteggEmailProviderResponse) error { + + if err := d.Set("provider_name", d.Id()); err != nil { + return err + } + + fields := map[string]string{ + "secret": f.Secret, + "updated_at": f.UpdatedAt, + "created_at": f.CreatedAt, + } + + for key, value := range fields { + if err := d.Set(key, value); err != nil { + return fmt.Errorf("error setting %s: %s", key, err) + } + } + + return nil +} + +func resourceFronteggEmailProviderCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + clientHolder := meta.(*restclient.ClientHolder) + in := resourceFronteggEmailProviderSerialize(d) + provider := d.Get("provider_name").(string) + d.SetId(provider) + if err := clientHolder.ApiClient.Post(ctx, fronteggEmailPorivderPath, in, nil); err != nil { + return diag.FromErr(err) + } + return nil +} + +func resourceFronteggEmailProviderRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + clientHolder := meta.(*restclient.ClientHolder) + + var out fronteggEmailProviderResponse + if err := clientHolder.ApiClient.Get(ctx, fronteggEmailPorivderPathV1, &out); err != nil { + return diag.FromErr(err) + } + if err := resourceFronteggEmailProviderDeserialize(d, &out); err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceFronteggEmailProviderUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + clientHolder := meta.(*restclient.ClientHolder) + in := resourceFronteggEmailProviderSerialize(d) + providerName := "provider_name" + + provider := d.Get(providerName).(string) + d.SetId(provider) + + if d.HasChange(providerName) { + err := clientHolder.ApiClient.Delete(ctx, fronteggEmailPorivderPathV1, nil) + if err != nil { + return diag.FromErr(err) + } + } + + if err := clientHolder.ApiClient.Post(ctx, fronteggEmailPorivderPath, in, nil); err != nil { + return diag.FromErr(err) + } + + return nil +} + +func resourceFronteggEmailProviderDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + clientHolder := meta.(*restclient.ClientHolder) + err := clientHolder.ApiClient.Delete(ctx, fronteggEmailPorivderPathV1, nil) + if err != nil { + return diag.FromErr(err) + } + + return nil +} diff --git a/provider/resource_frontegg_workspace.go b/provider/resource_frontegg_workspace.go index 9583ca71..866ed123 100644 --- a/provider/resource_frontegg_workspace.go +++ b/provider/resource_frontegg_workspace.go @@ -2016,7 +2016,7 @@ func resourceFronteggWorkspaceUpdate(ctx context.Context, d *schema.ResourceData adminPortal = out.Rows[0] configuration = &adminPortal.Configuration default: - return diag.FromErr(fmt.Errorf("Too many admin portals!")) + return diag.FromErr(fmt.Errorf("too many admin portals")) } configuration.Navigation.Account = serializeVisibility("admin_portal.0.enable_account_settings") diff --git a/provider/validators/validator_email_providers.go b/provider/validators/validator_email_providers.go new file mode 100644 index 00000000..b5f9874a --- /dev/null +++ b/provider/validators/validator_email_providers.go @@ -0,0 +1,59 @@ +package validators + +import ( + "context" + "fmt" + "slices" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +const ( + Mailgun = "mailgun" + SES = "ses" + Sendgrid = "sendgrid" + SES_ROLE = "ses-role" +) + +func ValidateProvider(val interface{}, key string) (warns []string, errs []error) { + v := val.(string) + ps := []string{Mailgun, SES, Sendgrid, SES_ROLE} + + contain := slices.Contains(ps, v) + + if !contain { + errs = append(errs, fmt.Errorf("%q must be either %v ,got: %s", key, strings.Join(ps, ", "), v)) + } + return warns, errs +} + +func ValidateRequiredFields(ctx context.Context, rd *schema.ResourceDiff, i interface{}) error { + + provider := rd.Get("provider_name").(string) + + requiredFieldError := func(field, provider string) error { + return fmt.Errorf("%s is required when provider is '%s'", field, provider) + } + + if provider == SES { + if region, ok := rd.GetOk("region"); !ok || region.(string) == "" { + return requiredFieldError("region", SES) + } + + if id, ok := rd.GetOk("provider_id"); !ok || id.(string) == "" { + return requiredFieldError("provider_id", SES) + } + } + + if provider == Mailgun { + if domain, ok := rd.GetOk("domain"); !ok || domain.(string) == "" { + return requiredFieldError("domain", Mailgun) + } + if region, ok := rd.GetOk("region"); !ok || region.(string) == "" { + return requiredFieldError("region", Mailgun) + } + } + + return nil +}