From 8b776bb12eb1f6f59daaf9250ad537fd903ab8f9 Mon Sep 17 00:00:00 2001 From: Nautik Date: Thu, 4 Jan 2024 16:16:40 +0100 Subject: [PATCH 1/2] Use dedicated organization for sandbox acceptance tests --- .github/workflows/lint-build.yml | 5 +++-- gandi/resource_domain_test.go | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint-build.yml b/.github/workflows/lint-build.yml index 8560ed61..2ace39af 100644 --- a/.github/workflows/lint-build.yml +++ b/.github/workflows/lint-build.yml @@ -37,8 +37,9 @@ jobs: uses: actions/checkout@v2 - name: Test env: - GANDI_URL: https://api.sandbox.gandi.net - GANDI_KEY: ${{ secrets.GANDI_SANDBOX_KEY }} + GANDI_URL: https://api.sandbox.gandi.net + GANDI_KEY: ${{ secrets.GANDI_SANDBOX_KEY }} + GANDI_SHARING_ID: a2f9c3dc-ab0e-11ee-b064-00163e6722b2 run: | make testacc 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 79a3baee6e7aa71dba855cf36579c0f49d6edcc6 Mon Sep 17 00:00:00 2001 From: Nautik Date: Tue, 19 Dec 2023 13:32:07 +0100 Subject: [PATCH 2/2] 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 2ace39af..4e63b336 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 ```