From d22b3c52cd55b42e5c05d90d3913a5f5a7bc5878 Mon Sep 17 00:00:00 2001 From: Nautik Date: Thu, 4 Jan 2024 16:16:40 +0100 Subject: [PATCH 1/3] Use dedicated organization for sandbox acceptance tests --- gandi/resource_domain_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gandi/resource_domain_test.go b/gandi/resource_domain_test.go index ad7ab3bd..f193aa0c 100644 --- a/gandi/resource_domain_test.go +++ b/gandi/resource_domain_test.go @@ -68,12 +68,13 @@ func testAccConfig(resourceName, domainName string, tags string) string { "birth_date" = "" "birth_department" = "" } - family_name = "lewo" - given_name = "lewo" + organisation = "gandi_terraform_provider_acceptance_tests" + family_name = "Tests" + given_name = "Gandi" mail_obfuscated = false phone = "+33.606060606" street_addr = "Paris" - type = "person" + type = "company" zip = "75000" } %s From 8c37e17e17e73f4f87d09f96be537f4f2f5a2326 Mon Sep 17 00:00:00 2001 From: Nautik Date: Thu, 4 Jan 2024 16:21:41 +0100 Subject: [PATCH 2/3] Add required secret for sandbox organization to use --- .github/workflows/lint-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/lint-build.yml b/.github/workflows/lint-build.yml index 8560ed61..b74937b2 100644 --- a/.github/workflows/lint-build.yml +++ b/.github/workflows/lint-build.yml @@ -39,6 +39,7 @@ jobs: env: GANDI_URL: https://api.sandbox.gandi.net GANDI_KEY: ${{ secrets.GANDI_SANDBOX_KEY }} + GANDI_SHARING_ID: a2f9c3dc-ab0e-11ee-b064-00163e6722b2 run: | make testacc From 1335ec91e0727b6de322bbffb50160e7bd94289b Mon Sep 17 00:00:00 2001 From: Nautik Date: Tue, 19 Dec 2023 13:32:07 +0100 Subject: [PATCH 3/3] Add support for Personal Access Tokens --- .github/workflows/lint-build.yml | 10 ++++++++-- README.md | 7 ++----- docs/index.md | 14 ++++++-------- gandi/provider.go | 26 ++++++++++++++++++-------- gandi/provider_test.go | 6 +++--- gandi/resource_livedns_record_test.go | 24 +++++++++++++++--------- go.mod | 2 +- go.sum | 4 ++-- templates/index.md | 14 ++++++-------- 9 files changed, 61 insertions(+), 46 deletions(-) diff --git a/.github/workflows/lint-build.yml b/.github/workflows/lint-build.yml index b74937b2..1d43293a 100644 --- a/.github/workflows/lint-build.yml +++ b/.github/workflows/lint-build.yml @@ -24,7 +24,7 @@ jobs: extra_args: --all-files --show-diff-on-failure test: - name: Acceptance Test + name: Acceptance Tests # Secrets (sandbox token) are not available on forks if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest @@ -35,13 +35,19 @@ jobs: go-version: 1.17 - name: Check out code into the Go module directory uses: actions/checkout@v2 - - name: Test + - name: Test with apikey env: GANDI_URL: https://api.sandbox.gandi.net GANDI_KEY: ${{ secrets.GANDI_SANDBOX_KEY }} GANDI_SHARING_ID: a2f9c3dc-ab0e-11ee-b064-00163e6722b2 run: | make testacc + - name: Test with personal access token + env: + GANDI_URL: https://api.sandbox.gandi.net + GANDI_PERSONAL_ACCESS_TOKEN: ${{ secrets.GANDI_SANDBOX_PERSONAL_ACCESS_TOKEN }} + run: | + make testacc build: name: Build diff --git a/README.md b/README.md index 1f4dd77c..cc51fa2b 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ See the [Hashicorp Terraform documentation](https://www.terraform.io/docs/plugin ## Using the provider This example partly mimics the steps of [the official LiveDNS documentation example](http://doc.livedns.gandi.net/#quick-example), using the parts that have been implemented as Terraform resources. -Note: sharing_id is optional. It is used e.g. when the API key is registered to a user, where the domain you want to manage is not registered with that user (but the user does have rights on that zone/organization). ```terraform terraform { @@ -48,8 +47,7 @@ terraform { } provider "gandi" { - key = "" - sharing_id = "" + personal_access_token = "" } resource "gandi_domain" "example_com" { @@ -107,8 +105,7 @@ terraform { } provider "gandi" { - key = "" - sharing_id = "" + personal_access_token = "" } data "gandi_domain" "example_com" { diff --git a/docs/index.md b/docs/index.md index 2eb4edf0..724736f6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,7 +25,7 @@ terraform { } provider "gandi" { - key = "MY_API_KEY" + personal_access_token = "MY_PERSONAL_ACCESS_TOKEN" } resource "gandi_domain" "example_com" { @@ -37,9 +37,9 @@ resource "gandi_domain" "example_com" { The Gandi provider supports a couple of different methods for providing authentication credentials. -You can retrieve your API key by visiting the [Account Management](https://account.gandi.net/en/) screen, going to the `Security` tab and generating your `Production API Key`. +The recommended way is to create a Personal Access Token. Read more about these tokens in the [Gandi public API documentation](https://api.gandi.net/docs/authentication/). -Optionally, you can provide a Sharing ID to specify an organization. If set, the Sharing ID indicates the organization that will pay for any ordered products, and will filter collections. +The previous method of using an API key is now deprecated and should not be used anymore, though it is still supported by this provider for now. When using an API Key, you could also provide a Sharing ID to specify an organization. If set, the Sharing ID indicates the organization that will pay for any ordered products, and will filter collections. ### Static Credentials @@ -49,14 +49,13 @@ Usage: ```terraform provider "gandi" { - key = "MY_API_KEY" - sharing_id = "MY_SHARING_ID" + personal_access_token = "MY_PERSONAL_ACCESS_TOKEN" } ``` ### Environment Variables -You can provide your credentials via the `GANDI_KEY` and `GANDI_SHARING_ID` environment variables, representing the API Key and the Sharing ID, respectively. +You can provide your credentials via the `GANDI_PERSONAL_ACCESS_TOKEN` environment variable, representing the Personal Access Token. ```terraform provider "gandi" {} @@ -65,7 +64,6 @@ provider "gandi" {} Usage: ```terraform -$ export GANDI_KEY="MY_API_KEY" -$ export GANDI_SHARING_ID="MY_SHARING_ID" +$ export GANDI_PERSONAL_ACCESS_TOKEN="MY_PERSONAL_ACCESS_TOKEN" $ terraform plan ``` diff --git a/gandi/provider.go b/gandi/provider.go index a4130df3..c7691113 100644 --- a/gandi/provider.go +++ b/gandi/provider.go @@ -16,18 +16,27 @@ import ( func Provider() *schema.Provider { return &schema.Provider{ Schema: map[string]*schema.Schema{ + "personal_access_token": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc("GANDI_PERSONAL_ACCESS_TOKEN", nil), + Description: "A Gandi API Personal Access Token", + Sensitive: true, + }, "key": { Type: schema.TypeString, - Required: true, + Optional: true, DefaultFunc: schema.EnvDefaultFunc("GANDI_KEY", nil), - Description: "A Gandi API key", + Description: "(DEPRECATED) A Gandi API key", + Deprecated: "use personal_access_token instead", Sensitive: true, }, "sharing_id": { Type: schema.TypeString, Optional: true, DefaultFunc: schema.EnvDefaultFunc("GANDI_SHARING_ID", nil), - Description: "A Gandi Sharing ID", + Description: "(DEPRECATED) A Gandi Sharing ID", + Deprecated: "use personal_access_token instead", }, "dry_run": { Type: schema.TypeBool, @@ -74,11 +83,12 @@ type clients struct { func getGandiClients(d *schema.ResourceData) (interface{}, error) { config := config.Config{ - APIURL: d.Get("url").(string), - APIKey: d.Get("key").(string), - SharingID: d.Get("sharing_id").(string), - DryRun: d.Get("dry_run").(bool), - Debug: logging.IsDebugOrHigher(), + APIURL: d.Get("url").(string), + APIKey: d.Get("key").(string), + PersonalAccessToken: d.Get("personal_access_token").(string), + SharingID: d.Get("sharing_id").(string), + DryRun: d.Get("dry_run").(bool), + Debug: logging.IsDebugOrHigher(), } liveDNS := gandi.NewLiveDNSClient(config) email := gandi.NewEmailClient(config) diff --git a/gandi/provider_test.go b/gandi/provider_test.go index 8d0c58c2..480d5d51 100644 --- a/gandi/provider_test.go +++ b/gandi/provider_test.go @@ -28,10 +28,10 @@ func TestProvider_impl(t *testing.T) { } func testAccPreCheck(t *testing.T) { - if v := os.Getenv("GANDI_KEY"); v == "" { - t.Fatal("GANDI_KEY must be set for acceptance tests") + if os.Getenv("GANDI_PERSONAL_ACCESS_TOKEN") == "" && os.Getenv("GANDI_KEY") == "" { + t.Fatal("GANDI_PERSONAL_ACCESS_TOKEN or GANDI_KEY must be set for acceptance tests") } - if v := os.Getenv("GANDI_URL"); v == "" { + if os.Getenv("GANDI_URL") == "" { t.Fatal("GANDI_URL must be set for acceptance tests") } } diff --git a/gandi/resource_livedns_record_test.go b/gandi/resource_livedns_record_test.go index d2a74f3f..41f8f96c 100644 --- a/gandi/resource_livedns_record_test.go +++ b/gandi/resource_livedns_record_test.go @@ -42,9 +42,11 @@ func testAccConfigRecord() string { func deleteRecord() { config := config.Config{ - APIURL: os.Getenv("GANDI_URL"), - APIKey: os.Getenv("GANDI_KEY"), - Debug: logging.IsDebugOrHigher(), + APIURL: os.Getenv("GANDI_URL"), + PersonalAccessToken: os.Getenv("GANDI_PERSONAL_ACCESS_TOKEN"), + APIKey: os.Getenv("GANDI_KEY"), + SharingID: os.Getenv("GANDI_SHARING_ID"), + Debug: logging.IsDebugOrHigher(), } liveDNS := gandi.NewLiveDNSClient(config) @@ -228,9 +230,11 @@ func testAccConfigMutableRecord() string { func updateRecord(values []string) { config := config.Config{ - APIURL: os.Getenv("GANDI_URL"), - APIKey: os.Getenv("GANDI_KEY"), - Debug: logging.IsDebugOrHigher(), + APIURL: os.Getenv("GANDI_URL"), + PersonalAccessToken: os.Getenv("GANDI_PERSONAL_ACCESS_TOKEN"), + APIKey: os.Getenv("GANDI_KEY"), + SharingID: os.Getenv("GANDI_SHARING_ID"), + Debug: logging.IsDebugOrHigher(), } liveDNS := gandi.NewLiveDNSClient(config) _, err := liveDNS.UpdateDomainRecordByNameAndType( @@ -246,9 +250,11 @@ func updateRecord(values []string) { func checkRecordValuesOnAPI(state *terraform.State, expected []string) error { config := config.Config{ - APIURL: os.Getenv("GANDI_URL"), - APIKey: os.Getenv("GANDI_KEY"), - Debug: logging.IsDebugOrHigher(), + APIURL: os.Getenv("GANDI_URL"), + PersonalAccessToken: os.Getenv("GANDI_PERSONAL_ACCESS_TOKEN"), + APIKey: os.Getenv("GANDI_KEY"), + SharingID: os.Getenv("GANDI_SHARING_ID"), + Debug: logging.IsDebugOrHigher(), } liveDNS := gandi.NewLiveDNSClient(config) rec, err := liveDNS.GetDomainRecordByNameAndType( diff --git a/go.mod b/go.mod index beadf815..75a2361f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/fatih/color v1.9.0 // indirect - github.com/go-gandi/go-gandi v0.6.0 + github.com/go-gandi/go-gandi v0.7.0 github.com/google/uuid v1.1.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.16.0 github.com/hashicorp/yamux v0.0.0-20190923154419-df201c70410d // indirect diff --git a/go.sum b/go.sum index 49b43bb7..f00f2b6e 100644 --- a/go.sum +++ b/go.sum @@ -51,8 +51,8 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-gandi/go-gandi v0.6.0 h1:RgFoevggRRp7hF9XsOmWmtwbUg2axhe2ygEdd6Mtstc= -github.com/go-gandi/go-gandi v0.6.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw= +github.com/go-gandi/go-gandi v0.7.0 h1:gsP33dUspsN1M+ZW9HEgHchK9HiaSkYnltO73RHhSZA= +github.com/go-gandi/go-gandi v0.7.0/go.mod h1:9NoYyfWCjFosClPiWjkbbRK5UViaZ4ctpT8/pKSSFlw= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= diff --git a/templates/index.md b/templates/index.md index 2eb4edf0..724736f6 100644 --- a/templates/index.md +++ b/templates/index.md @@ -25,7 +25,7 @@ terraform { } provider "gandi" { - key = "MY_API_KEY" + personal_access_token = "MY_PERSONAL_ACCESS_TOKEN" } resource "gandi_domain" "example_com" { @@ -37,9 +37,9 @@ resource "gandi_domain" "example_com" { The Gandi provider supports a couple of different methods for providing authentication credentials. -You can retrieve your API key by visiting the [Account Management](https://account.gandi.net/en/) screen, going to the `Security` tab and generating your `Production API Key`. +The recommended way is to create a Personal Access Token. Read more about these tokens in the [Gandi public API documentation](https://api.gandi.net/docs/authentication/). -Optionally, you can provide a Sharing ID to specify an organization. If set, the Sharing ID indicates the organization that will pay for any ordered products, and will filter collections. +The previous method of using an API key is now deprecated and should not be used anymore, though it is still supported by this provider for now. When using an API Key, you could also provide a Sharing ID to specify an organization. If set, the Sharing ID indicates the organization that will pay for any ordered products, and will filter collections. ### Static Credentials @@ -49,14 +49,13 @@ Usage: ```terraform provider "gandi" { - key = "MY_API_KEY" - sharing_id = "MY_SHARING_ID" + personal_access_token = "MY_PERSONAL_ACCESS_TOKEN" } ``` ### Environment Variables -You can provide your credentials via the `GANDI_KEY` and `GANDI_SHARING_ID` environment variables, representing the API Key and the Sharing ID, respectively. +You can provide your credentials via the `GANDI_PERSONAL_ACCESS_TOKEN` environment variable, representing the Personal Access Token. ```terraform provider "gandi" {} @@ -65,7 +64,6 @@ provider "gandi" {} Usage: ```terraform -$ export GANDI_KEY="MY_API_KEY" -$ export GANDI_SHARING_ID="MY_SHARING_ID" +$ export GANDI_PERSONAL_ACCESS_TOKEN="MY_PERSONAL_ACCESS_TOKEN" $ terraform plan ```